diff --git a/CMakeLists.txt b/CMakeLists.txt index c1223777f..0e19d06c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,15 @@ if (WITH_FUZZING STREQUAL none) check_cxx_symbol_exists (abi::__cxa_demangle cxxabi.h HAVE___CXA_DEMANGLE) endif (WITH_FUZZING STREQUAL none) +check_cxx_symbol_exists (__argv cstdlib HAVE___ARGV) +check_cxx_symbol_exists (getprogname cstdlib HAVE_GETPROGNAME) +check_cxx_symbol_exists (program_invocation_short_name cerrno HAVE_PROGRAM_INVOCATION_SHORT_NAME) +check_cxx_source_compiles ([=[ +#include +extern char* __progname; +int main() { return __progname != nullptr ? EXIT_SUCCESS : EXIT_FAILURE; } +]=] HAVE___PROGNAME) + if (WITH_TLS) set (GLOG_THREAD_LOCAL_STORAGE 1) endif (WITH_TLS) diff --git a/src/config.h.cmake.in b/src/config.h.cmake.in index 1aec46119..dac54d7c9 100644 --- a/src/config.h.cmake.in +++ b/src/config.h.cmake.in @@ -115,4 +115,16 @@ /* define if abi::__cxa_demangle is available in cxxabi.h */ #cmakedefine HAVE___CXA_DEMANGLE +/* define if __argv is available in cstdlib */ +#cmakedefine HAVE___ARGV + +/* define if __progname is available */ +#cmakedefine HAVE___PROGNAME + +/* define if getprogname is available in cstdlib */ +#cmakedefine HAVE_GETPROGNAME + +/* define if program_invocation_short_name is available in cerrno */ +#cmakedefine HAVE_PROGRAM_INVOCATION_SHORT_NAME + #endif // GLOG_CONFIG_H diff --git a/src/utilities.cc b/src/utilities.cc index 51ddc9c9c..09a5050bc 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -29,9 +29,12 @@ // // Author: Shinichiro Hamaji +#define _GNU_SOURCE 1 + #include "utilities.h" #include +#include #include #include #include @@ -61,6 +64,10 @@ # include #endif +#if defined(HAVE___PROGNAME) +extern char* __progname; +#endif + using std::string; namespace google { @@ -189,13 +196,29 @@ namespace google { inline namespace glog_internal_namespace_ { +const char* const_basename(const char* filepath) { + const char* base = strrchr(filepath, '/'); +#ifdef GLOG_OS_WINDOWS // Look for either path separator in Windows + if (!base) base = strrchr(filepath, '\\'); +#endif + return base ? (base + 1) : filepath; +} + const char* ProgramInvocationShortName() { if (g_program_invocation_short_name != nullptr) { return g_program_invocation_short_name; - } else { - // TODO(hamaji): Use /proc/self/cmdline and so? - return "UNKNOWN"; } +#if defined(HAVE_PROGRAM_INVOCATION_SHORT_NAME) + return program_invocation_short_name; +#elif defined(HAVE_GETPROGNAME) + return getprogname(); +#elif defined(HAVE___PROGNAME) + return __progname; +#elif defined(HAVE___ARGV) + return const_basename(__argv[0]); +#else + return "UNKNOWN"; +#endif } static int32 g_main_thread_pid = getpid(); @@ -210,14 +233,6 @@ bool PidHasChanged() { return true; } -const char* const_basename(const char* filepath) { - const char* base = strrchr(filepath, '/'); -#ifdef GLOG_OS_WINDOWS // Look for either path separator in Windows - if (!base) base = strrchr(filepath, '\\'); -#endif - return base ? (base + 1) : filepath; -} - static string g_my_user_name; const string& MyUserName() { return g_my_user_name; } static void MyUserNameInitializer() { @@ -268,11 +283,7 @@ void SetCrashReason(const logging::internal::CrashReason* r) { void InitGoogleLoggingUtilities(const char* argv0) { CHECK(!IsGoogleLoggingInitialized()) << "You called InitGoogleLogging() twice!"; - const char* slash = strrchr(argv0, '/'); -#ifdef GLOG_OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); -#endif - g_program_invocation_short_name = slash ? slash + 1 : argv0; + g_program_invocation_short_name = const_basename(argv0); #ifdef HAVE_STACKTRACE InstallFailureFunction(&DumpStackTraceAndExit);