]> granicus.if.org Git - icinga2/commitdiff
Implemented support for writing a PID file.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 12 Jul 2012 15:03:34 +0000 (17:03 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Thu, 12 Jul 2012 15:03:34 +0000 (17:03 +0200)
base/application.cpp
base/application.h
base/unix.h
icinga/icingaapplication.cpp
icinga/icingaapplication.h

index 12dec6a618ec5e25b0ef45c28f58f1e2d4a920a4..15ade90b8a3fe3c4f988d5c9f564409cd1144eea 100644 (file)
@@ -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;
+}
+
index 9d8aa4930b7e174428a65b08de6711f52f127b52..4f370606b7853adf3df6b6981470efe49fbdfc3d 100644 (file)
@@ -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<Component> > m_Components; /**< Components that
                                        were loaded by the application. */
        vector<string> 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. */
 
index cebe038dfdc8a285b7645a58fde5c22e25cadb26..0e790f2b2b6060228dff5ba122dfb61f9120f2bc 100644 (file)
@@ -34,6 +34,7 @@
 #include <signal.h>
 #include <libgen.h>
 #include <syslog.h>
+#include <sys/file.h>
 
 void Sleep(unsigned long milliseconds);
 
index f240651aafe7cb324afd04aa4484924ce253dfff..aa50ea7ca67736b95612542fe727a2c9d284a139 100644 (file)
@@ -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<string>& args)
 
        time(&m_StartTime);
 
+       UpdatePidFile(PidFilename);
+
        if (args.size() < 2) {
                stringstream msgbuf;
                msgbuf << "Syntax: " << args[0] << " [-S] [-L logfile] [-d] [--] <config-file>";
@@ -170,7 +174,9 @@ int IcingaApplication::Main(const vector<string>& args)
 
        if (daemonize) {
                Logger::Write(LogInformation, "icinga", "Daemonizing.");
+               ClosePidFile();
                Utility::Daemonize();
+               UpdatePidFile(PidFilename);
                Logger::UnregisterLogger(consoleLogger);
        }
 
index e9189b9676ce905ef75564fe3a1bb290f9eb4107..f2e920fe3c8ce9729276112b4abd64aaf96095c1 100644 (file)
@@ -45,6 +45,8 @@ public:
 
        time_t GetStartTime(void) const;
 
+       static const string PidFilename;
+
 private:
        string m_CertificateFile;
        string m_CAFile;