Menu

Diff of /src/glib/gpidfile.h [000000] .. [r1]  Maximize  Restore

Switch to side-by-side view

--- a
+++ b/src/glib/gpidfile.h
@@ -0,0 +1,120 @@
+//
+// Copyright (C) 2017 Graeme Walker
+// 
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+// ===
+///
+/// \file gpidfile.h
+///
+
+#ifndef G_PIDFILE_H
+#define G_PIDFILE_H
+
+#include "gdef.h"
+#include "gexception.h"
+#include "gsignalsafe.h"
+#include "gpath.h"
+#include <sys/types.h>
+#include <string>
+
+namespace G
+{
+	class PidFile ;
+	class Daemon ;
+}
+
+/// \class G::PidFile
+/// A class for creating pid files. Works with G::Root and G::Daemon so that 
+/// the pid file can get created very late in a daemon startup sequence. 
+/// Installs a signal handler so that the pid file gets deleted on process 
+/// termination.
+/// 
+/// Usage:
+/// \code
+/// G::PidFile pid_file ;
+/// if( !path.empty() ) 
+/// { pid_file.init(path) ; pid_file.check() ; }
+/// G::Root::init("nobody") ;
+/// if( daemon ) G::Daemon::detach( pid_file ) ;
+/// { G::Root claim_root ; pid_file.commit() ; }
+/// \endcode
+/// 
+/// \see G::Daemon
+/// 
+class G::PidFile
+{
+public:
+	G_EXCEPTION( Error , "invalid pid file" ) ;
+
+	static void cleanup( SignalSafe , const char * path ) ;
+		///< Deletes the specified pid file if it contains this 
+		///< process's id. Claims root privilege to read
+		///< and delete the pid file (see G::Root).
+		///< 
+		///< This is not normally needed by client code since it 
+		///< is installed as a signal handler (see G::Cleanup) 
+		///< and called from the destructor.
+		///< 
+		///< Signal-safe, reentrant implementation.
+
+	explicit PidFile( const Path & pid_file_path ) ;
+		///< Constructor. The path should normally be an 
+		///< absolute path. Use commit() to actually create 
+		///< the file.
+
+	PidFile() ;
+		///< Default constructor. Constructs a do-nothing 
+		///< object. Initialise with init().
+
+	void init( const Path & pid_file_path ) ;
+		///< Used after default construction to make the object 
+		///< active. Use commit() to actually create the file.
+
+	~PidFile() ;
+		///< Destructor. Calls cleanup() to delete the file.
+
+	void commit() ;
+		///< Creates the file and installs signal handlers to
+		///< cleanup() the file on abnormal process termination. 
+		///< 
+		///< Does nothing if no pid file path has been defined.
+		///< Throws on error.
+		///< 
+		///< The caller is responsible for setting the file 
+		///< ownership and permissions by switching effecive
+		///< user-id and umask.
+
+	void check() ;
+		///< Throws an exception if the path is not absolute.
+		///< The use of G::Daemon normally requires an absolute
+		///< path because it may change the current working
+		///< directory.
+
+	Path path() const ;
+		///< Returns the path as supplied to the constructor
+		///< or init().
+
+private:
+	Path m_path ;
+
+private:
+	PidFile( const PidFile & ) ; // not implemented
+	void operator=( const PidFile & ) ; // not implemented
+	static bool mine( SignalSafe , const char * path ) ; // reentrant
+	static void create( const Path & pid_file ) ;
+	bool valid() const ;
+} ;
+
+#endif
+