27 #elif defined( __APPLE__ )
29 #elif defined( _WIN32 )
34 # define VCL_NAMESPACE Gaudi
40 # define strcasecmp _stricmp
41 # define strncasecmp _strnicmp
42 # define getpid _getpid
49 static const std::array<const char*, 1> SHLIB_SUFFIXES = {
".dll" };
50 #else // UNIX...: first the EGCS stuff, then the OS dependent includes
56 # include <sys/times.h>
58 # if defined( __linux ) || defined( __APPLE__ )
60 # include <sys/utsname.h>
69 # endif // HPUX or not...
72 static const std::array<const char*, 2> SHLIB_SUFFIXES = {
".dylib",
".so" };
74 static const std::array<const char*, 1> SHLIB_SUFFIXES = {
".so" };
77 #endif // Windows or Unix...
85 # if defined( __linux )
86 void* mh = ::dlopen(
name.length() == 0 ?
nullptr :
path, RTLD_LAZY | RTLD_GLOBAL );
88 # elif defined( __APPLE__ )
89 void* mh = ::dlopen(
name.length() == 0 ?
nullptr :
path, RTLD_LAZY | RTLD_GLOBAL );
92 shl_t mh = ::shl_load(
name.length() == 0 ? 0 :
path, BIND_IMMEDIATE | BIND_VERBOSE, 0 );
93 HMODULE*
mod =
new HMODULE;
95 if ( 0 != ::shl_gethandle_r( mh, &
mod->dsc ) ) {
96 std::cout <<
"System::loadDynamicLib>" << ::strerror(
getLastError() ) << std::endl;
98 typedef void* ( *___all )();
99 ___all _alloc = (___all)malloc;
100 mod->numSym = ::shl_getsymbols(
mod->dsc.handle, TYPE_PROCEDURE, EXPORT_SYMBOLS, malloc, &
mod->sym );
113 if (
name.length() == 0 ) {
return doLoad(
name, handle ); }
117 std::string dllName =
name;
118 bool hasShlibSuffix =
false;
119 for (
const char* suffix : SHLIB_SUFFIXES ) {
120 const size_t len = strlen( suffix );
121 if ( dllName.compare( dllName.length() - len, len, suffix ) == 0 ) {
122 hasShlibSuffix =
true;
129 if ( !hasShlibSuffix ) { dllName += SHLIB_SUFFIXES[0]; }
132 return doLoad( dllName, handle );
137 unsigned long res = 0;
139 if (
name.length() == 0 ) {
140 res = loadWithoutEnvironment(
name, handle );
146 res = loadWithoutEnvironment( imgName, handle );
149 std::string dllName =
name;
152 #if defined( __linux ) || defined( __APPLE__ )
153 if ( ( dllName.find(
'/' ) == std::string::npos ) && ( dllName.compare( 0, 3,
"lib" ) != 0 ) ) {
154 dllName =
"lib" + dllName;
159 for (
const char* suffix : SHLIB_SUFFIXES ) {
161 std::string libName = dllName;
162 const size_t len = strlen( suffix );
163 if ( dllName.compare( dllName.length() - len, len, suffix ) != 0 ) { libName += suffix; }
165 res = loadWithoutEnvironment( libName, handle );
167 if ( res == 1 ) {
break; }
171 #if defined( __linux ) || defined( __APPLE__ )
183 if ( !::FreeLibrary( (HINSTANCE)handle ) ) {
184 #elif defined( __linux ) || defined( __APPLE__ )
191 HMODULE*
mod = (HMODULE*)handle;
192 if ( 0 == ::shl_unload(
mod->dsc.handle ) ) {
206 *pFunction = (
EntryPoint )::GetProcAddress( (HINSTANCE)handle,
name.data() );
209 #elif defined( __linux )
210 *pFunction =
reinterpret_cast<EntryPoint>( ::dlsym( handle,
name.c_str() ) );
217 #elif defined( __APPLE__ )
219 if ( !( *pFunction ) ) {
224 if ( 0 == *pFunction ) {
232 HMODULE*
mod = (HMODULE*)handle;
234 long ll1 =
name.length();
235 for (
int i = 0; i <
mod->numSym; i++ ) {
236 long ll2 = strlen(
mod->sym[i].name );
237 if ( 0 != ::strncmp(
mod->sym[i].name,
name.c_str(), ( ll1 > ll2 ) ? ll1 : ll2 ) == 0 ) {
257 return ::GetLastError();
260 return static_cast<unsigned long>(
static_cast<unsigned int>( errno ) );
272 std::string errString =
"";
274 LPVOID lpMessageBuffer;
275 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error,
276 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
277 (LPTSTR)&lpMessageBuffer, 0, NULL );
278 errString = (
const char*)lpMessageBuffer;
280 ::LocalFree( lpMessageBuffer );
282 char* cerrString(
nullptr );
284 if ( error == 0xAFFEDEAD ) {
285 cerrString = ::dlerror();
286 if ( !cerrString ) cerrString = ::strerror( error );
288 cerrString = (
char*)
"Unknown error. No information found in strerror()!";
290 errString = std::string( cerrString );
294 cerrString = ::strerror( error );
295 errString = std::string( cerrString );
331 using namespace Gaudi;
358 auto helperFunc = [](
const std::vector<std::string>&
args ) -> std::vector<const char*> {
359 std::vector<const char*> result;
360 std::transform(
args.begin(),
args.end(), std::back_inserter( result ),
361 [](
const std::string&
s ) { return s.c_str(); } );
364 static const std::vector<const char*>
args = helperFunc(
cmdLineArgs() );
366 return (
char**)&(
args[0] );
372 # pragma warning( disable : 4996 )
378 if ( ( env = getenv( var ) ) !=
nullptr ) {
388 if ( ( env = getenv( var ) ) !=
nullptr ) {
399 #if defined( __APPLE__ )
401 # include <crt_externs.h>
404 #if defined( _WIN32 )
405 # define environ _environ
406 #elif defined( __APPLE__ )
407 static char** environ = *_NSGetEnviron();
409 std::vector<std::string> vars;
410 for (
int i = 0; environ[i] !=
nullptr; ++i ) { vars.push_back( environ[i] ); }
418 # include <execinfo.h>
421 int System::backTrace( [[maybe_unused]]
void** addresses, [[maybe_unused]]
const int depth ) {
425 int count = backtrace( addresses, depth );
426 return count > 0 ? count : 0;
428 #else // windows and osx parts not implemented
436 const size_t totalOffset = offset + 2;
437 const size_t totalDepth = depth + totalOffset;
439 std::string fnc, lib;
441 std::vector<void*> addresses( totalDepth,
nullptr );
443 for (
size_t i = totalOffset; i < count; ++i ) {
444 void* addr =
nullptr;
447 std::ostringstream ost;
448 ost <<
"#" << std::setw( 3 ) << std::setiosflags( std::ios::left ) << i - totalOffset + 1;
449 ost <<
std::hex << addr <<
std::dec <<
" " << fnc <<
" [" << lib <<
"]" << std::endl;
454 }
catch (
const std::bad_alloc& e ) {
return false; }
458 [[maybe_unused]] std::string& fnc, [[maybe_unused]] std::string& lib ) {
464 if ( dladdr( addresses, &info ) && info.dli_fname && info.dli_fname[0] !=
'\0' ) {
465 const char* symbol = info.dli_sname && info.dli_sname[0] !=
'\0' ? info.dli_sname :
nullptr;
467 lib = info.dli_fname;
468 addr = info.dli_saddr;
473 std::unique_ptr<char, decltype( free )*>( abi::__cxa_demangle( symbol,
nullptr,
nullptr, &stat ), std::free );
474 fnc = ( stat == 0 ) ? dmg.get() : symbol;
483 #else // not implemented for windows and osx
492 return value.empty() ?
494 ::unsetenv(
name.c_str() ),
497 ::setenv(
name.c_str(), value.c_str(), overwrite );
500 if ( value.empty() ) {
502 return ::_putenv( (
name +
"=" ).c_str() );
504 if ( !getenv(
name.c_str() ) || overwrite ) {
506 return ::_putenv( (
name +
"=" + value ).c_str() );