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