1ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran/* 2ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Copyright (C) 2014 The Android Open Source Project 3ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * 4ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Licensed under the Apache License, Version 2.0 (the "License"); 5ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * you may not use this file except in compliance with the License. 6ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * You may obtain a copy of the License at 7ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * 8ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * http://www.apache.org/licenses/LICENSE-2.0 9ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * 10ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * Unless required by applicable law or agreed to in writing, software 11ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * distributed under the License is distributed on an "AS IS" BASIS, 12ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * See the License for the specific language governing permissions and 14ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran * limitations under the License. 15ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran */ 16ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 178205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#ifdef LIBC_STATIC 188205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#error NetdClient.cpp should NOT be included in static libc builds. 198205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran#endif 208205a61248973ac13716ae80e712c80e126b0541Sreeram Ramachandran 217a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris#include <async_safe/log.h> 227a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris 2372c53933f852be6d1cd6c09c86176fbc6d609dacSreeram Ramachandran#include "private/NetdClientDispatch.h" 24ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 25ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran#include <dlfcn.h> 2672c53933f852be6d1cd6c09c86176fbc6d609dacSreeram Ramachandran#include <pthread.h> 27ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 28ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandrantemplate <typename FunctionType> 29ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic void netdClientInitFunction(void* handle, const char* symbol, FunctionType* function) { 30ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran typedef void (*InitFunctionType)(FunctionType*); 31ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran InitFunctionType initFunction = reinterpret_cast<InitFunctionType>(dlsym(handle, symbol)); 32ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran if (initFunction != NULL) { 33ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran initFunction(function); 34ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran } 35ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran} 36ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 37ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic void netdClientInitImpl() { 3884c10c2e7928cf2128f2495b9d5ed916088b2f2bDmitriy Ivanov void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW); 39ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran if (netdClientHandle == NULL) { 40ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran // If the library is not available, it's not an error. We'll just use 41ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran // default implementations of functions that it would've overridden. 42ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran return; 43ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran } 44903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran netdClientInitFunction(netdClientHandle, "netdClientInitAccept4", 45903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran &__netdClientDispatch.accept4); 46ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran netdClientInitFunction(netdClientHandle, "netdClientInitConnect", 47ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran &__netdClientDispatch.connect); 485240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen netdClientInitFunction(netdClientHandle, "netdClientInitNetIdForResolv", 495240b562e7e9de2f31ba70f71c394c5529aadf0fPaul Jensen &__netdClientDispatch.netIdForResolv); 50903b78873a744d3fba187e4bd22008ba21162e51Sreeram Ramachandran netdClientInitFunction(netdClientHandle, "netdClientInitSocket", &__netdClientDispatch.socket); 51ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran} 52ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 53ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranstatic pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT; 54ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran 55ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandranextern "C" __LIBC_HIDDEN__ void netdClientInit() { 56ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) { 577a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63Christopher Ferris async_safe_format_log(ANDROID_LOG_ERROR, "netdClient", "Failed to initialize netd_client"); 58ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran } 59ceb5bd787c8ce281e5f4343c5d4f77b41c3e2919Sreeram Ramachandran} 60