14#include <mach-o/dyld.h>
22volatile sig_atomic_t s_signal_received = 0;
23void signal_handler(
int signal) { s_signal_received = signal; }
25char **s_argv =
nullptr;
26std::string *s_exe_path =
nullptr;
27std::string *s_reexec_path =
nullptr;
29std::string resolve_exe_path(
const char *argv0) {
32 ssize_t len = ::readlink(
"/proc/self/exe", buf,
sizeof(buf) - 1);
35 return std::string(buf);
41 if (_NSGetExecutablePath(buf, &size) == 0) {
43 if (::realpath(buf, real) !=
nullptr)
44 return std::string(real);
45 return std::string(buf);
51 if (::realpath(argv0, real) !=
nullptr)
52 return std::string(real);
53 return std::string(argv0);
62 static const std::string empty;
63 return s_exe_path !=
nullptr ? *s_exe_path : empty;
67 if (s_reexec_path !=
nullptr)
68 *s_reexec_path = path;
72 if (s_reexec_path ==
nullptr || s_reexec_path->empty())
74 return s_reexec_path->c_str();
83int main(
int argc,
char **argv) {
85 static std::string exe_path = resolve_exe_path(argc > 0 ? argv[0] :
nullptr);
86 s_exe_path = &exe_path;
87 static std::string reexec_path;
88 s_reexec_path = &reexec_path;
91 std::signal(SIGINT, signal_handler);
92 std::signal(SIGTERM, signal_handler);
96 while (s_signal_received == 0) {
void run_safe_shutdown_hooks()
const char * get_reexec_path()
Armed re-exec path, or nullptr.
const std::string & get_exe_path()
Absolute path to running exe (resolved at startup); empty on failure.
char ** get_argv()
argv captured by main(); stable for process lifetime.
void arm_reexec(const std::string &path)
Arm an execv on the next arch_restart(). Pass empty to disarm.
Application App
Global storage of Application pointer - only one Application can exist.