this repo has no description
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