#ifdef _WIN32
WSACleanup();
-#else /* _WIN32 */
- //lt_dlexit();
#endif /* _WIN32 */
+
+ ClosePidFile();
}
/**
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;
+}
+
static bool IsMainThread(void);
+ void UpdatePidFile(const string& filename);
+ void ClosePidFile(void);
+
protected:
void RunEventLoop(void);
string GetExePath(void) const;
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. */
#include <signal.h>
#include <libgen.h>
#include <syslog.h>
+#include <sys/file.h>
void Sleep(unsigned long milliseconds);
using namespace icinga;
+const string IcingaApplication::PidFilename = "icinga.pid";
+
/**
* The entry point for the Icinga application.
*
time(&m_StartTime);
+ UpdatePidFile(PidFilename);
+
if (args.size() < 2) {
stringstream msgbuf;
msgbuf << "Syntax: " << args[0] << " [-S] [-L logfile] [-d] [--] <config-file>";
if (daemonize) {
Logger::Write(LogInformation, "icinga", "Daemonizing.");
+ ClosePidFile();
Utility::Daemonize();
+ UpdatePidFile(PidFilename);
Logger::UnregisterLogger(consoleLogger);
}
time_t GetStartTime(void) const;
+ static const string PidFilename;
+
private:
string m_CertificateFile;
string m_CAFile;