X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;ds=inline;f=common%2Fos_posix.cpp;h=da7878311a72f970a309fd11a3f3c5cf90fddc58;hb=03c5d3d41dc219051cbbb8b84ea505e15ff433c4;hp=9271e8863b14c4f837ba9f131da41ca7f57d0f91;hpb=b4a3d1495a5e92ba23bf463bcea34a6e75b55294;p=apitrace diff --git a/common/os_posix.cpp b/common/os_posix.cpp index 9271e88..da78783 100644 --- a/common/os_posix.cpp +++ b/common/os_posix.cpp @@ -31,16 +31,28 @@ #include #include +#include #include #include #include #include +#if defined(__linux__) +#include // PATH_MAX +#endif + #ifdef __APPLE__ +#include // PATH_MAX #include #endif +#ifndef PATH_MAX +#warning PATH_MAX undefined +#define PATH_MAX 4096 +#endif + #include "os.hpp" +#include "os_path.hpp" namespace os { @@ -51,72 +63,109 @@ mutex = PTHREAD_MUTEX_INITIALIZER; void -AcquireMutex(void) +acquireMutex(void) { pthread_mutex_lock(&mutex); } void -ReleaseMutex(void) +releaseMutex(void) { pthread_mutex_unlock(&mutex); } -bool -GetProcessName(char *str, size_t size) +Path +getProcessName(void) { - char szProcessPath[PATH_MAX + 1]; - char *lpProcessName; + Path path; + size_t size = PATH_MAX; + char *buf = path.buf(size); // http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe #ifdef __APPLE__ - uint32_t len = sizeof szProcessPath; - if (_NSGetExecutablePath(szProcessPath, &len) != 0) { - *str = 0; - return false; + uint32_t len = size; + if (_NSGetExecutablePath(buf, &len) != 0) { + *buf = 0; + return path; } + len = strlen(buf); #else ssize_t len; - len = readlink("/proc/self/exe", szProcessPath, sizeof(szProcessPath) - 1); + len = readlink("/proc/self/exe", buf, size - 1); if (len == -1) { // /proc/self/exe is not available on setuid processes, so fallback to // /proc/self/cmdline. int fd = open("/proc/self/cmdline", O_RDONLY); if (fd >= 0) { - len = read(fd, szProcessPath, sizeof(szProcessPath) - 1); + len = read(fd, buf, size - 1); close(fd); } } if (len <= 0) { - snprintf(str, size, "%i", (int)getpid()); - return true; + snprintf(buf, size, "%i", (int)getpid()); + return path; } #endif - szProcessPath[len] = 0; + path.truncate(len); - lpProcessName = strrchr(szProcessPath, '/'); - lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath; + return path; +} - strncpy(str, lpProcessName, size); - if (size) - str[size - 1] = 0; +Path +getCurrentDir(void) +{ + Path path; + size_t size = PATH_MAX; + char *buf = path.buf(size); + + getcwd(buf, size); + buf[size - 1] = 0; + + path.truncate(); + return path; +} + +bool +Path::exists(void) const +{ + struct stat st; + int err; + + err = stat(str(), &st); + if (err) { + return false; + } + + if (!S_ISREG(st.st_mode)) + return false; return true; } -bool -GetCurrentDir(char *str, size_t size) +int execute(char * const * args) { - char *ret; - ret = getcwd(str, size); - str[size - 1] = 0; - return ret ? true : false; + pid_t pid = fork(); + if (pid == 0) { + // child + execvp(args[0], args); + fprintf(stderr, "error: failed to execute %s\n", args[0]); + exit(-1); + } else { + // parent + if (pid == -1) { + fprintf(stderr, "error: failed to fork\n"); + return -1; + } + int status = -1; + waitpid(pid, &status, 0); + return status; + } } void -DebugMessage(const char *format, ...) +log(const char *format, ...) { va_list ap; va_start(ap, format); @@ -125,7 +174,8 @@ DebugMessage(const char *format, ...) va_end(ap); } -long long GetTime(void) +long long +getTime(void) { struct timeval tv; gettimeofday(&tv, NULL); @@ -133,7 +183,7 @@ long long GetTime(void) } void -Abort(void) +abort(void) { exit(0); } @@ -151,14 +201,15 @@ struct sigaction old_actions[NUM_SIGNALS]; * - http://sourceware.org/git/?p=glibc.git;a=blob;f=debug/segfault.c * - http://ggi.cvs.sourceforge.net/viewvc/ggi/ggi-core/libgg/gg/cleanup.c?view=markup */ -static void signal_handler(int sig, siginfo_t *info, void *context) +static void +signalHandler(int sig, siginfo_t *info, void *context) { static int recursion_count = 0; - fprintf(stderr, "signal_handler: sig = %i\n", sig); + fprintf(stderr, "apitrace: warning: caught signal %i\n", sig); if (recursion_count) { - fprintf(stderr, "recursion with sig %i\n", sig); + fprintf(stderr, "apitrace: warning: recursion handling signal %i\n", sig); } else { if (gCallback) { ++recursion_count; @@ -170,7 +221,7 @@ static void signal_handler(int sig, siginfo_t *info, void *context) struct sigaction *old_action; if (sig >= NUM_SIGNALS) { /* This should never happen */ - fprintf(stderr, "Unexpected signal %i\n", sig); + fprintf(stderr, "error: unexpected signal %i\n", sig); raise(SIGKILL); } old_action = &old_actions[sig]; @@ -180,7 +231,7 @@ static void signal_handler(int sig, siginfo_t *info, void *context) old_action->sa_sigaction(sig, info, context); } else { if (old_action->sa_handler == SIG_DFL) { - fprintf(stderr, "taking default action for signal %i\n", sig); + fprintf(stderr, "apitrace: info: taking default action for signal %i\n", sig); #if 1 struct sigaction dfl_action; @@ -203,14 +254,14 @@ static void signal_handler(int sig, siginfo_t *info, void *context) } void -SetExceptionCallback(void (*callback)(void)) +setExceptionCallback(void (*callback)(void)) { assert(!gCallback); if (!gCallback) { gCallback = callback; struct sigaction new_action; - new_action.sa_sigaction = signal_handler; + new_action.sa_sigaction = signalHandler; sigemptyset(&new_action.sa_mask); new_action.sa_flags = SA_SIGINFO | SA_RESTART; @@ -227,7 +278,7 @@ SetExceptionCallback(void (*callback)(void)) } void -ResetExceptionCallback(void) +resetExceptionCallback(void) { gCallback = NULL; }