37 void noCloseOnExec(
int fd )
39 ::fcntl( fd , F_SETFD , 0 ) ;
55 void G::Process::cd(
const Path & dir )
57 if( ! cd(dir,NoThrow()) )
58 throw CannotChangeDirectory( dir.
str() ) ;
61 bool G::Process::cd(
const Path & dir , NoThrow )
63 return 0 == ::chdir( dir.
str().c_str() ) ;
66 void G::Process::closeStderr()
68 ::close( STDERR_FILENO ) ;
70 noCloseOnExec( STDERR_FILENO ) ;
73 void G::Process::closeFiles(
bool keep_stderr )
75 closeFilesExcept( keep_stderr ? STDERR_FILENO : -1 ) ;
78 void G::Process::closeFilesExcept(
int keep_1 ,
int keep_2 )
81 std::cout << std::flush ;
82 std::cerr << std::flush ;
86 long rc = ::sysconf( _SC_OPEN_MAX ) ;
88 n =
static_cast<int>( rc ) ;
91 for(
int fd = 0 ; fd < n ; fd++ )
93 if( fd != keep_1 && fd != keep_2 )
99 if( keep_1 != STDIN_FILENO && keep_2 != STDIN_FILENO )
101 ::open( dev_null.
str().c_str() , O_RDONLY ) ;
103 if( keep_1 != STDOUT_FILENO && keep_2 != STDOUT_FILENO )
105 ::open( dev_null.
str().c_str() , O_WRONLY ) ;
107 if( keep_1 != STDERR_FILENO && keep_2 != STDERR_FILENO )
109 ::open( dev_null.
str().c_str() , O_WRONLY ) ;
113 noCloseOnExec( STDIN_FILENO ) ;
114 noCloseOnExec( STDOUT_FILENO ) ;
115 noCloseOnExec( STDERR_FILENO ) ;
130 std::string G::Process::strerror(
int errno_ )
132 char * p = std::strerror( errno_ ) ;
133 std::string s( p ? p :
"" ) ;
134 if( s.empty() ) s =
"unknown error" ;
138 void G::Process::revokeExtraGroups()
143 int rc = ::setgroups( 0U , &dummy ) ; G_IGNORE_VARIABLE(rc) ;
147 G::Identity G::Process::beSpecial( Identity special_identity ,
bool change_group )
151 setEffectiveUserTo( special_identity ) ;
153 setEffectiveGroupTo( special_identity ) ;
154 return old_identity ;
157 G::Identity G::Process::beSpecial( SignalSafe safe , Identity special_identity ,
bool change_group )
161 setEffectiveUserTo( safe , special_identity ) ;
163 setEffectiveGroupTo( safe , special_identity ) ;
164 return old_identity ;
167 G::Identity G::Process::beOrdinary( Identity ordinary_id ,
bool change_group )
174 setEffectiveGroupTo( ordinary_id ) ;
175 setEffectiveUserTo( ordinary_id ) ;
183 return special_identity ;
186 G::Identity G::Process::beOrdinary( SignalSafe safe , Identity ordinary_id ,
bool change_group )
193 setEffectiveGroupTo( safe , ordinary_id ) ;
194 setEffectiveUserTo( safe , ordinary_id ) ;
202 return special_identity ;
205 void G::Process::beOrdinaryForExec( Identity run_as_id )
210 setRealGroupTo( run_as_id ,
false ) ;
211 setEffectiveGroupTo( run_as_id ,
false ) ;
212 setRealUserTo( run_as_id ,
false ) ;
213 setEffectiveUserTo( run_as_id ,
false ) ;
217 std::string G::Process::cwd(
bool no_throw )
219 std::vector<char> buffer( PATH_MAX + 10 ) ;
222 char * p = getcwd( &buffer[0] , buffer.size() ) ;
223 int error = errno_() ;
224 if( p ==
nullptr && error == ERANGE )
225 buffer.resize( buffer.size() + PATH_MAX ) ;
226 else if( p ==
nullptr && !no_throw )
227 throw std::runtime_error(
"getcwd() failed" ) ;
231 buffer.push_back(
'\0' ) ;
232 return std::string( &buffer[0] ) ;
237 bool readlink_(
const char * path , std::string & value )
239 std::vector<char> buffer( PATH_MAX + 1 ) ;
241 ssize_t rc = readlink( path , &buffer[0] , buffer.size() ) ;
242 if( rc > 0 && static_cast<size_t>(rc) <= buffer.size() )
243 value = std::string(&buffer[0],static_cast<size_t>(rc)) ;
250 std::string G::Process::exe()
253 std::vector<char> buffer( std::max(100,PROC_PIDPATHINFO_MAXSIZE) ) ;
255 int rc = proc_pidpath( getpid() , &buffer[0] , buffer.size() ) ;
258 size_t n =
static_cast<size_t>(rc) ;
259 if( n > buffer.size() ) n = buffer.size() ;
260 return std::string( &buffer[0] , n ) ;
264 return std::string() ;
268 std::string G::Process::exe()
272 readlink_(
"/proc/self/exe" , result ) ||
273 readlink_(
"/proc/curproc/file" , result ) ||
274 readlink_(
"/proc/curproc/exe" , result ) ;
286 G::Process::Id::Id( SignalSafe ,
const char * path ) :
290 int fd = ::open( path ? path :
"" , O_RDONLY ) ;
293 const size_t buffer_size = 11U ;
294 char buffer[buffer_size] ;
296 ssize_t rc = ::read( fd , buffer , buffer_size-1U ) ;
298 for(
const char * p = buffer ; rc > 0 && *p >=
'0' && *p <=
'9' ; p++ , rc-- )
301 m_pid += ( *p -
'0' ) ;
306 G::Process::Id::Id( std::istream & stream )
310 throw Process::InvalidId() ;
313 std::string G::Process::Id::str()
const
315 std::ostringstream ss ;
320 bool G::Process::Id::operator==(
const Id & other )
const
322 return m_pid == other.m_pid ;
329 mode_t umask_value( G::Process::Umask::Mode mode )
332 if( mode == G::Process::Umask::Tightest ) m = 0177 ;
333 if( mode == G::Process::Umask::Tighter ) m = 0117 ;
334 if( mode == G::Process::Umask::Readable ) m = 0133 ;
335 if( mode == G::Process::Umask::GroupOpen ) m = 0113 ;
349 G::Process::Umask::Umask( Mode mode ) :
352 m_imp->m_old_mode = ::umask( umask_value(mode) ) ;
355 G::Process::Umask::~Umask()
357 mode_t rc = ::umask( m_imp->m_old_mode ) ; G_IGNORE_VARIABLE(rc) ;
361 void G::Process::Umask::set( Mode mode )
363 mode_t rc = ::umask( umask_value(mode) ) ; G_IGNORE_VARIABLE(rc) ;
366 void G::Process::Umask::tighten()
368 ::umask( ::umask(2) | mode_t(7) ) ;
std::string str() const
Returns the path string.
bool isRoot() const
Returns true if the userid is zero.
A pimple-pattern implementation class used by G::Process::Umask.
An empty structure that is used to indicate a signal-safe, reentrant implementation.
static Identity root()
Returns the superuser identity.
static Identity real()
Returns the calling process's real identity.
static Identity invalid()
Returns an invalid identity.
A combination of user-id and group-id, with a very low-level interface to the get/set/e/uid/gid funct...
static Identity effective()
Returns the current effective identity.
static std::string lower(const std::string &s)
Returns a copy of 's' in which all Latin-1 uppercase characters have been replaced by lowercase chara...
static bool isPrintableAscii(const std::string &s)
Returns true if every character is a 7-bit, non-control character (ie.
A private implementation class used by G::Process that wraps a process id and hides the pid_t type...
A Path object represents a file system path.
static Path nullDevice()
Returns the path of the "/dev/null" special file, or equivalent.