| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# System.cpp

Go to the documentation of this file.

    00001 // $Id: System.cpp,v 1.39 2008/06/05 10:04:53 marcocle Exp $
    00002 //====================================================================
    00003 //      System.cpp
    00004 //--------------------------------------------------------------------
    00005 //
    00006 //      Package    : System (The LHCb System service)
    00007 //
    00008 //  Description: Implementation of Systems internals
    00009 //
    00010 //      Author     : M.Frank
    00011 //  Created    : 13/1/99
    00012 //      Changes    :
    00013 //====================================================================
    00014 #define SYSTEM_SYSTEM_CPP
    00015 #include <ctime>
    00016 #include <cstring>
    00017 #include <cstdlib>
    00018 #include <iostream>
    00019 #include <typeinfo>
    00020
    00021 #include "GaudiKernel/System.h"
    00022
    00023 #ifdef _WIN32
    00024   #define strcasecmp  _stricmp
    00025   #define strncasecmp _strnicmp
    00026   #define getpid _getpid
    00027   #define NOMSG
    00028   #define NOGDI
    00029   #include "process.h"
    00030   #include "windows.h"
    00031   #undef NOMSG
    00032   #undef NOGDI
    00033   static const char* SHLIB_SUFFIX = ".dll";
    00034 #else  // UNIX...: first the EGCS stuff, then the OS dependent includes
    00035   static const char* SHLIB_SUFFIX = ".so";
    00036   #include <errno.h>
    00037   #include <string.h>
    00038   #include "sys/times.h"
    00039   #include "unistd.h"
    00040   #include "libgen.h"
    00041   #include <cstdio>
    00042   #include <cxxabi.h>
    00043 #if defined(linux) || defined(__APPLE__)
    00044   #include "dlfcn.h"
    00045   #include <sys/utsname.h>
    00046   #include <unistd.h>
    00047 #elif __hpux
    00048   #include "dl.h"
    00049 struct HMODULE {
    00050   shl_descriptor dsc;
    00051   long           numSym;
    00052   shl_symbol*    sym;
    00053 };
    00054 #endif
    00055
    00056 #endif
    00057
    00058 // Note: __attribute__ is a GCC keyword available since GCC 3.4
    00059 #ifdef __GNUC__
    00060 #  if __GNUC__ < 3 || \
    00061       (__GNUC__ == 3 && (__GNUC_MINOR__ < 4 ))
    00062 // GCC < 3.4
    00063 #    define __attribute__(x)
    00064 #  endif
    00065 #else
    00066 // non-GCC
    00067 #  define __attribute__(x)
    00068 #endif
    00069
    00070 static std::vector<std::string> s_argvStrings;
    00071 static std::vector<const char*> s_argvChars;
    00072
    00073 static unsigned long doLoad(const std::string& name, System::ImageHandle* handle)  {
    00074 #ifdef _WIN32
    00075   void* mh = ::LoadLibrary( name.length() == 0 ? System::exeName().c_str() : name.c_str());
    00076   *handle = mh;
    00077 #else
    00078   const char* path = name.c_str();
    00079 #if defined(linux) || defined(__APPLE__)
    00080   void *mh = ::dlopen(name.length() == 0 ? 0 : path, RTLD_LAZY | RTLD_GLOBAL);
    00081   *handle = mh;
    00082 #elif __hpux
    00083   shl_t mh = ::shl_load(name.length() == 0 ? 0 : path, BIND_IMMEDIATE | BIND_VERBOSE, 0);
    00084   HMODULE* mod = new HMODULE;
    00085   if ( 0 != mh ) {
    00086     if ( 0 != ::shl_gethandle_r(mh, &mod->dsc) ) {
    00087       std::cout << "System::loadDynamicLib>" << ::strerror(getLastError()) << std::endl;
    00088     }
    00089     else {
    00090       typedef void* (*___all)();
    00091       ___all _alloc = (___all)malloc;
    00092       mod->numSym = ::shl_getsymbols(mod->dsc.handle, TYPE_PROCEDURE, EXPORT_SYMBOLS, malloc, &mod->sym);
    00093       *handle = mod;
    00094     }
    00095   }
    00096 #endif
    00097 #endif
    00098   if ( 0 == *handle )   {
    00099     return System::getLastError();
    00100   }
    00101   return 1;
    00102 }
    00103
    00104 static unsigned long loadWithoutEnvironment(const std::string& name, System::ImageHandle* handle)    {
    00105
    00106   std::string dllName = name;
    00107   long len = strlen(SHLIB_SUFFIX);
    00108
    00109   // Add the suffix at the end of the library name only if necessary
    00110   // FIXME: cure the logic
    00111   if ((dllName.length() != 0) &&
    00112       ::strncasecmp(dllName.data()+dllName.length()-len, SHLIB_SUFFIX, len) != 0) {
    00113     dllName += SHLIB_SUFFIX;
    00114   }
    00115
    00116   // Load the library
    00117   return doLoad(dllName, handle);
    00118 }
    00119
    00121 unsigned long System::loadDynamicLib(const std::string& name, ImageHandle* handle) {
    00122   unsigned long res;
    00123   // if name is empty, just load it
    00124   if (name.length() == 0) {
    00125     res = loadWithoutEnvironment(name, handle);
    00126   } else {
    00127     // If the name is a logical name (environment variable), the try
    00128     // to load the corresponding library from there.
    00129     std::string env = name;
    00130     if ( 0 != ::getenv(env.c_str()) )    {
    00131       std::string imgName = ::getenv(env.c_str());
    00132       res = loadWithoutEnvironment(imgName, handle);
    00133     } else {
    00134       // build the dll name
    00135       std::string dllName = name;
    00136 #if defined(linux) || defined(__APPLE__)
    00137       dllName = "lib" + dllName;
    00138 #endif
    00139       dllName += SHLIB_SUFFIX;
    00140       // try to locate the dll using the standard PATH
    00141       res = loadWithoutEnvironment(dllName, handle);
    00142     }
    00143     if ( res != 1 ) {
    00144 #if defined(linux) || defined(__APPLE__)
    00145       errno = 0xAFFEDEAD;
    00146 #endif
    00147      // std::cout << "System::loadDynamicLib>" << getLastErrorString() << std::endl;
    00148     }
    00149   }
    00150   return res;
    00151 }
    00152
    00154 unsigned long System::unloadDynamicLib(ImageHandle handle)    {
    00155 #ifdef _WIN32
    00156   if ( !::FreeLibrary((HINSTANCE)handle) ) {
    00157 #elif defined(linux) || defined(__APPLE__)
    00158   ::dlclose( handle );
    00159   if ( 0 ) {
    00160 #elif __hpux
    00161   // On HP we have to run finalization ourselves.....
    00162   Creator pFinalize = 0;
    00163   if ( getProcedureByName(handle, "_fini", &pFinalize) ) {
    00164     pFinalize();
    00165   }
    00166   HMODULE* mod = (HMODULE*)handle;
    00167   if ( 0 == ::shl_unload( mod->dsc.handle ) ) {
    00168     delete mod;
    00169   }
    00170   else {
    00171 #endif
    00172     return getLastError();
    00173   }
    00174   return 1;
    00175 }
    00176
    00178 unsigned long System::getProcedureByName(ImageHandle handle, const std::string& name, EntryPoint* pFunction)    {
    00179 #ifdef _WIN32
    00180   *pFunction = (EntryPoint)::GetProcAddress((HINSTANCE)handle, name.data());
    00181   if ( 0 == *pFunction )    {
    00182     return System::getLastError();
    00183   }
    00184   return 1;
    00185 #elif defined(linux)
    00186   *pFunction = (EntryPoint)::dlsym(handle, name.c_str());
    00187   if ( 0 == *pFunction )    {
    00188     errno = 0xAFFEDEAD;
    00189    // std::cout << "System::getProcedureByName>" << getLastErrorString() << std::endl;
    00190     return 0;
    00191   }
    00192   return 1;
    00193 #elif defined(__APPLE__)
    00194   *pFunction = (EntryPoint)::dlsym(handle, name.c_str());
    00195   if(!(*pFunction)) {
    00196     // Try with an underscore :
    00197     std::string sname = "_" + name;
    00198     *pFunction = (EntryPoint)::dlsym(handle, sname.c_str());
    00199   }
    00200   if ( 0 == *pFunction )    {
    00201     errno = 0xAFFEDEAD;
    00202     std::cout << "System::getProcedureByName>" << getLastErrorString() << std::endl;
    00203     //std::cout << "System::getProcedureByName> failure" << std::endl;
    00204     return 0;
    00205   }
    00206   return 1;
    00207 #elif __hpux
    00208   HMODULE* mod = (HMODULE*)handle;
    00209   if ( 0 != mod ) {
    00210     long ll1 = name.length();
    00211     for ( int i = 0; i < mod->numSym; i++ ) {
    00212       long ll2 = strlen(mod->sym[i].name);
    00213       if ( 0 != ::strncmp(mod->sym[i].name, name.c_str(), (ll1>ll2) ? ll1 : ll2)==0 ) {
    00214               *pFunction = (EntryPoint) mod->sym[i].value;
    00215               return 1;
    00216       }
    00217     }
    00218   }
    00219   return 0;
    00220 #endif
    00221 }
    00222
    00224 unsigned long System::getProcedureByName(ImageHandle handle, const std::string& name, Creator* pFunction)    {
    00225   return getProcedureByName(handle, name, (EntryPoint*)pFunction);
    00226 }
    00227
    00229 unsigned long System::getLastError()    {
    00230 #ifdef _WIN32
    00231   return ::GetLastError();
    00232 #else
    00233   return static_cast<unsigned long>(errno);
    00234 #endif
    00235 }
    00236
    00238 const std::string System::getLastErrorString()    {
    00239   const std::string errString = getErrorString(getLastError());
    00240   return errString;
    00241 }
    00242
    00244 const std::string System::getErrorString(unsigned long error)    {
    00245   std::string errString =  "";
    00246 #ifdef _WIN32
    00247   LPVOID lpMessageBuffer;
    00248   ::FormatMessage(
    00249     FORMAT_MESSAGE_ALLOCATE_BUFFER |  FORMAT_MESSAGE_FROM_SYSTEM,
    00250     NULL,
    00251     error,
    00252     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
    00253     (LPTSTR) &lpMessageBuffer,
    00254     0,
    00255     NULL );
    00256   errString = (const char*)lpMessageBuffer;
    00257   // Free the buffer allocated by the system
    00258   ::LocalFree( lpMessageBuffer );
    00259 #else
    00260   char *cerrString(0);
    00261   // Remember: for linux dl* routines must be handled differently!
    00262   if ( error == 0xAFFEDEAD ) {
    00263     cerrString = (char*)::dlerror();
    00264     if ( 0 == cerrString ) {
    00265       cerrString = ::strerror(error);
    00266     }
    00267     if ( 0 == cerrString ) {
    00268       cerrString = (char *)"Unknown error. No information found in strerror()!";
    00269     }
    00270     else {
    00271       errString = std::string(cerrString);
    00272     }
    00273     errno = 0;
    00274   }
    00275   else    {
    00276     cerrString = ::strerror(error);
    00277     errString = std::string(cerrString);
    00278   }
    00279 #endif
    00280   return errString;
    00281 }
    00282
    00283 // This is a little bit complicated....but at least it gives
    00284 // usable results:
    00285 // Native class template:
    00286 //  Spac::templa<Spac::templa<Spac::templ<Spac::templa<AAA::a,Spac::templa<double,unsigned char>>>,B::bbb>,float>
    00287 // is translated under egcs to the unreadable string:
    00288 //  Q24Spact6templa2ZQ24Spact6templa2ZQ24Spact5templ1ZQ24Spact6templa2ZQ23AAA1aZQ24Spact6templa2ZdZUcZQ21B3bbbZf
    00289
    00290 std::string __typeName(char*&  name);
    00291 std::string __className(char*& name) {
    00292   std::string result;
    00293   int j = 0, k, i;
    00294   if ( 't' == *name ) {
    00295     goto Template;
    00296   }
    00297   for ( i = ::strtol(name, &name, 10);  i > 0; i = ::strtol(name, &name, 10) ) {
    00298     if ( j++ != 0 ) result.append("::",2);
    00299     result.append(name, i);
    00300     if ( *(name+=i) == 't' ) {
    00301       result.append("::",2);
    00302     Template:
    00303       result.append(name, (i=::strtol(++name, &name, 10)));
    00304       result.append("<");
    00305       for (k = 0, i=::strtol(name+i, &name, 10); k < i; k++ ) {
    00306         result += __typeName( ++name );
    00307         if ( k+1 < i ) result += ",";
    00308       }
    00309       result.append(">");
    00310     }
    00311   }
    00312   return result;
    00313 }
    00314
    00315 std::string __typeName(char*&  name) {
    00316   if ( *name == 'Q' ) {              // Handle name spaces
    00317     if ( *(++name) == '_' )          // >= 10 nested name spaces
    00318       ::strtol(++name, &name, 10);   // type Q_##_...
    00319     return __className(++name);
    00320   }
    00321   else if ( 't' == *name )  {
    00322     return __className(name);
    00323   }
    00324   else  {
    00325     std::string result;
    00326     char* ptr;
    00327     int i = ::strtol(name, &ptr, 10);
    00328     if ( i <= 0 )  {
    00329       name = ptr;
    00330       while ( *name != 0 && *name != 'Z' )  {
    00331         if ( *name == 'U' )  {
    00332           result += "unsigned ";
    00333           name++;
    00334         }
    00335         switch( *name++ )  {
    00336         case 'c': result += "char"; break;
    00337         case 's': result += "short"; break;
    00338         case 'i': result += "int"; break;
    00339         case 'l': result += "long"; break;
    00340         case 'f': result += "float"; break;
    00341         case 'd': result += "double"; break;
    00342         default:  result += *(name-1);
    00343         }
    00344       }
    00345       return result;
    00346     }
    00347     else {
    00348       return __className(name);
    00349     }
    00350   }
    00351 }
    00352 const std::string System::typeinfoName( const std::type_info& tinfo) {
    00353   return typeinfoName(tinfo.name());
    00354 }
    00355 const std::string System::typeinfoName( const char* class_name) {
    00356   std::string result;
    00357 #ifdef _WIN32
    00358   long off = 0;
    00359   if ( ::strncmp(class_name, "class ", 6) == 0 )   {
    00360     // The returned name is prefixed with "class "
    00361     off = 6;
    00362   }
    00363   if ( ::strncmp(class_name, "struct ", 7) == 0 )   {
    00364     // The returned name is prefixed with "struct "
    00365     off = 7;
    00366   }
    00367   if ( off > 0 )    {
    00368     std::string tmp = class_name + off;
    00369     long loc = 0;
    00370     while( (loc = tmp.find("class ")) > 0 )  {
    00371       tmp.erase(loc, 6);
    00372     }
    00373     loc = 0;
    00374     while( (loc = tmp.find("struct ")) > 0 )  {
    00375       tmp.erase(loc, 7);
    00376     }
    00377     result = tmp;
    00378   }
    00379   else  {
    00380     result = class_name;
    00381   }
    00382   // Change any " *" to "*"
    00383   while ( (off=result.find(" *")) != std::string::npos ) {
    00384     result.replace(off, 2, "*");
    00385   }
    00386   // Change any " &" to "&"
    00387   while ( (off=result.find(" &")) != std::string::npos ) {
    00388     result.replace(off, 2, "&");
    00389   }
    00390
    00391 #elif defined(__linux) || defined(__APPLE__)
    00392     if ( ::strlen(class_name) == 1 ) {
    00393       // See http://www.realitydiluted.com/mirrors/reality.sgi.com/dehnert_engr/cxx/abi.pdf
    00394       // for details
    00395       switch(class_name[0]) {
    00396       case 'v':
    00397         result = "void";
    00398         break;
    00399       case 'w':
    00400         result = "wchar_t";
    00401         break;
    00402       case 'b':
    00403         result = "bool";
    00404         break;
    00405       case 'c':
    00406         result = "char";
    00407         break;
    00408       case 'h':
    00409         result = "unsigned char";
    00410         break;
    00411       case 's':
    00412         result = "short";
    00413         break;
    00414       case 't':
    00415         result = "unsigned short";
    00416         break;
    00417       case 'i':
    00418         result = "int";
    00419         break;
    00420       case 'j':
    00421         result = "unsigned int";
    00422         break;
    00423       case 'l':
    00424         result = "long";
    00425         break;
    00426       case 'm':
    00427         result = "unsigned long";
    00428         break;
    00429       case 'x':
    00430         result = "long long";
    00431         break;
    00432       case 'y':
    00433         result = "unsigned long long";
    00434         break;
    00435       case 'n':
    00436         result = "__int128";
    00437         break;
    00438       case 'o':
    00439         result = "unsigned __int128";
    00440         break;
    00441       case 'f':
    00442         result = "float";
    00443         break;
    00444       case 'd':
    00445         result = "double";
    00446         break;
    00447       case 'e':
    00448         result = "long double";
    00449         break;
    00450       case 'g':
    00451         result = "__float128";
    00452         break;
    00453       case 'z':
    00454         result = "ellipsis";
    00455         break;
    00456       }
    00457     }
    00458     else  {
    00459       int   status;
    00460       char* realname;
    00461       realname = abi::__cxa_demangle(class_name, 0, 0, &status);
    00462       if (realname == 0) return class_name;
    00463       result = realname;
    00464       free(realname);
    00466       std::string::size_type pos = result.find(", ");
    00467       while( std::string::npos != pos ) {
    00468         result.replace( pos , 2 , "," ) ;
    00469         pos = result.find(", ");
    00470       }
    00471     }
    00472 #endif
    00473   return result;
    00474 }
    00475
    00477 const std::string& System::hostName() {
    00478   static std::string host = "";
    00479   if ( host == "" ) {
    00480     char buffer[512];
    00481     memset(buffer,0,sizeof(buffer));
    00482 #ifdef _WIN32
    00483     unsigned long len = sizeof(buffer);
    00484     ::GetComputerName(buffer, &len);
    00485 #else
    00486     ::gethostname(buffer, sizeof(buffer));
    00487 #endif
    00488     host = buffer;
    00489   }
    00490   return host;
    00491 }
    00492
    00494 const std::string& System::osName() {
    00495   static std::string osname = "";
    00496 #ifdef _WIN32
    00497   osname = "Windows";
    00498 #else
    00499   struct utsname ut;
    00500   if (uname(&ut) == 0) {
    00501     osname = ut.sysname;
    00502   } else {
    00503     osname = "UNKNOWN";
    00504   }
    00505 #endif
    00506   return osname;
    00507 }
    00508
    00509
    00511 const std::string& System::osVersion() {
    00512   static std::string osver = "";
    00513 #ifdef _WIN32
    00514   OSVERSIONINFO ut;
    00515   ut.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    00516   ::GetVersionEx(&ut);
    00517   char ver[64];
    00518   sprintf(ver,"%d.%d",ut.dwMajorVersion,ut.dwMinorVersion);
    00519   osver = ver;
    00520 #else
    00521   struct utsname ut;
    00522   if (uname(&ut) == 0) {
    00523     osver = ut.release;
    00524   } else {
    00525     osver = "UNKNOWN";
    00526   }
    00527 #endif
    00528   return osver;
    00529 }
    00530
    00532 const std::string& System::machineType() {
    00533   static std::string mach = "";
    00534 #ifdef _WIN32
    00535   SYSTEM_INFO ut;
    00536   ::GetSystemInfo(&ut);
    00537   char arch[64];
    00538   sprintf(arch,"%d",ut.wProcessorArchitecture);
    00539   mach =  arch;
    00540 #else
    00541   struct utsname ut;
    00542   if (uname(&ut) == 0) {
    00543     mach = ut.machine;
    00544   } else {
    00545     mach = "UNKNOWN";
    00546   }
    00547 #endif
    00548   return mach;
    00549 }
    00550
    00552 const std::string& System::accountName() {
    00553   static std::string account = "";
    00554   if ( account == "" ) {
    00555 #ifdef _WIN32
    00556     char buffer[512];
    00557     unsigned long buflen = sizeof(buffer);
    00558     ::GetUserName(buffer, &buflen);
    00559     account = buffer;
    00560 #else
    00561     const char* acct = ::getlogin();
    00562     if ( 0 == acct ) acct = ::getenv("LOGNAME");
    00563     if ( 0 == acct ) acct = ::getenv("USER");
    00564     account = (acct) ? acct : "Unknown";
    00565 #endif
    00566   }
    00567   return account;
    00568 }
    00569
    00571 long System::numCmdLineArgs()   {
    00572   return cmdLineArgs().size();
    00573 }
    00574
    00576 long System::argc()    {
    00577   return cmdLineArgs().size();
    00578 }
    00579
    00581 const std::vector<std::string> System::cmdLineArgs()    {
    00582   if ( s_argvChars.size() == 0 )    {
    00583     char exe[1024];
    00584 #ifdef _WIN32
    00585     // For compatibility with UNIX we CANNOT use strtok!
    00586     // If we would use strtok, options like -g="My world" at
    00587     // the command line level would result on NT in TWO options
    00588     // instead in one as in UNIX.
    00589     char *next, *tmp1, *tmp2;
    00590     for(LPTSTR cmd = ::GetCommandLine(); *cmd; cmd=next)   {
    00591       memset(exe,0,sizeof(exe));
    00592       while ( *cmd == ' ' ) cmd++;
    00593       next=::strchr(cmd,' ');
    00594       if ( !next ) next = cmd + strlen(cmd);
    00595       if ( (tmp1=::strchr(cmd,'\"')) > 0 && tmp1 < next )  {
    00596         tmp2 = ::strchr(++tmp1,'\"');
    00597         if ( tmp2 > 0 )   {
    00598           next = ++tmp2;
    00599           if ( cmd < tmp1 ) strncpy(exe, cmd, tmp1-cmd-1);
    00600           strncpy(&exe[strlen(exe)], tmp1, tmp2-tmp1-1);
    00601         }
    00602         else    {
    00603           std::cout << "Mismatched \" in command line arguments" << std::endl;
    00604           s_argvChars.erase(s_argvChars.begin(), s_argvChars.end());
    00605           s_argvStrings.erase(s_argvStrings.begin(), s_argvStrings.end());
    00606           return s_argvStrings;
    00607         }
    00608       }
    00609       else    {
    00610         strncpy(exe, cmd, next-cmd);
    00611       }
    00612       s_argvStrings.push_back(exe);
    00613       s_argvChars.push_back( s_argvStrings.back().c_str());
    00614     }
    00615 #elif defined(linux) || defined(__APPLE__)
    00616     sprintf(exe, "/proc/%d/cmdline", ::getpid());
    00617     FILE *cmdLine = ::fopen(exe,"r");
    00618     char cmd[1024];
    00619     if ( cmdLine )   {
    00620       long len = fread(cmd, sizeof(char), sizeof(cmd), cmdLine);
    00621       if ( len > 0 )   {
    00622         cmd[len] = 0;
    00623         for ( char* token = cmd; token-cmd < len; token += strlen(token)+1 )  {
    00624           s_argvStrings.push_back(token);
    00625           s_argvChars.push_back( s_argvStrings.back().c_str());
    00626         }
    00627         s_argvStrings[0] = exeName();
    00628         s_argvChars[0]   = s_argvStrings[0].c_str();
    00629       }
    00630     }
    00631     ::fclose(cmdLine);
    00632 #endif
    00633   }
    00634   return s_argvStrings;
    00635 }
    00636
    00638 char** System::argv()    {
    00640   if( s_argvChars.empty() ) { cmdLineArgs(); }
    00641
    00642   // We rely here on the fact that a vector's allocation table is contiguous
    00643   return (char**)&s_argvChars[0];
    00644 }
    00645
    00647 const std::string System::getEnv(const char* var) {
    00648   char* env;
    00649   if  ( (env = getenv(var)) != 0 ) {
    00650     return env;
    00651   } else {
    00652     return "UNKNOWN";
    00653   }
    00654 }
    00655
    00657 #if defined(__APPLE__)
    00658 // Needed for _NSGetEnviron(void)
    00659 #include "crt_externs.h"
    00660 #endif
    00661 const std::vector<std::string> System::getEnv() {
    00662 #if defined(_WIN32)
    00663 #  define environ _environ
    00664 #elif defined(linux)
    00665   extern char **environ;
    00666 #elif defined(__APPLE__)
    00667   static char **environ = *_NSGetEnviron();
    00668 #endif
    00669   std::vector<std::string> vars;
    00670   for (int i=0; environ[i] != 0; ++i) {
    00671     vars.push_back(environ[i]);
    00672   }
    00673   return vars;
    00674 }
    00675
    00676 bool System::backTrace(void** addresses __attribute__ ((unused)),
    00677                        const size_t depth __attribute__ ((unused)))
    00678 {
    00679
    00680 #ifdef __linux
    00681
    00682   if ( backtrace( addresses, depth ) > 0 ) {
    00683     return true ;
    00684   } else {
    00685     return false ;
    00686   }
    00687
    00688 #else // windows and osx parts not implemented
    00689   return false ;
    00690 #endif
    00691
    00692 }
    00693
    00694
    00695
    00696 bool System::getStackLevel(void* addresses  __attribute__ ((unused)),
    00697                            void*& addr      __attribute__ ((unused)),
    00698                            std::string& fnc __attribute__ ((unused)),
    00699                            std::string& lib __attribute__ ((unused)))
    00700 {
    00701
    00702 #ifdef __linux
    00703
    00704   Dl_info info;
    00705
    00706   if ( dladdr( addresses, &info ) && info.dli_fname
    00707       && info.dli_fname[0] != '\0' ) {
    00708     const char* symbol = info.dli_sname
    00709     && info.dli_sname[0] != '\0' ? info.dli_sname : 0;
    00710
    00711     lib = info.dli_fname;
    00712     addr = info.dli_saddr;
    00713     const char* dmg(0);
    00714
    00715     if (symbol != 0) {
    00716       int stat;
    00717       dmg = abi::__cxa_demangle(symbol,0,0,&stat);
    00718       fnc = (stat == 0) ? dmg : symbol;
    00719     } else {
    00720       fnc = "local";
    00721     }
    00722     free((void*)dmg);
    00723     return true ;
    00724   } else {
    00725     return false ;
    00726   }
    00727
    00728 #else // not implemented for windows and osx
    00729   return false ;
    00730 #endif
    00731
    00732 }
    00733
    00735 int System::setEnv(const std::string &name, const std::string &value, int overwrite)
    00736 {
    00737 #ifndef WIN32
    00738   // UNIX version
    00739   return value.empty() ?
    00740     // remove if set to nothing (and return success)
    00741     ::unsetenv(name.c_str()) , 0 :
    00742     // set the value
    00743     ::setenv(name.c_str(),value.c_str(), overwrite);
    00744 #else
    00745   // Windows version
    00746   if ( value.empty() ) {
    00747     // equivalent to unsetenv
    00748     return ::_putenv((name+"=").c_str());
    00749   }
    00750   else {
    00751     if ( !getenv(name.c_str()) || overwrite ) {
    00752       // set if not yet present or overwrite is set (force)
    00753       return ::_putenv((name+"="+value).c_str());
    00754     }
    00755   }
    00756   return 0; // if we get here, we are trying to set a variable already set, but
    00757             // not to overwrite.
    00758             // It is considered a success on Linux (man P setenv)
    00759 #endif
    00760
    00761 }
    00762