From: Shawn Routhier Date: Thu, 22 Jan 2015 07:37:11 +0000 (-0800) Subject: [trac3687] First round of pid file handling X-Git-Tag: trac3712_base~29^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c3bff5bf095ee79bfa24bb203710f53af3fa09a;p=thirdparty%2Fkea.git [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. --- diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index 7ad7749589..f794c84c99 100644 --- a/src/lib/util/Makefile.am +++ b/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 diff --git a/src/lib/util/pid.cc b/src/lib/util/pid.cc new file mode 100644 index 0000000000..d142a8b54b --- /dev/null +++ b/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 +#include +#include + +namespace isc { +namespace util { + +pidFile::pidFile(const std::string& filename) + : filename_(filename) { +} + +bool +pidFile::check() { + boost::shared_ptr 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 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 + diff --git a/src/lib/util/pid.h b/src/lib/util/pid.h new file mode 100644 index 0000000000..9978a15c7d --- /dev/null +++ b/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 +#include +#include +#include +#include +#include + +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 + + diff --git a/src/lib/util/tests/Makefile.am b/src/lib/util/tests/Makefile.am index 7bad6f9613..d166d7e2bf 100644 --- a/src/lib/util/tests/Makefile.am +++ b/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) diff --git a/src/lib/util/tests/pid_unittest.cc b/src/lib/util/tests/pid_unittest.cc new file mode 100644 index 0000000000..821af91ba6 --- /dev/null +++ b/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 + +namespace { +using namespace isc::util; + +} // end of anonymous namespace +