diff options
Diffstat (limited to '')
-rw-r--r-- | src/Globals.h | 1 | ||||
-rw-r--r-- | src/LoggerListeners.cpp | 20 | ||||
-rw-r--r-- | src/LoggerListeners.h | 2 | ||||
-rw-r--r-- | src/Root.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 46 |
5 files changed, 56 insertions, 15 deletions
diff --git a/src/Globals.h b/src/Globals.h index e7b7fdcac..4c9091e85 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -221,6 +221,7 @@ template class SizeChecker<UInt8, 1>; #include <semaphore.h> #include <errno.h> #include <fcntl.h> + #include <unistd.h> #endif #if defined(ANDROID_NDK) diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index 31b12af1e..132751e8e 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -238,8 +238,26 @@ public: -cLogger::cListener * MakeConsoleListener(void) +// Listener for when stdout is closed, i.e. When running as a daemon. +class cNullConsoleListener + : public cLogger::cListener +{ + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + } +}; + + + + + +cLogger::cListener * MakeConsoleListener(bool a_IsService) { + if (a_IsService) + { + return new cNullConsoleListener; + } + #ifdef _WIN32 // See whether we are writing to a console the default console attrib: bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); diff --git a/src/LoggerListeners.h b/src/LoggerListeners.h index c419aa75a..a7f9a35a5 100644 --- a/src/LoggerListeners.h +++ b/src/LoggerListeners.h @@ -25,7 +25,7 @@ private: -cLogger::cListener * MakeConsoleListener(); +cLogger::cListener * MakeConsoleListener(bool a_IsService); diff --git a/src/Root.cpp b/src/Root.cpp index 54e65b6da..8d344ee65 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -106,7 +106,7 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo) EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif - cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * consoleLogListener = MakeConsoleListener(m_RunAsService); cLogger::cListener * fileLogListener = new cFileListener(); cLogger::GetInstance().AttachListener(consoleLogListener); cLogger::GetInstance().AttachListener(fileLogListener); diff --git a/src/main.cpp b/src/main.cpp index 152339e12..2103f3356 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -250,7 +250,7 @@ void universalMain(std::unique_ptr<cSettingsRepositoryInterface> overridesRepo) -#if defined(_WIN32) +#if defined(_WIN32) // Windows service support. //////////////////////////////////////////////////////////////////////////////// // serviceWorkerThread: Keep the service alive @@ -358,7 +358,7 @@ void WINAPI serviceMain(DWORD argc, TCHAR *argv[]) serviceSetState(0, SERVICE_STOPPED, 0); } -#endif +#endif // Windows service support. @@ -378,7 +378,7 @@ std::unique_ptr<cMemorySettingsRepository> parseArguments(int argc, char **argv) TCLAP::SwitchArg crashDumpFull ("", "crash-dump-full", "Crashdumps created by the server will contain full server memory", cmd); TCLAP::SwitchArg crashDumpGlobals("", "crash-dump-globals", "Crashdumps created by the server will contain the global variables' values", cmd); TCLAP::SwitchArg noBufArg ("", "no-output-buffering", "Disable output buffering", cmd); - TCLAP::SwitchArg runAsServiceArg ("d", "run-as-service", "Run as a service on Windows", cmd); + TCLAP::SwitchArg runAsServiceArg ("d", "service", "Run as a service on Windows, or daemon on UNIX like systems", cmd); cmd.parse(argc, argv); // Copy the parsed args' values into a settings repository: @@ -484,11 +484,11 @@ int main(int argc, char **argv) #endif auto argsRepo = parseArguments(argc, argv); - - #if defined(_WIN32) - // Attempt to run as a service - if (cRoot::m_RunAsService) - { + + // Attempt to run as a service + if (cRoot::m_RunAsService) + { + #if defined(_WIN32) // Windows service. SERVICE_TABLE_ENTRY ServiceTable[] = { { SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)serviceMain }, @@ -500,11 +500,33 @@ int main(int argc, char **argv) LOGERROR("Attempted, but failed, service startup."); return GetLastError(); } - } - else - #endif + #else // UNIX daemon. + pid_t pid = fork(); + + // fork() returns a negative value on error. + if (pid < 0) + { + LOGERROR("Could not fork process."); + return EXIT_FAILURE; + } + + // Check if we are the parent or child process. Parent stops here. + if (pid > 0) + { + return EXIT_SUCCESS; + } + + // Child process now goes quiet, running in the background. + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + universalMain(std::move(argsRepo)); + #endif + } + else { - // Not running as a Windows service, do normal startup + // Not running as a service, do normal startup universalMain(std::move(argsRepo)); } |