1 // 2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net> 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 // === 17 /// 18 /// \file gprocess.h 19 /// 20 21 #ifndef G_PROCESS_H 22 #define G_PROCESS_H 23 24 #include "gdef.h" 25 #include "gexception.h" 26 #include "gidentity.h" 27 #include "gpath.h" 28 #include "gstrings.h" 29 #include <iostream> 30 #include <sys/types.h> 31 #include <string> 32 33 /// \namespace G 34 namespace G 35 { 36 class Process ; 37 class NewProcess ; 38 } 39 40 /// \class G::Process 41 /// A static interface for doing things with processes. 42 /// \see G::Identity 43 /// 44 class G::Process : private G::IdentityUser 45 { 46 public: 47 G_EXCEPTION( CannotChangeDirectory , "cannot cd()" ) ; 48 G_EXCEPTION( InvalidId , "invalid process-id string" ) ; 49 50 class IdImp ; 51 /// Process-id class. 52 class Id 53 { 54 public: Id() ; 55 public: explicit Id( std::istream & ) ; 56 public: Id( SignalSafe , const char * pid_file_path ) ; // (ctor for signal-handler) 57 public: std::string str() const ; 58 public: bool operator==( const Id & ) const ; 59 private: pid_t m_pid ; 60 friend class NewProcess ; 61 friend class Process ; 62 } ; 63 /// Used to temporarily modify the process umask. 64 class Umask 65 { 66 public: enum Mode { Readable , Tighter , Tightest , GroupOpen } ; 67 public: explicit Umask( Mode ) ; 68 public: ~Umask() ; 69 public: static void set( Mode ) ; 70 private: Umask( const Umask & ) ; // not implemented 71 private: void operator=( const Umask & ) ; // not implemented 72 private: class UmaskImp ; 73 private: UmaskImp * m_imp ; 74 } ; 75 /// An overload discriminator for Process. 76 class NoThrow 77 {} ; 78 79 static void closeFiles( bool keep_stderr = false ) ; 80 ///< Closes all open file descriptors. 81 82 static void closeFiles( int fd ) ; 83 ///< Closes all open file descriptors except the given one. 84 85 static void closeStderr() ; 86 ///< Closes stderr. 87 88 static void cd( const Path & dir ) ; 89 ///< Changes directory. 90 91 static bool cd( const Path & dir , NoThrow ) ; 92 ///< Changes directory. Returns false on error. 93 94 static int errno_() ; 95 ///< Returns the process's current 'errno' value. 96 97 static int errno_( int ) ; 98 ///< Sets the process's 'errno' value. Returns the old 99 ///< value. Used in signal handlers. 100 101 static std::string strerror( int errno_ ) ; 102 ///< Translates an 'errno' value into a meaningful diagnostic string. 103 104 static void revokeExtraGroups() ; 105 ///< Revokes secondary group memberships if really root 106 ///< or if suid. 107 108 static Identity beOrdinary( Identity nobody , bool change_group = true ) ; 109 ///< Revokes special privileges (root or suid). 110 ///< 111 ///< If really root (as opposed to suid root) then the effective 112 ///< id is changed to that passed in. 113 ///< 114 ///< If suid (including suid-root), then the effective id is 115 ///< changed to the real id, and the parameter is ignored. 116 ///< 117 ///< Returns the old identity, which can be passed to beSpecial(). 118 ///< 119 ///< See also class G::Root. 120 121 static Identity beSpecial( Identity special , bool change_group = true ) ; 122 ///< Re-acquires special privileges (either root or suid). The 123 ///< parameter must have come from a previous call to beOrdinary(). 124 ///< 125 ///< Returns the old identity (which is normally ignored). 126 ///< 127 ///< See also class G::Root. 128 129 static Identity beOrdinary( SignalSafe , Identity nobody , bool change_group = true ) ; 130 ///< A signal-safe overload. 131 132 static Identity beSpecial( SignalSafe , Identity special , bool change_group = true ) ; 133 ///< A signal-safe overload. 134 135 static void beNobody( Identity ) ; 136 ///< If currently running with a real identity of root then the 137 ///< real identity is set to the nobody identity and the 138 ///< effective identity is set to root. 139 ///< 140 ///< Must only be used before exec()ing a new executable image, 141 ///< in which case the old effective ids are lost anywas by 142 ///< the exec(). 143 144 private: 145 Process() ; 146 } ; 147 148 /// \namespace G 149 namespace G 150 { 151 inline 152 std::ostream & operator<<( std::ostream & stream , const G::Process::Id & id ) 153 { 154 return stream << id.str() ; 155 } 156 157 inline 158 std::istream & operator>>( std::istream & stream , G::Process::Id & id ) 159 { 160 id = G::Process::Id( stream ) ; 161 return stream ; 162 } 163 } 164 165 #endif 166 167