14 #define SYSTEM_SYSTEM_CPP
23 #include "GaudiKernel/System.h"
27 #define strcasecmp _stricmp
28 #define strncasecmp _strnicmp
29 #define getpid _getpid
36 static const char* SHLIB_SUFFIX =
".dll";
37 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
38 static const char* SHLIB_SUFFIX =
".so";
41 #include "sys/times.h"
46 #if defined(__linux) || defined(__APPLE__)
48 #include <sys/utsname.h>
63 # if __GNUC__ < 3 || \
64 (__GNUC__ == 3 && (__GNUC_MINOR__ < 4 ))
66 # define __attribute__(x)
70 # define __attribute__(x)
73 static std::vector<std::string> s_argvStrings;
74 static std::vector<const char*> s_argvChars;
78 void* mh = ::LoadLibrary( name.length() == 0 ?
System::exeName().c_str() : name.c_str());
81 const char*
path = name.c_str();
82 #if defined(__linux) || defined(__APPLE__)
83 void *mh = ::dlopen(name.length() == 0 ? 0 :
path, RTLD_LAZY | RTLD_GLOBAL);
86 shl_t mh = ::shl_load(name.length() == 0 ? 0 :
path, BIND_IMMEDIATE | BIND_VERBOSE, 0);
87 HMODULE*
mod =
new HMODULE;
89 if ( 0 != ::shl_gethandle_r(mh, &mod->dsc) ) {
90 std::cout <<
"System::loadDynamicLib>" << ::strerror(
getLastError()) << std::endl;
93 typedef void* (*___all)();
94 ___all _alloc = (___all)malloc;
95 mod->numSym = ::shl_getsymbols(mod->dsc.handle, TYPE_PROCEDURE, EXPORT_SYMBOLS, malloc, &mod->sym);
101 if ( 0 == *handle ) {
107 static unsigned long loadWithoutEnvironment(
const std::string& name,
System::ImageHandle* handle) {
109 std::string dllName = name;
110 long len = strlen(SHLIB_SUFFIX);
114 if ((dllName.length() != 0) &&
115 ::strncasecmp(dllName.data()+dllName.length()-len, SHLIB_SUFFIX, len) != 0) {
116 dllName += SHLIB_SUFFIX;
120 return doLoad(dllName, handle);
127 if (name.length() == 0) {
128 res = loadWithoutEnvironment(name, handle);
133 if (
getEnv(name, imgName) ) {
134 res = loadWithoutEnvironment(imgName, handle);
137 std::string dllName = name;
141 if (dllName.find(
'/') == std::string::npos) {
142 #if defined(__linux) || defined(__APPLE__)
143 if (dllName.substr(0, 3) !=
"lib")
144 dllName =
"lib" + dllName;
146 if (dllName.find(SHLIB_SUFFIX) == std::string::npos)
147 dllName += SHLIB_SUFFIX;
150 res = loadWithoutEnvironment(dllName, handle);
153 #if defined(__linux) || defined(__APPLE__)
165 if ( !::FreeLibrary((HINSTANCE)handle) ) {
166 #elif defined(__linux) || defined(__APPLE__)
175 HMODULE*
mod = (HMODULE*)handle;
176 if ( 0 == ::shl_unload( mod->dsc.handle ) ) {
191 *pFunction = (
EntryPoint)::GetProcAddress((HINSTANCE)handle, name.data());
192 if ( 0 == *pFunction ) {
196 #elif defined(__linux)
198 *pFunction = (
EntryPoint)::dlsym(handle, name.c_str());
200 *pFunction = FuncPtrCast<EntryPoint>(::dlsym(handle, name.c_str()));
202 if ( 0 == *pFunction ) {
208 #elif defined(__APPLE__)
209 *pFunction = (
EntryPoint)::dlsym(handle, name.c_str());
212 std::string
sname =
"_" + name;
213 *pFunction = (
EntryPoint)::dlsym(handle, sname.c_str());
215 if ( 0 == *pFunction ) {
223 HMODULE* mod = (HMODULE*)handle;
225 long ll1 = name.length();
226 for (
int i = 0;
i < mod->numSym;
i++ ) {
227 long ll2 = strlen(mod->sym[
i].name);
228 if ( 0 != ::strncmp(mod->sym[
i].name, name.c_str(), (ll1>ll2) ? ll1 : ll2)==0 ) {
246 return ::GetLastError();
249 return static_cast<unsigned long>(
static_cast<unsigned int>(errno));
261 std::string errString =
"";
263 LPVOID lpMessageBuffer;
265 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
268 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
269 (LPTSTR) &lpMessageBuffer,
272 errString = (
const char*)lpMessageBuffer;
274 ::LocalFree( lpMessageBuffer );
278 if ( error == 0xAFFEDEAD ) {
279 cerrString = (
char*)::dlerror();
280 if ( 0 == cerrString ) {
281 cerrString = ::strerror(error);
283 if ( 0 == cerrString ) {
284 cerrString = (
char *)
"Unknown error. No information found in strerror()!";
287 errString = std::string(cerrString);
292 cerrString = ::strerror(error);
293 errString = std::string(cerrString);
307 if ( ::strncmp(class_name,
"class ", 6) == 0 ) {
311 if ( ::strncmp(class_name,
"struct ", 7) == 0 ) {
316 std::string tmp = class_name + off;
318 while( (loc = tmp.find(
"class ")) > 0 ) {
322 while( (loc = tmp.find(
"struct ")) > 0 ) {
331 while ( (off=result.find(
" *")) != std::string::npos ) {
332 result.replace(off, 2,
"*");
335 while ( (off=result.find(
" &")) != std::string::npos ) {
336 result.replace(off, 2,
"&");
339 #elif defined(__linux) || defined(__APPLE__)
340 if ( ::strlen(class_name) == 1 ) {
343 switch(class_name[0]) {
357 result =
"signed char";
360 result =
"unsigned char";
366 result =
"unsigned short";
372 result =
"unsigned int";
378 result =
"unsigned long";
381 result =
"long long";
384 result =
"unsigned long long";
390 result =
"unsigned __int128";
399 result =
"long double";
402 result =
"__float128";
412 realname = abi::__cxa_demangle(class_name, 0, 0, &status);
413 if (realname == 0)
return class_name;
417 std::string::size_type pos = result.find(
", ");
418 while( std::string::npos != pos ) {
419 result.replace( pos , 2 ,
"," ) ;
420 pos = result.find(
", ");
429 static std::string host =
"";
432 memset(buffer,0,
sizeof(buffer));
434 unsigned long len =
sizeof(buffer);
435 ::GetComputerName(buffer, &len);
437 ::gethostname(buffer,
sizeof(buffer));
446 static std::string osname =
"";
451 if (uname(&ut) == 0) {
463 static std::string osver =
"";
466 ut.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
468 std::ostringstream ver;
469 ver << ut.dwMajorVersion <<
'.' << ut.dwMinorVersion;
473 if (uname(&ut) == 0) {
484 static std::string mach =
"";
487 ::GetSystemInfo(&ut);
488 std::ostringstream arch;
489 arch << ut.wProcessorArchitecture;
493 if (uname(&ut) == 0) {
513 static std::string account =
"";
514 if ( account ==
"" ) {
517 unsigned long buflen =
sizeof(buffer);
518 ::GetUserName(buffer, &buflen);
521 const char* acct = ::getlogin();
522 if ( 0 == acct ) acct = ::getenv(
"LOGNAME");
523 if ( 0 == acct ) acct = ::getenv(
"USER");
524 account = (acct) ? acct :
"Unknown";
542 if ( s_argvChars.size() == 0 ) {
547 #pragma warning(push)
548 #pragma warning(disable:4996)
553 char *next, *tmp1, *tmp2;
554 for(LPTSTR cmd = ::GetCommandLine(); *cmd; cmd=next) {
555 memset(exe,0,
sizeof(exe));
556 while ( *cmd ==
' ' ) cmd++;
557 next=::strchr(cmd,
' ');
558 if ( !next ) next = cmd + strlen(cmd);
559 if ( (tmp1=::strchr(cmd,
'\"')) > 0 && tmp1 < next ) {
560 tmp2 = ::strchr(++tmp1,
'\"');
563 if ( cmd < tmp1 ) strncpy(exe, cmd, tmp1-cmd-1);
564 strncpy(&exe[strlen(exe)], tmp1, tmp2-tmp1-1);
567 std::cout <<
"Mismatched \" in command line arguments" << std::endl;
568 s_argvChars.erase(s_argvChars.begin(), s_argvChars.end());
569 s_argvStrings.erase(s_argvStrings.begin(), s_argvStrings.end());
570 return s_argvStrings;
574 strncpy(exe, cmd, next-cmd);
576 s_argvStrings.push_back(exe);
577 s_argvChars.push_back( s_argvStrings.back().c_str());
580 #elif defined(__linux) || defined(__APPLE__)
581 sprintf(exe,
"/proc/%d/cmdline", ::getpid());
582 FILE *cmdLine = ::fopen(exe,
"r");
585 long len = fread(cmd,
sizeof(
char),
sizeof(cmd), cmdLine);
588 for (
char* token = cmd; token-cmd < len; token += strlen(token)+1 ) {
589 s_argvStrings.push_back(token);
590 s_argvChars.push_back( s_argvStrings.back().c_str());
593 s_argvChars[0] = s_argvStrings[0].c_str();
599 return s_argvStrings;
608 return (
char**)&s_argvChars[0];
614 #pragma warning(disable:4996)
620 if ( (env = getenv(var)) != 0 ) {
630 if ( (env = getenv(var)) != 0 ) {
639 return getenv(var) != 0;
643 #if defined(__APPLE__)
645 #include "crt_externs.h"
649 # define environ _environ
650 #elif defined(__APPLE__)
651 static char **environ = *_NSGetEnviron();
653 std::vector<std::string> vars;
654 for (
int i=0; environ[
i] != 0; ++
i) {
655 vars.push_back(environ[
i]);
664 #include <execinfo.h>
673 int count = backtrace( addresses, depth );
680 #else // windows and osx parts not implemented
689 const int totalOffset = offset + 2;
690 const int totalDepth = depth + totalOffset;
692 std::string fnc, lib;
694 void** addresses = (
void**) malloc(totalDepth*
sizeof(
void *));
695 if ( addresses != 0 ){
697 for (
int i = totalOffset;
i < count; ++
i) {
701 std::ostringstream ost;
702 ost <<
"#" << std::setw(3) << std::setiosflags( std::ios::left ) << i-totalOffset+1;
703 ost << std::hex << addr << std::dec <<
" " << fnc <<
" [" << lib <<
"]" << std::endl;
727 if ( dladdr( addresses, &info ) && info.dli_fname
728 && info.dli_fname[0] !=
'\0' ) {
729 const char* symbol = info.dli_sname
730 && info.dli_sname[0] !=
'\0' ? info.dli_sname : 0;
732 lib = info.dli_fname;
733 addr = info.dli_saddr;
738 dmg = abi::__cxa_demangle(symbol,0,0,&stat);
739 fnc = (stat == 0) ? dmg : symbol;
749 #else // not implemented for windows and osx
760 return value.empty() ?
762 ::unsetenv(name.c_str()) , 0 :
764 ::setenv(name.c_str(),value.c_str(), overwrite);
767 if ( value.empty() ) {
769 return ::_putenv((name+
"=").c_str());
772 if ( !getenv(name.c_str()) || overwrite ) {
774 return ::_putenv((name+
"="+value).c_str());
GAUDI_API const std::string & osName()
OS name.
GAUDI_API unsigned long getProcedureByName(ImageHandle handle, const std::string &name, EntryPoint *pFunction)
Get a specific function defined in the DLL.
GAUDI_API bool getStackLevel(void *addresses, void *&addr, std::string &fnc, std::string &lib)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
GAUDI_API unsigned long getLastError()
Get last system known error.
void * ImageHandle
Definition of an image handle.
GAUDI_API const std::string & exeName()
Name of the executable file running.
GAUDI_API long argc()
Number of arguments passed to the commandline (==numCmdLineArgs()); just to match argv call...
GAUDI_API int backTrace(void **addresses, const int depth)
GAUDI_API int setEnv(const std::string &name, const std::string &value, int overwrite=1)
Set an environment variables.
GAUDI_API const std::string getErrorString(unsigned long error)
Retrieve error code as string for a given error.
int instrset_detect(void)
GAUDI_API bool isEnvSet(const char *var)
Check if an environment variable is set or not.
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
GAUDI_API int instructionsetLevel()
Instruction Set "Level".
GAUDI_API const std::string & machineType()
Machine type.
void *(* Creator)()
Definition of the "generic" DLL entry point function.
GAUDI_API long numCmdLineArgs()
Number of arguments passed to the commandline.
GAUDI_API const std::string & hostName()
Host name.
GAUDI_API char ** argv()
char** command line arguments including executable name as arg[0]; You may not modify them! ...
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
GAUDI_API const std::string & accountName()
User login name.
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
GAUDI_API unsigned long unloadDynamicLib(ImageHandle handle)
unload dynamic link library
unsigned long(* EntryPoint)(const unsigned long iid, void **ppvObject)
Definition of the "generic" DLL entry point function.
GAUDI_API const std::vector< std::string > cmdLineArgs()
Command line arguments including executable name as arg[0] as vector of strings.
GAUDI_API const std::string & osVersion()
OS version.