00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00038 #include "blocxx/BLOCXX_config.h"
00039 #if defined(BLOCXX_USE_DL)
00040 #include "blocxx/dlSharedLibrary.hpp"
00041 #include "blocxx/Format.hpp"
00042 #include "blocxx/Mutex.hpp"
00043 #include "blocxx/MutexLock.hpp"
00044 #include "blocxx/GlobalMutex.hpp"
00045 #include <dlfcn.h>
00046 #ifdef BLOCXX_HAVE_FCNTL_H
00047
00048 #include <fcntl.h>
00049 #endif
00050
00051 #include "blocxx/Types.hpp"
00052
00053 #if defined(BLOCXX_USE_FAKE_LIBS)
00054
00055 #include "blocxx/FileSystem.hpp"
00056 #include "blocxx/File.hpp"
00057 #include "blocxx/Array.hpp"
00058
00059 #define BLOCXX_FAKELIB_HEADING "FAKE"
00060 #define BLOCXX_FAKELIB_HEADING_LENGTH 4
00061
00062 #endif
00063
00064 #include <iostream>
00065
00066 namespace BLOCXX_NAMESPACE
00067 {
00068
00069
00070 bool dlSharedLibrary::s_call_dlclose = true;
00071
00072 GlobalMutex dlSharedLibrary_guard = BLOCXX_GLOBAL_MUTEX_INIT();
00073
00074 dlSharedLibrary::dlSharedLibrary(void * libhandle, const String& libName)
00075 : SharedLibrary(), m_libhandle( libhandle ), m_libName(libName)
00076 {
00077 #if defined(BLOCXX_USE_FAKE_LIBS)
00078
00079 m_fakeLibrary = dlSharedLibrary::isFakeLibrary(libName);
00080
00081 if ( m_fakeLibrary )
00082 {
00083 initializeSymbolMap();
00084 }
00085 #endif
00086 }
00087
00088 dlSharedLibrary::~dlSharedLibrary()
00089 {
00090 #if !defined(BLOCXX_VALGRIND_SUPPORT) // dlclose()ing shared libs make it impossible to see where memory leaks occurred with valgrind.
00091 if (s_call_dlclose)
00092 {
00093 dlclose( m_libhandle );
00094 }
00095 #endif
00096 }
00097 bool dlSharedLibrary::doGetFunctionPointer(const String& functionName,
00098 void** fp) const
00099 {
00100 MutexLock l(dlSharedLibrary_guard);
00101 #if defined(BLOCXX_USE_FAKE_LIBS)
00102 String realFunctionName = functionName;
00103
00104
00105 if ( m_fakeLibrary )
00106 {
00107 Map<String,String>::const_iterator symIter = m_symbolMap.find(functionName);
00108 if ( symIter == m_symbolMap.end() )
00109 {
00110 return false;
00111 }
00112 realFunctionName = symIter->second;
00113 }
00114 *fp = dlsym( m_libhandle, realFunctionName.c_str() );
00115 #else
00116 *fp = dlsym( m_libhandle, functionName.c_str() );
00117 #endif
00118
00119 if (!*fp)
00120 {
00121 return false;
00122 }
00123 return true;
00124 }
00125
00126 bool dlSharedLibrary::isFakeLibrary(const String& library_path)
00127 {
00128 bool fake = false;
00129 #if defined(BLOCXX_USE_FAKE_LIBS)
00130 if ( FileSystem::canRead(library_path) )
00131 {
00132
00133
00134 int libfd = open(library_path.c_str(), O_RDONLY);
00135
00136 if ( libfd )
00137 {
00138 char buffer[(BLOCXX_FAKELIB_HEADING_LENGTH) + 1];
00139 size_t num_read = read(libfd, buffer,(BLOCXX_FAKELIB_HEADING_LENGTH));
00140 if ( num_read == (BLOCXX_FAKELIB_HEADING_LENGTH) )
00141 {
00142
00143 buffer[BLOCXX_FAKELIB_HEADING_LENGTH] = '\0';
00144 if ( String(BLOCXX_FAKELIB_HEADING) == buffer )
00145 {
00146
00147 fake = true;
00148 }
00149 }
00150 close(libfd);
00151 }
00152 }
00153 #endif
00154 return fake;
00155 }
00156
00157 #if defined(BLOCXX_USE_FAKE_LIBS)
00158 void dlSharedLibrary::initializeSymbolMap()
00159 {
00160 if ( ! m_fakeLibrary )
00161 {
00162 return;
00163 }
00164
00165
00166
00167 StringArray lines = FileSystem::getFileLines(m_libName);
00168
00169 for ( StringArray::const_iterator iter = lines.begin();
00170 iter != lines.end();
00171 ++iter )
00172 {
00173
00174 if ( iter->startsWith('#') )
00175 {
00176 continue;
00177 }
00178 StringArray current_line = iter->tokenize("=");
00179
00180 if ( current_line.size() != 2 )
00181 {
00182 continue;
00183 }
00184
00185 String option = String(current_line[0]).trim();
00186 String value = String(current_line[1]).trim();
00187 m_symbolMap[option] = value;
00188 }
00189 }
00190 #endif
00191
00192 }
00193
00194 #endif
00195