this repo has no description
at trunk 105 lines 2.7 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "os.h" 3 4#include <dlfcn.h> 5#include <mach-o/dyld.h> 6#include <pthread.h> 7 8#include <csignal> 9#include <cstdint> 10#include <cstdlib> 11 12#include "utils.h" 13 14namespace py { 15 16const word OS::kNumSignals = NSIG; 17bool volatile OS::pending_signals_[kNumSignals]; 18 19const int OS::kRtldGlobal = RTLD_GLOBAL; 20const int OS::kRtldLocal = RTLD_LOCAL; 21const int OS::kRtldNow = RTLD_NOW; 22 23const char* OS::name() { return "darwin"; } 24 25// clang-format off 26#define V(SIGNAL) { #SIGNAL, SIGNAL } 27const OS::Signal OS::kPlatformSignals[] = { 28 V(SIGEMT), 29 V(SIGINFO), 30 V(SIGIO), 31 V(SIGIOT), 32 V(SIGPROF), 33 V(SIGSYS), 34 V(SIGVTALRM), 35 V(SIGWINCH), 36 { nullptr, 0 }, 37}; 38#undef V 39// clang-format on 40 41void OS::createThread(ThreadFunction func, void* arg) { 42 pthread_t thread; 43 pthread_create(&thread, nullptr, func, arg); 44 pthread_detach(thread); 45} 46 47char* OS::executablePath() { 48 uint32_t buf_len = 0; 49 int res = _NSGetExecutablePath(nullptr, &buf_len); 50 CHECK(res == -1, "expected buffer too small"); 51 unique_c_ptr<char> path(reinterpret_cast<char*>(std::malloc(buf_len))); 52 CHECK(path != nullptr, "out of memory"); 53 res = _NSGetExecutablePath(path.get(), &buf_len); 54 CHECK(res == 0, "failed to determine executable path"); 55 char* real_path = ::realpath(path.get(), nullptr); 56 CHECK(real_path != nullptr, "failed to determine executable path"); 57 return real_path; 58} 59 60void* OS::openSharedObject(const char* filename, int mode, 61 const char** error_msg) { 62 void* result = ::dlopen(filename, mode); 63 if (result == nullptr) { 64 *error_msg = ::dlerror(); 65 } 66 return result; 67} 68 69SignalHandler OS::setSignalHandler(int signum, SignalHandler handler) { 70 struct sigaction new_context, old_context; 71 new_context.sa_handler = handler; 72 sigemptyset(&new_context.sa_mask); 73 new_context.sa_flags = 0; 74 if (::sigaction(signum, &new_context, &old_context) == -1) { 75 return SIG_ERR; 76 } 77 return old_context.sa_handler; 78} 79 80SignalHandler OS::signalHandler(int signum) { 81 struct sigaction context; 82 if (::sigaction(signum, nullptr, &context) == -1) { 83 return SIG_ERR; 84 } 85 return context.sa_handler; 86} 87 88void* OS::sharedObjectSymbolAddress(void* handle, const char* symbol, 89 const char** error_msg) { 90 void* result = ::dlsym(handle, symbol); 91 if (result == nullptr && error_msg != nullptr) { 92 *error_msg = ::dlerror(); 93 } 94 return result; 95} 96 97word OS::sharedObjectSymbolName(void* addr, char* buf, word size) { 98 Dl_info info; 99 if (::dladdr(addr, &info) && info.dli_sname != nullptr) { 100 return std::snprintf(buf, size, "%s", info.dli_sname); 101 } 102 return -1; 103} 104 105} // namespace py