00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #define SYSTEM_MODULEINFO_CPP
00015
00016
00017 #include <cstring>
00018 #include <cstdlib>
00019
00020
00021
00022 #include "GaudiKernel/ModuleInfo.h"
00023
00024 #ifdef _WIN32
00025 # define strcasecmp _stricmp
00026 # define strncasecmp _strnicmp
00027 #include "process.h"
00028 #include "windows.h"
00029 #include "Win32PsApi.h"
00030 static PsApiFunctions _psApi;
00031 #define getpid _getpid
00032 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
00033 #include <errno.h>
00034 #include <string.h>
00035 #include "sys/times.h"
00036 #include "unistd.h"
00037 #include "libgen.h"
00038 #include <cstdio>
00039 #include <dlfcn.h>
00040 #endif
00041
00042 static System::ImageHandle ModuleHandle = 0;
00043 static std::vector<std::string> s_linkedModules;
00044
00046 const std::string& System::moduleName() {
00047 static std::string module("");
00048 if ( module == "" ) {
00049 if ( processHandle() && moduleHandle() ) {
00050 #ifdef _WIN32
00051 char moduleName[256] = {"Unknown.module"};
00052 moduleName[0] = 0;
00053 if ( _psApi.isValid() ) {
00054 _psApi.GetModuleBaseNameA( processHandle(), (HINSTANCE)moduleHandle(), moduleName, sizeof(moduleName) );
00055 }
00056 std::string mod = moduleName;
00057 #elif defined(linux) || defined(sun)
00058 std::string mod = ::basename((char*)((Dl_info*)moduleHandle())->dli_fname);
00059 #elif __hpux
00060 std::string mod = ::basename(((HMODULE*)moduleHandle())->dsc.filename);
00061 #endif
00062 module = mod.substr(0, mod.rfind('.'));
00063 }
00064 }
00065 return module;
00066 }
00067
00069 const std::string& System::moduleNameFull() {
00070 static std::string module("");
00071 if ( module == "" ) {
00072 if ( processHandle() && moduleHandle() ) {
00073 char name[512] = {"Unknown.module"};
00074 name[0] = 0;
00075 #ifdef _WIN32
00076 if ( _psApi.isValid() ) {
00077 _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)moduleHandle(), name,sizeof(name) );
00078 }
00079 #elif defined(linux) || defined(sun)
00080 ::realpath(((Dl_info*)moduleHandle())->dli_fname, name);
00081 #elif __hpux
00082 ::realpath(((HMODULE*)moduleHandle())->dsc.filename, name);
00083 #endif
00084 module = name;
00085 }
00086 }
00087 return module;
00088 }
00089
00091 const System::ModuleType System::moduleType() {
00092 static ModuleType type = UNKNOWN;
00093 if ( type == UNKNOWN ) {
00094 const std::string& module = moduleNameFull();
00095 int loc = module.rfind('.')+1;
00096 if ( loc == 0 )
00097 type = EXECUTABLE;
00098 else if ( module[loc] == 'e' || module[loc] == 'E' )
00099 type = EXECUTABLE;
00100 #ifdef _WIN32
00101 else if ( module[loc] == 'd' || module[loc] == 'D' )
00102 #else
00103 else if ( module[loc] == 's' && module[loc+1] == 'o' )
00104 #endif
00105 type = SHAREDLIB;
00106 else
00107 type = UNKNOWN;
00108 }
00109 return type;
00110 }
00111
00113 void* System::processHandle() {
00114 static long pid = ::getpid();
00115 #ifdef _WIN32
00116 static HANDLE hP = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
00117 #else
00118 static void* hP = (void*)pid;
00119 #endif
00120 return hP;
00121 }
00122
00123 void System::setModuleHandle(System::ImageHandle handle) {
00124 ModuleHandle = handle;
00125 }
00126
00127 System::ImageHandle System::moduleHandle() {
00128 if ( 0 == ModuleHandle ) {
00129 if ( processHandle() ) {
00130 #ifdef _WIN32
00131 static HINSTANCE handle = 0;
00132 DWORD cbNeeded;
00133 if ( 0 == handle && _psApi.isValid() ) {
00134 if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
00135 }
00136 }
00137 return handle;
00138 #elif defined(linux) || defined(sun)
00139 static Dl_info info;
00140 if ( 0 != ::dladdr(System::moduleHandle, &info) ) {
00141 return &info;
00142 }
00143 #elif __hpux
00144 return 0;
00145 #endif
00146 }
00147 }
00148 return ModuleHandle;
00149 }
00150
00151 System::ImageHandle System::exeHandle() {
00152 #ifdef _WIN32
00153 if ( processHandle() ) {
00154 static HINSTANCE handle = 0;
00155 DWORD cbNeeded;
00156 if ( 0 == handle && _psApi.isValid() ) {
00157 if ( _psApi.EnumProcessModules( processHandle(), &handle, sizeof(ModuleHandle), &cbNeeded) ) {
00158 }
00159 }
00160 return handle;
00161 }
00162 #elif defined(linux) || defined(sun)
00163
00164 static Dl_info infoBuf, *info = &infoBuf;
00165 if ( 0 == info ) {
00166 void* handle = ::dlopen(0, RTLD_LAZY);
00167
00168 if ( 0 != handle ) {
00169 void* func = ::dlsym(handle, "main");
00170
00171 if ( 0 != func ) {
00172 if ( 0 != ::dladdr(func, &infoBuf) ) {
00173
00174 info = &infoBuf;
00175 }
00176 }
00177 }
00178 }
00179 return info;
00180 #elif __hpux
00181
00182 #endif
00183 return 0;
00184 }
00185
00186 const std::string& System::exeName() {
00187 static std::string module("");
00188 if ( module.length() == 0 ) {
00189 char name[512] = {"Unknown.module"};
00190 name[0] = 0;
00191 #ifdef _WIN32
00192 if ( _psApi.isValid() && processHandle() ) {
00193 _psApi.GetModuleFileNameExA( processHandle(), (HINSTANCE)exeHandle(), name,sizeof(name) );
00194 }
00195 #elif defined(linux) || defined(sun)
00196 char cmd[512];
00197 ::sprintf(cmd, "/proc/%d/exe", ::getpid());
00198 module = "Unknown";
00199 ::readlink(cmd, name, sizeof(name));
00200 #elif __hpux
00201 ::realpath(((HMODULE*)exeHandle())->dsc.filename, name);
00202 #endif
00203 module = name;
00204 }
00205 return module;
00206 }
00207
00208 const std::vector<std::string> System::linkedModules() {
00209 if ( s_linkedModules.size() == 0 ) {
00210 #ifdef _WIN32
00211 char name[255];
00212 DWORD cbNeeded;
00213 HINSTANCE handle[1024];
00214 if ( _psApi.isValid() ) {
00215 if ( _psApi.EnumProcessModules(processHandle(),handle,sizeof(handle),&cbNeeded) ) {
00216 for ( long i = 0; i < cbNeeded/sizeof(HANDLE); i++ ) {
00217 if ( 0 < _psApi.GetModuleFileNameExA( processHandle(), handle[i], name, sizeof(name)) ) {
00218 s_linkedModules.push_back(name);
00219 }
00220 }
00221 }
00222 }
00223 #elif defined(linux) || defined(sun)
00224 char ff[512], cmd[1024], fname[1024], buf1[64], buf2[64], buf3[64], buf4[64];
00225 ::sprintf(ff, "/proc/%d/maps", ::getpid());
00226 FILE* maps = ::fopen(ff, "r");
00227 while( ::fgets(cmd, sizeof(cmd), maps) ) {
00228 int len;
00229 sscanf(cmd, "%s %s %s %s %d %s", buf1, buf2, buf3, buf4, &len, fname);
00230 if ( len > 0 && strncmp(buf2,"r-xp",strlen("r-xp")) == 0 ) {
00231 s_linkedModules.push_back(fname);
00232 }
00233 }
00234 ::fclose(maps);
00235 #endif
00236 }
00237 return s_linkedModules;
00238 }