27#elif defined( __APPLE__ )
38#if defined( __linux ) || defined( __APPLE__ )
40# include <sys/utsname.h>
52static const std::array<const char*, 2> SHLIB_SUFFIXES = {
".dylib",
".so" };
54static const std::array<const char*, 1> SHLIB_SUFFIXES = {
".so" };
60 void* mh = ::dlopen(
name.length() == 0 ?
nullptr : path, RTLD_LAZY | RTLD_GLOBAL );
62#elif defined( __APPLE__ )
63 void* mh = ::dlopen(
name.length() == 0 ?
nullptr : path, RTLD_LAZY | RTLD_GLOBAL );
66 shl_t mh = ::shl_load(
name.length() == 0 ? 0 : path, BIND_IMMEDIATE | BIND_VERBOSE, 0 );
67 HMODULE*
mod =
new HMODULE;
69 if ( 0 != ::shl_gethandle_r( mh, &
mod->dsc ) ) {
70 std::cout <<
"System::loadDynamicLib>" << ::strerror(
getLastError() ) << std::endl;
72 typedef void* ( *___all )();
73 ___all _alloc = (___all)malloc;
74 mod->numSym = ::shl_getsymbols(
mod->dsc.handle, TYPE_PROCEDURE, EXPORT_SYMBOLS, malloc, &
mod->sym );
83static unsigned long loadWithoutEnvironment(
const std::string& name,
System::ImageHandle* handle ) {
86 if (
name.length() == 0 ) {
return doLoad(
name, handle ); }
90 std::string dllName =
name;
91 bool hasShlibSuffix =
false;
92 for (
const char* suffix : SHLIB_SUFFIXES ) {
93 const size_t len = strlen( suffix );
94 if ( dllName.compare( dllName.length() - len, len, suffix ) == 0 ) {
95 hasShlibSuffix =
true;
102 if ( !hasShlibSuffix ) { dllName += SHLIB_SUFFIXES[0]; }
105 return doLoad( dllName, handle );
110 unsigned long res = 0;
112 if ( name.length() == 0 ) {
113 res = loadWithoutEnvironment( name, handle );
118 if (
getEnv( name, imgName ) ) {
119 res = loadWithoutEnvironment( imgName, handle );
122 std::string dllName = name;
125#if defined( __linux ) || defined( __APPLE__ )
126 if ( ( dllName.find(
'/' ) == std::string::npos ) && ( dllName.compare( 0, 3,
"lib" ) != 0 ) ) {
127 dllName =
"lib" + dllName;
132 for (
const char* suffix : SHLIB_SUFFIXES ) {
134 std::string libName = dllName;
135 const size_t len = strlen( suffix );
136 if ( dllName.compare( dllName.length() - len, len, suffix ) != 0 ) { libName += suffix; }
138 res = loadWithoutEnvironment( libName, handle );
140 if ( res == 1 ) {
break; }
144#if defined( __linux ) || defined( __APPLE__ )
155#if defined( __linux ) || defined( __APPLE__ )
162 HMODULE* mod = (HMODULE*)handle;
163 if ( 0 == ::shl_unload( mod->dsc.handle ) ) {
176#if defined( __linux )
177 *pFunction =
reinterpret_cast<EntryPoint>( ::dlsym( handle, name.c_str() ) );
184#elif defined( __APPLE__ )
185 *pFunction = (
EntryPoint )::dlsym( handle, name.c_str() );
186 if ( !( *pFunction ) ) {
188 std::string sname =
"_" + name;
189 *pFunction = (
EntryPoint )::dlsym( handle, sname.c_str() );
191 if ( 0 == *pFunction ) {
199 HMODULE* mod = (HMODULE*)handle;
201 long ll1 = name.length();
202 for (
int i = 0; i < mod->numSym; i++ ) {
203 long ll2 = strlen( mod->sym[i].name );
204 if ( 0 != ::strncmp( mod->sym[i].name, name.c_str(), ( ll1 > ll2 ) ? ll1 : ll2 ) == 0 ) {
224 return static_cast<unsigned long>(
static_cast<unsigned int>( errno ) );
235 std::string errString =
"";
236 char* cerrString(
nullptr );
238 if ( error == 0xAFFEDEAD ) {
239 cerrString = ::dlerror();
240 if ( !cerrString ) cerrString = ::strerror( error );
242 cerrString = (
char*)
"Unknown error. No information found in strerror()!";
244 errString = std::string( cerrString );
248 cerrString = ::strerror( error );
249 errString = std::string( cerrString );
256const std::string
System::typeinfoName(
const char* class_name ) {
return Platform::typeinfoName( class_name ); }
260 static const std::string host = Platform::hostName();
266 static const std::string osname = Platform::osName();
272 static const std::string osver = Platform::osVersion();
278 static const std::string mach = Platform::machineType();
284 static const std::string account = Platform::accountName();
296 static const std::vector<std::string> args = Platform::cmdLineArgs();
302 auto helperFunc = [](
const std::vector<std::string>& args ) -> std::vector<const char*> {
303 std::vector<const char*> result;
304 std::transform( args.begin(), args.end(), std::back_inserter( result ),
305 [](
const std::string& s ) { return s.c_str(); } );
308 static const std::vector<const char*> args = helperFunc(
cmdLineArgs() );
310 return (
char**)&( args[0] );
316 if ( ( env = getenv( var ) ) !=
nullptr ) {
326 if ( ( env = getenv( var ) ) !=
nullptr ) {
337#if defined( __APPLE__ )
339# include <crt_externs.h>
342#if defined( __APPLE__ )
343 static char** environ = *_NSGetEnviron();
345 std::vector<std::string> vars;
346 for (
int i = 0; environ[i] !=
nullptr; ++i ) { vars.push_back( environ[i] ); }
353#if defined( __linux ) || defined( __APPLE__ )
354# include <execinfo.h>
359#if defined( __linux ) || defined( __APPLE__ )
361 int count = backtrace( addresses, depth );
362 return count > 0 ? count : 0;
372 const size_t totalOffset = offset + 2;
373 const size_t totalDepth = depth + totalOffset;
375 std::string fnc, lib;
377 std::vector<void*> addresses( totalDepth,
nullptr );
379 for (
size_t i = totalOffset; i < count; ++i ) {
380 void* addr =
nullptr;
383 std::ostringstream ost;
384 ost <<
"#" << std::setw( 3 ) << std::setiosflags( std::ios::left ) << i - totalOffset + 1;
385 ost << std::hex << addr << std::dec <<
" " << fnc <<
" [" << lib <<
"]" << std::endl;
390 }
catch (
const std::bad_alloc& e ) {
return false; }
394 [[maybe_unused]] std::string& fnc, [[maybe_unused]] std::string& lib ) {
396#if defined( __linux ) || defined( __APPLE__ )
400 if ( dladdr( addresses, &info ) && info.dli_fname && info.dli_fname[0] !=
'\0' ) {
401 const char* symbol = info.dli_sname && info.dli_sname[0] !=
'\0' ? info.dli_sname :
nullptr;
403 lib = info.dli_fname;
404 addr = info.dli_saddr;
409 std::unique_ptr<char, decltype( free )*>( abi::__cxa_demangle( symbol,
nullptr,
nullptr, &stat ), std::free );
410 fnc = ( stat == 0 ) ? dmg.get() : symbol;
425int System::setEnv(
const std::string& name,
const std::string& value,
int overwrite ) {
426 return value.empty() ?
428 ::unsetenv( name.c_str() ),
431 ::setenv( name.c_str(), value.c_str(), overwrite );
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
GAUDI_API bool getStackLevel(void *addresses, void *&addr, std::string &fnc, std::string &lib)
GAUDI_API const std::string & osName()
OS name.
GAUDI_API int backTrace(void **addresses, const int depth)
void *(* Creator)()
Definition of the "generic" DLL entry point function.
GAUDI_API bool isEnvSet(const char *var)
Check if an environment variable is set or not.
unsigned long(* EntryPoint)(const unsigned long iid, void **ppvObject)
Definition of the "generic" DLL entry point function.
GAUDI_API const std::string & machineType()
Machine type.
GAUDI_API unsigned long loadDynamicLib(const std::string &name, ImageHandle *handle)
Load dynamic link library.
GAUDI_API long numCmdLineArgs()
Number of arguments passed to the commandline.
GAUDI_API const std::string getLastErrorString()
Get last system error as string.
GAUDI_API unsigned long unloadDynamicLib(ImageHandle handle)
unload dynamic link library
GAUDI_API unsigned long getProcedureByName(ImageHandle handle, const std::string &name, EntryPoint *pFunction)
Get a specific function defined in the DLL.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
void * ImageHandle
Definition of an image handle.
GAUDI_API std::vector< std::string > getEnv()
get all environment variables
GAUDI_API const std::string & hostName()
Host name.
GAUDI_API const std::string & accountName()
User login name.
GAUDI_API unsigned long getLastError()
Get last system known error.
GAUDI_API long argc()
Number of arguments passed to the commandline (==numCmdLineArgs()); just to match argv call....
GAUDI_API const std::string getErrorString(unsigned long error)
Retrieve error code as string for a given error.
GAUDI_API const std::vector< std::string > cmdLineArgs()
Command line arguments including executable name as arg[0] as vector of strings.
GAUDI_API int setEnv(const std::string &name, const std::string &value, int overwrite=1)
Set an environment variables.
GAUDI_API char ** argv()
char** command line arguments including executable name as arg[0]; You may not modify them!
GAUDI_API const std::string & osVersion()
OS version.