Menu

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

Switch to side-by-side view

--- a
+++ b/src/glib/gprocess.h
@@ -0,0 +1,170 @@
+//
+// 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 gprocess.h
+///
+
+#ifndef G_PROCESS_H
+#define G_PROCESS_H
+
+#include "gdef.h"
+#include "gexception.h"
+#include "gidentity.h"
+#include "gpath.h"
+#include "gstrings.h"
+#include "gsignalsafe.h"
+#include <iostream>
+#include <sys/types.h>
+#include <string>
+
+namespace G
+{
+	class Process ;
+	class NewProcess ;
+}
+
+/// \class G::Process
+/// A static interface for doing things with processes.
+/// \see G::Identity
+/// 
+class G::Process : private G::IdentityUser
+{
+public:
+	G_EXCEPTION( CannotChangeDirectory , "cannot cd()" ) ;
+	G_EXCEPTION( InvalidId , "invalid process-id string" ) ;
+
+	class IdImp ;
+	class Id /// Process-id class.
+	{
+		public: Id() ;
+		public: explicit Id( std::istream & ) ;
+		public: Id( SignalSafe , const char * pid_file_path ) ; // (ctor for signal-handler)
+		public: std::string str() const ;
+		public: bool operator==( const Id & ) const ;
+		private: pid_t m_pid ;
+		friend class NewProcess ;
+		friend class Process ;
+	} ;
+	class Umask /// Used to temporarily modify the process umask.
+	{
+		public: enum Mode { Readable , Tighter , Tightest , GroupOpen } ;
+		public: explicit Umask( Mode ) ;
+		public: ~Umask() ;
+		public: static void set( Mode ) ;
+		public: static void tighten() ; // no "other" access, user and group unchanged
+		private: Umask( const Umask & ) ; // not implemented
+		private: void operator=( const Umask & ) ; // not implemented
+		private: class UmaskImp ;
+		private: UmaskImp * m_imp ;
+	} ;
+	class NoThrow /// An overload discriminator for Process.
+		{} ;
+
+	static void closeFiles( bool keep_stderr = false ) ;
+		///< Closes all open file descriptors, but optionally not stderr.
+		///< Stdin, stdout, and possibly stderr are reopened to the 
+		///< null device.
+
+	static void closeFilesExcept( int fd_1 , int fd_2 = -1 ) ;
+		///< Closes all open file descriptors except the given ones.
+		///< If stdin, stdout, or stderr are closed then they are
+		///< reopened to the null device.
+
+	static void closeStderr() ;
+		///< Closes stderr and reopens it to the null device.
+
+	static void cd( const Path & dir ) ;
+		///< Changes directory.
+
+	static bool cd( const Path & dir , NoThrow ) ;
+		///< Changes directory. Returns false on error.
+
+	static int errno_( const SignalSafe & = G::SignalSafe() ) ;
+		///< Returns the process's current 'errno' value.
+
+	static int errno_( const SignalSafe & , int e_new ) ;
+		///< Sets the process's 'errno' value. Returns the old
+		///< value. Used in signal handlers.
+
+	static std::string strerror( int errno_ ) ;
+		///< Translates an 'errno' value into a meaningful diagnostic string.
+		///< The returned string is non-empty, even for a zero errno.
+
+	static void revokeExtraGroups() ;
+		///< Revokes secondary group memberships if really root
+		///< or if suid.
+
+	static Identity beOrdinary( Identity ordinary_id , bool change_group = true ) ;
+		///< Revokes special privileges (root or suid).
+		///< 
+		///< If the real-id is root then the effective id is changed to whatever 
+		///< is passed in. Otherwise the effective id is changed to the real id, 
+		///< and the parameter is ignored. 
+		///< 
+		///< Returns the old effective-id, which can be passed to beSpecial().
+		///< 
+		///< See also class G::Root.
+
+	static Identity beSpecial( Identity special_id , bool change_group = true ) ;
+		///< Re-acquires special privileges (either root or suid). The 
+		///< parameter must have come from a previous call to beOrdinary().
+		///< 
+		///< Returns the old effective-id (which is normally ignored).
+		///< 
+		///< See also class G::Root.
+
+	static Identity beOrdinary( SignalSafe , Identity ordinary_id , bool change_group = true ) ;
+		///< A signal-safe overload.
+
+	static Identity beSpecial( SignalSafe , Identity special_id , bool change_group = true ) ;
+		///< A signal-safe overload.
+
+	static void beOrdinaryForExec( Identity run_as_id ) ;
+		///< Sets the real and effective user and group ids to those
+		///< given. Errors are ignored. This should only be used in
+		///< a forked child process prior to doing an exec().
+
+	static std::string cwd( bool no_throw = false ) ;
+		///< Returns the current working directory. Throws on error
+		///< by default or returns the empty string.
+
+	static std::string exe() ;
+		///< Returns the absolute path of the current executable, 
+		///< independent of the argv array passed to main(). Returns 
+		///< the empty string if unknown.
+
+private:
+	Process() ;
+} ;
+
+namespace G
+{
+	inline
+	std::ostream & operator<<( std::ostream & stream , const G::Process::Id & id )
+	{
+		return stream << id.str() ;
+	}
+
+	inline
+	std::istream & operator>>( std::istream & stream , G::Process::Id & id )
+	{
+		id = G::Process::Id( stream ) ;
+		return stream ;
+	}
+}
+
+#endif