From: Gunnar Beutner Date: Thu, 12 Jul 2012 15:03:34 +0000 (+0200) Subject: Implemented support for writing a PID file. X-Git-Tag: v0.0.1~258 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9104bdd8daf39b4c7e3e6c1578cd3ae35bbd623f;p=icinga2 Implemented support for writing a PID file. --- diff --git a/base/application.cpp b/base/application.cpp index 12dec6a61..15ade90b8 100644 --- a/base/application.cpp +++ b/base/application.cpp @@ -69,9 +69,9 @@ Application::~Application(void) #ifdef _WIN32 WSACleanup(); -#else /* _WIN32 */ - //lt_dlexit(); #endif /* _WIN32 */ + + ClosePidFile(); } /** @@ -406,3 +406,41 @@ int Application::Run(int argc, char **argv) return result; } + +void Application::UpdatePidFile(const string& filename) +{ + ClosePidFile(); + + /* There's just no sane way of getting a file descriptor for a + * C++ ofstream which is why we're using FILEs here. */ + m_PidFile = fopen(filename.c_str(), "w"); + + if (m_PidFile == NULL) + throw runtime_error("Could not open PID file '" + filename + "'"); + + if (flock(fileno(m_PidFile), LOCK_EX | LOCK_NB) < 0) { + ClosePidFile(); + + throw runtime_error("Another instance of the application is " + "already running. Remove the '" + filename + "' file if " + "you're certain that this is not the case."); + } + +#ifndef _WIN32 + pid_t pid = getpid(); +#else /* _WIN32 */ + DWORD pid = GetCurrentProcessId(); +#endif /* _WIN32 */ + + fprintf(m_PidFile, "%d", pid); + fflush(m_PidFile); +} + +void Application::ClosePidFile(void) +{ + if (m_PidFile != NULL) + fclose(m_PidFile); + + m_PidFile = NULL; +} + diff --git a/base/application.h b/base/application.h index 9d8aa4930..4f370606b 100644 --- a/base/application.h +++ b/base/application.h @@ -56,6 +56,9 @@ public: static bool IsMainThread(void); + void UpdatePidFile(const string& filename); + void ClosePidFile(void); + protected: void RunEventLoop(void); string GetExePath(void) const; @@ -68,6 +71,7 @@ private: map< string, shared_ptr > m_Components; /**< Components that were loaded by the application. */ vector m_Arguments; /**< Command-line arguments */ + FILE *m_PidFile; /**< The PID file */ static bool m_Debugging; /**< Whether debugging is enabled. */ static boost::thread::id m_MainThreadID; /**< ID of the main thread. */ diff --git a/base/unix.h b/base/unix.h index cebe038df..0e790f2b2 100644 --- a/base/unix.h +++ b/base/unix.h @@ -34,6 +34,7 @@ #include #include #include +#include void Sleep(unsigned long milliseconds); diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index f240651aa..aa50ea7ca 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -28,6 +28,8 @@ using namespace icinga; +const string IcingaApplication::PidFilename = "icinga.pid"; + /** * The entry point for the Icinga application. * @@ -47,6 +49,8 @@ int IcingaApplication::Main(const vector& args) time(&m_StartTime); + UpdatePidFile(PidFilename); + if (args.size() < 2) { stringstream msgbuf; msgbuf << "Syntax: " << args[0] << " [-S] [-L logfile] [-d] [--] "; @@ -170,7 +174,9 @@ int IcingaApplication::Main(const vector& args) if (daemonize) { Logger::Write(LogInformation, "icinga", "Daemonizing."); + ClosePidFile(); Utility::Daemonize(); + UpdatePidFile(PidFilename); Logger::UnregisterLogger(consoleLogger); } diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index e9189b967..f2e920fe3 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -45,6 +45,8 @@ public: time_t GetStartTime(void) const; + static const string PidFilename; + private: string m_CertificateFile; string m_CAFile;