MCPcopy Create free account
hub / github.com/Icinga/icinga2 / Daemonize

Function Daemonize

lib/cli/daemoncommand.cpp:69–132  ·  view source on GitHub ↗

* Daemonize(). On error, this function logs by itself and exits (i.e. does not return). * * Implementation note: We're only supposed to call exit() in one of the forked processes. * The other process calls _exit(). This prevents issues with exit handlers like atexit(). */

Source from the content-addressed store, hash-verified

67 * The other process calls _exit(). This prevents issues with exit handlers like atexit().
68 */
69static void Daemonize() noexcept
70{
71#ifndef _WIN32
72 try {
73 Application::UninitializeBase();
74 } catch (const std::exception& ex) {
75 Log(LogCritical, "cli")
76 << "Failed to stop thread pool before daemonizing, unexpected error: " << DiagnosticInformation(ex);
77 exit(EXIT_FAILURE);
78 }
79
80 pid_t pid = fork();
81 if (pid == -1) {
82 Log(LogCritical, "cli")
83 << "fork() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
84 exit(EXIT_FAILURE);
85 }
86
87 if (pid) {
88 // systemd requires that the pidfile of the daemon is written before the forking
89 // process terminates. So wait till either the forked daemon has written a pidfile or died.
90
91 int status;
92 int ret;
93 pid_t readpid;
94 do {
95 Utility::Sleep(0.1);
96
97 readpid = Application::ReadPidFile(Configuration::PidPath);
98 ret = waitpid(pid, &status, WNOHANG);
99 } while (readpid != pid && ret == 0);
100
101 if (ret == pid) {
102 Log(LogCritical, "cli", "The daemon could not be started. See log output for details.");
103 _exit(EXIT_FAILURE);
104 } else if (ret == -1) {
105 Log(LogCritical, "cli")
106 << "waitpid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
107 _exit(EXIT_FAILURE);
108 }
109
110 _exit(EXIT_SUCCESS);
111 }
112
113 Log(LogDebug, "Daemonize()")
114 << "Child process with PID " << Utility::GetPid() << " continues; re-initializing base.";
115
116 // Detach from controlling terminal
117 pid_t sid = setsid();
118 if (sid == -1) {
119 Log(LogCritical, "cli")
120 << "setsid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
121 exit(EXIT_FAILURE);
122 }
123
124 try {
125 Application::InitializeBase();
126 } catch (const std::exception& ex) {

Callers 1

RunMethod · 0.85

Calls 1

LogClass · 0.85

Tested by

no test coverage detected