| # Gaudi Framework, version v22r4 |

Home |  | Generated: Fri Sep 2 2011

# System.cpp

Go to the documentation of this file.

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

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines