Browse Source

[trac3687] First round of pid file handling

Create a utility class to handle pid files.

This allows somebody to check, write and delete pid files
for use in mediating processes.

The Check routine will attempt to read a pid file and
then check if the pid is in use.  The write routine will
delete the current pid file and write a new pid to the file.
The delete routine simply deletes the old pid file.
Shawn Routhier 10 years ago
parent
commit
6c3bff5bf0

+ 1 - 0
src/lib/util/Makefile.am

@@ -28,6 +28,7 @@ libkea_util_la_SOURCES += encode/binary_from_base32hex.h
 libkea_util_la_SOURCES += encode/binary_from_base16.h
 libkea_util_la_SOURCES += random/qid_gen.h random/qid_gen.cc
 libkea_util_la_SOURCES += random/random_number_generator.h
+libkea_util_la_SOURCES += pid.h pid.cc
 
 libkea_util_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
 CLEANFILES = *.gcno *.gcda

+ 91 - 0
src/lib/util/pid.cc

@@ -0,0 +1,91 @@
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <util/pid.h>
+#include <cstdio>
+#include <signal.h>
+
+namespace isc {
+namespace util {
+
+pidFile::pidFile(const std::string& filename)
+    : filename_(filename) {
+}
+
+bool
+pidFile::check() {
+    boost::shared_ptr<std::ifstream> fs;
+    int pid;
+    bool good;
+
+    fs.reset(new std::ifstream(filename_.c_str()));
+
+    // If we weren't able to open the file treat
+    // it as if the process wasn't running
+    if (fs->is_open() == false) {
+	fs.reset();
+	return (false);
+    }
+
+    // Try to get the pid, get the status and get rid of the file
+    *fs >> pid;
+    good = fs->good();
+    fs->close();
+    fs.reset();
+
+    // Treat being unable to read a pid the same as if we
+    // got a pid and the process is still running.
+    if ((good == false) || (kill(pid, 0) == 0)) {
+	return (true);
+    }
+
+    // No process
+    return (false);
+}
+
+void
+pidFile::write() {
+    write(getpid());
+}
+
+void
+pidFile::write(int pid) {
+    boost::shared_ptr<std::ofstream> fs;
+
+    fs.reset(new std::ofstream(filename_.c_str()));
+    if (fs->is_open() == false) {
+	fs.reset();
+	isc_throw(pidFileError, "Unable to open PID file '"
+		  << filename_ << "' for write");
+    }
+
+    // File is open, write the pid.
+    *fs << pid << std::endl;
+
+    // That's it
+    fs->close();
+    fs.reset();
+}
+
+void
+pidFile::deleteFile() {
+    if (remove(filename_.c_str()) != 0) {
+        isc_throw(pidFileError, "Unable to delete PID file '"
+		  << filename_ << "'");
+    }
+}
+
+} // namespace isc::util
+} // namespace isc
+

+ 87 - 0
src/lib/util/pid.h

@@ -0,0 +1,87 @@
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef PID_H
+#define PID_H
+
+#include <exceptions/exceptions.h>
+#include <boost/lexical_cast.hpp>
+#include <boost/shared_ptr.hpp>
+#include <fstream>
+#include <ostream>
+#include <string>
+
+namespace isc {
+namespace util {
+
+/// @brief Exception thrown when an error occurs during PID file processing.
+class pidFileError : public Exception {
+public:
+    pidFileError(const char* file, size_t line, const char* what) :
+    isc::Exception(file, line, what) { };
+};
+
+/// @brief Class to help with processing PID files
+///
+/// This is a utility class to manipulate PID files.  It provides
+/// functiosn for writing and deleting a file containing a PID as
+/// well as for extracting a PID from a file and checking if the
+/// process is still running.
+
+class pidFile {
+public:
+    /// @brief Constructor
+    ///
+    /// @param filename PID filename.
+    pidFile(const std::string& filename);
+
+    /// @brief Destructor
+    ~pidFile();
+
+    /// @brief Read the PID in from the file and check it.
+    ///
+    /// Read the PID in from the file then use it to see if
+    /// a process with that PID exists.  If the file doesn't
+    /// exist treat it as the process not being there.
+    /// If the file exists but can't be read or it doesn't
+    /// the proper format treat it as the process existing.
+    ///
+    /// @return true if the PID is in use, false otherwise
+    bool check();
+
+    /// @brief Write the PID to the file.
+    void write(int);
+
+    /// @brief Get PID of the proces and write it to the file.
+    void write();
+
+    /// @brief Delete the file.
+    void deleteFile();
+
+    /// @brief Returns the path to the PID file.
+    std::string getFilename() const {
+        return (filename_);
+    }
+
+private:
+    /// @brief PID filename
+    std::string filename_;
+};
+
+} // namespace isc::util
+} // namespace isc
+
+#endif // PID_H
+
+

+ 1 - 0
src/lib/util/tests/Makefile.am

@@ -45,6 +45,7 @@ run_unittests_SOURCES += strutil_unittest.cc
 run_unittests_SOURCES += time_utilities_unittest.cc
 run_unittests_SOURCES += range_utilities_unittest.cc
 run_unittests_SOURCES += signal_set_unittest.cc
+run_unittests_SOURCES += pid_unittest.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)

+ 21 - 0
src/lib/util/tests/pid_unittest.cc

@@ -0,0 +1,21 @@
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <util/pid.h>
+
+namespace {
+using namespace isc::util;
+
+} // end of anonymous namespace
+