Implemented support for writing a PID file.

This commit is contained in:
Gunnar Beutner 2012-07-12 17:03:34 +02:00
parent ff3259eee6
commit 9104bdd8da
5 changed files with 53 additions and 2 deletions

View 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;
}

View 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. */

View File

@ -34,6 +34,7 @@
#include <signal.h>
#include <libgen.h>
#include <syslog.h>
#include <sys/file.h>
void Sleep(unsigned long milliseconds);

View 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);
}

View File

@ -45,6 +45,8 @@ public:
time_t GetStartTime(void) const;
static const string PidFilename;
private:
string m_CertificateFile;
string m_CAFile;