diff --git a/etc/init.d/icinga2.in b/etc/init.d/icinga2.in index c97f8b244..e5b07cd2b 100644 --- a/etc/init.d/icinga2.in +++ b/etc/init.d/icinga2.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # # chkconfig: 35 90 12 # description: Icinga 2 @@ -48,8 +48,7 @@ start() { fi printf "Starting Icinga 2: " - $DAEMON -c $ICINGA2_CONFIG_FILE /dev/null 2>$ICINGA2_ERROR_LOG & - disown + $DAEMON -c $ICINGA2_CONFIG_FILE -d -e $ICINGA2_ERROR_LOG echo "Done" echo diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index 236b16e82..94e7fed28 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -129,6 +129,56 @@ static void SigHupHandler(int signum) } #endif /* _WIN32 */ +static bool Daemonize(const String& stderrFile) +{ +#ifndef _WIN32 + pid_t pid = fork(); + if (pid == -1) { + return false; + } + + if (pid) + exit(0); + + int fdnull = open("/dev/null", O_RDWR); + if (fdnull > 0) { + if (fdnull != 0) + dup2(fdnull, 0); + + if (fdnull != 1) + dup2(fdnull, 1); + + if (fdnull > 2) + close(fdnull); + } + + const char *errPath = "/dev/null"; + + if (!stderrFile.IsEmpty()) + errPath = stderrFile.CStr(); + + int fderr = open(errPath, O_WRONLY | O_APPEND); + + if (fderr < 0 && errno == ENOENT) + fderr = open(errPath, O_CREAT | O_WRONLY | O_APPEND, 0600); + + if (fderr > 0) { + if (fderr != 2) + dup2(fderr, 2); + + if (fderr > 2) + close(fderr); + } + + pid_t sid = setsid(); + if (sid == -1) { + return false; + } +#endif + + return true; +} + /** * Entry point for the Icinga application. * @@ -181,6 +231,8 @@ int main(int argc, char **argv) ("config,c", po::value >(), "parse a configuration file") ("validate,v", "exit after validating the configuration") ("debug,x", "enable debugging") + ("daemonize,d", "detach from the controlling terminal") + ("errorlog,e", po::value(), "log fatal errors to the specified log file (only works in combination with --daemonize)") ; try { @@ -267,6 +319,15 @@ int main(int argc, char **argv) return EXIT_FAILURE; } + if (g_AppParams.count("daemonize")) { + String errorLog; + + if (g_AppParams.count("errorlog")) + errorLog = g_AppParams["errorlog"].as(); + + Daemonize(errorLog); + } + bool validateOnly = g_AppParams.count("validate"); if (!LoadConfigFiles(validateOnly))