From 3faa9e329907bca551843119b27dd84d67eb0f40 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Sun, 8 Dec 2019 21:19:47 +0000 Subject: Move forking code into a function and remove DaemonSeed. --- src/inspircd.cpp | 82 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'src/inspircd.cpp') diff --git a/src/inspircd.cpp b/src/inspircd.cpp index b3198de57..022f06673 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -78,6 +78,8 @@ const char* ExitCodes[] = namespace { + void VoidSignalHandler(int); + // Deletes a pointer and then zeroes it. template void DeleteZero(T*& pr) @@ -137,6 +139,38 @@ namespace #endif } + // Attempts to fork into the background. + bool ForkIntoBackground() + { + // We use VoidSignalHandler whilst forking to avoid breaking daemon scripts + // if the parent process exits with SIGTERM (15) instead of EXIT_STATUS_NOERROR (0). + signal(SIGTERM, VoidSignalHandler); + + errno = 0; + int childpid = fork(); + if (childpid < 0) + { + ServerInstance->Logs->Log("STARTUP", LOG_DEFAULT, "fork() failed: %s", strerror(errno)); + return false; + } + else if (childpid > 0) + { + // Wait until the child process kills the parent so that the shell prompt + // doesnt display over the output. Sending a kill with a signal of 0 just + // checks that the child pid is still running. If it is not then an error + // happened and the parent should exit. + while (kill(childpid, 0) != -1) + sleep(1); + exit(EXIT_STATUS_NOERROR); + } + else + { + setsid(); + signal(SIGTERM, InspIRCd::SetSignal); + return true; + } + } + // Increase the size of a core dump file to improve debugging problems. void IncreaseCoreDumpSize() { @@ -222,40 +256,6 @@ void InspIRCd::SetSignals() signal(SIGTERM, InspIRCd::SetSignal); } -bool InspIRCd::DaemonSeed() -{ -#ifdef _WIN32 - std::cout << "InspIRCd Process ID: " << con_green << GetCurrentProcessId() << con_reset << std::endl; - return true; -#else - // Do not use exit() here: It will exit with status SIGTERM which would break e.g. daemon scripts - signal(SIGTERM, VoidSignalHandler); - - int childpid = fork(); - if (childpid < 0) - return false; - else if (childpid > 0) - { - /* We wait here for the child process to kill us, - * so that the shell prompt doesnt come back over - * the output. - * Sending a kill with a signal of 0 just checks - * if the child pid is still around. If theyre not, - * they threw an error and we should give up. - */ - while (kill(childpid, 0) != -1) - sleep(1); - exit(EXIT_STATUS_NOERROR); - } - setsid (); - std::cout << "InspIRCd Process ID: " << con_green << getpid() << con_reset << std::endl; - - signal(SIGTERM, InspIRCd::SetSignal); - IncreaseCoreDumpSize(); - return true; -#endif -} - void InspIRCd::WritePID(const std::string& filename, bool exitonfail) { #ifndef _WIN32 @@ -452,16 +452,16 @@ InspIRCd::InspIRCd(int argc, char** argv) this->SetSignals(); - if (!Config->cmdline.nofork) + if (!Config->cmdline.nofork && !ForkIntoBackground()) { - if (!this->DaemonSeed()) - { - std::cout << "ERROR: could not go into daemon mode. Shutting down." << std::endl; - Logs->Log("STARTUP", LOG_DEFAULT, "ERROR: could not go into daemon mode. Shutting down."); - Exit(EXIT_STATUS_FORK); - } + std::cout << "ERROR: could not go into daemon mode. Shutting down." << std::endl; + Logs->Log("STARTUP", LOG_DEFAULT, "ERROR: could not go into daemon mode. Shutting down."); + Exit(EXIT_STATUS_FORK); } + std::cout << "InspIRCd Process ID: " << con_green << getpid() << con_reset << std::endl; + + IncreaseCoreDumpSize(); SocketEngine::RecoverFromFork(); /* During startup we read the configuration now, not in -- cgit v1.2.3