summaryrefslogtreecommitdiff
path: root/src/inspircd.cpp
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2019-12-08 21:19:47 +0000
committerPeter Powell <petpow@saberuk.com>2019-12-08 21:19:47 +0000
commit3faa9e329907bca551843119b27dd84d67eb0f40 (patch)
tree4297a62b0e5f0c2bad8058fd19e13eafdd20ad50 /src/inspircd.cpp
parent191ad98fb554d4c000d7048deb03f7fad91170ad (diff)
Move forking code into a function and remove DaemonSeed.
Diffstat (limited to 'src/inspircd.cpp')
-rw-r--r--src/inspircd.cpp82
1 files changed, 41 insertions, 41 deletions
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<typename T>
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