21#ifndef G_NEW_PROCESS_H
22#define G_NEW_PROCESS_H
41 class NewProcessWaitable ;
42 struct NewProcessConfig ;
66 G_EXCEPTION( Error ,
"cannot spawn new process" ) ;
67 G_EXCEPTION( CannotFork ,
"cannot fork" ) ;
68 G_EXCEPTION( WaitError ,
"failed waiting for child process" ) ;
69 G_EXCEPTION( ChildError ,
"child process terminated abnormally" ) ;
70 G_EXCEPTION( Insecure ,
"refusing to exec while the user-id is zero" ) ;
71 G_EXCEPTION( PipeError ,
"pipe error" ) ;
72 G_EXCEPTION( InvalidPath ,
"invalid executable path -- must be absolute" ) ;
73 G_EXCEPTION( InvalidParameter ,
"invalid parameter" ) ;
74 G_EXCEPTION( CreateProcessError ,
"CreateProcess error" ) ;
81 Fd(
bool null_ ,
bool pipe_ ,
int fd_ ) : m_null(null_) , m_pipe(pipe_) , m_fd(fd_) {}
82 static Fd pipe() {
return {
false,
true,-1} ; }
83 static Fd devnull() {
return {
true,
false,-1} ; }
84 static Fd fd(
int fd_) {
return fd_ < 0 ? devnull() :
Fd(
false,
false,fd_) ; }
85 bool operator==(
const Fd & other )
const {
return m_null == other.m_null && m_pipe == other.m_pipe && m_fd == other.m_fd ; }
86 bool operator!=(
const Fd & other )
const {
return !(*
this == other) ; }
90 Fd fd_stdin = Fd::devnull() ,
Fd fd_stdout = Fd::pipe() ,
Fd fd_stderr = Fd::devnull() ,
93 int exec_error_exit = 127 ,
94 const std::string & exec_error_format = std::string() ,
95 std::string (*exec_error_format_fn)(std::string,
int) =
nullptr ) ;
138 int id() const noexcept ;
145 void kill(
bool yield = false ) noexcept ;
149 static std::pair<
bool,pid_t>
fork() ;
158 void operator=( const
NewProcess & ) = delete ;
162 static std::
string execErrorFormat( const std::
string & ,
int ) ;
193 void assign( pid_t pid ,
int fd ) ;
197 void assign( HANDLE hprocess , HANDLE hpipe ,
int ) ;
206 void waitp( std::promise<std::pair<int,std::string>> ) noexcept ;
225 int get( std::nothrow_t ,
int exit_code_on_error = 127 ) const ;
228 std::
string output() const ;
240 std::vector<
char> m_buffer ;
241 std::
size_t m_data_size{0U} ;
242 HANDLE m_hprocess{0} ;
249 int m_read_error{0} ;
250 bool m_test_mode{
false} ;
306 NewProcessConfig & set_exec_error_format_fn( std::string (*)(std::string,
int) ) ;
316 bool m_strict_path{
true} ;
318 bool m_strict_id{
true} ;
319 int m_exec_error_exit{127} ;
320 std::string m_exec_error_format ;
321 std::string (*m_exec_error_format_fn)( std::string , int ){
nullptr} ;
348 m_args.push_back( argv1 ) ;
355 m_args.push_back( argv1 ) ;
356 m_args.push_back( argv2 ) ;
382 config.m_strict_path ,
385 config.m_exec_error_exit ,
386 config.m_exec_error_format ,
387 config.m_exec_error_format_fn )
Holds a set of environment variables and also provides static methods to wrap getenv() and putenv().
static Environment minimal()
Returns a minimal, safe set of environment variables.
A structure representing an external program, holding a path and a set of arguments.
A combination of user-id and group-id, with a very low-level interface to the get/set/e/uid/gid funct...
static Identity invalid() noexcept
Returns an invalid identity.
A pimple-pattern implementation class used by G::NewProcess.
Holds the parameters and future results of a waitpid() system call, as performed by the wait() method...
NewProcessWaitable(HANDLE hprocess, HANDLE hpipe, int)
Constructor taking process and pipe handles.
void assign(HANDLE hprocess, HANDLE hpipe, int)
Reinitialises as if constructed with the given proces handle and pipe handle.
A class for creating new processes.
int id() const noexcept
Returns the process id.
void kill(bool yield=false) noexcept
Tries to kill the spawned process and optionally yield to a thread that might be waiting on it.
static std::pair< bool, pid_t > fork()
A utility function that forks the calling process and returns twice; once in the parent and once in t...
NewProcess(const Path &exe, const StringArray &args, const Environment &env=Environment::minimal(), Fd fd_stdin=Fd::devnull(), Fd fd_stdout=Fd::pipe(), Fd fd_stderr=Fd::devnull(), const G::Path &cd=G::Path(), bool strict_path=true, Identity run_as_id=Identity::invalid(), bool strict_id=true, int exec_error_exit=127, const std::string &exec_error_format=std::string(), std::string(*exec_error_format_fn)(std::string, int)=nullptr)
Constructor.
NewProcessWaitable & waitable() noexcept
Returns a reference to the Waitable sub-object so that the caller can wait for the child process to e...
A Path object represents a file system path.
std::vector< std::string > StringArray
A std::vector of std::strings.
Provides syntactic sugar for the G::NewProcess constructor.
NewProcessConfig & set_exec_error_format_fn(std::string(*)(std::string, int))
Sets the 'exec_error_format_fn' value.
NewProcessConfig & set_args(const StringArray &args)
Sets the command-line arguments.
NewProcessConfig & set_fd_stdin(NewProcess::Fd)
Sets the standard-input file descriptor.
NewProcessConfig & set_cd(const G::Path &)
Sets the working directory.
NewProcessConfig & set_strict_path(bool=true)
Sets the 'strict_path' value.
NewProcessConfig & set_strict_id(bool=true)
Sets the 'strict_id' value.
NewProcessConfig(const Path &exe)
Constructor.
NewProcessConfig & set_fd_stdout(NewProcess::Fd)
Sets the standard-output file descriptor.
NewProcessConfig & set_exec_error_format(const std::string &)
Sets the 'exec_error_format' value.
NewProcessConfig & set_run_as_id(const G::Identity &)
Sets the run-as id.
NewProcessConfig & set_exec_error_exit(int)
Sets the 'exec_error_exit' value.
NewProcessConfig & set_fd_stderr(NewProcess::Fd)
Sets the standard-error file descriptor.
NewProcessConfig & set_env(const Environment &env)
Sets the environment.
Wraps up a file descriptor for passing to G::NewProcess.