21#ifndef G_NEW_PROCESS_H
22#define G_NEW_PROCESS_H
41 class NewProcessWaitable ;
64 G_EXCEPTION( Error ,
tx(
"cannot spawn new process") ) ;
65 G_EXCEPTION( CannotFork ,
tx(
"cannot fork") ) ;
66 G_EXCEPTION( WaitError ,
tx(
"failed waiting for child process") ) ;
67 G_EXCEPTION( ChildError ,
tx(
"child process terminated abnormally") ) ;
68 G_EXCEPTION( Insecure ,
tx(
"refusing to exec while the user-id is zero") ) ;
69 G_EXCEPTION( PipeError ,
tx(
"pipe error") ) ;
70 G_EXCEPTION( InvalidPath ,
tx(
"invalid executable path -- must be absolute") ) ;
71 G_EXCEPTION( InvalidParameter ,
tx(
"invalid parameter") ) ;
72 G_EXCEPTION( CreateProcessError ,
tx(
"CreateProcess error") ) ;
73 G_EXCEPTION( SystemError ,
tx(
"system error") ) ;
80 Fd(
bool null_ ,
bool pipe_ ,
int fd_ ) : m_null(null_) , m_pipe(pipe_) , m_fd(fd_) {}
81 static Fd pipe() {
return {
false,
true,-1} ; }
82 static Fd devnull() {
return {
true,
false,-1} ; }
83 static Fd fd(
int fd_) {
return fd_ < 0 ? devnull() :
Fd(
false,
false,fd_) ; }
84 bool operator==(
const Fd & other )
const {
return m_null == other.m_null && m_pipe == other.m_pipe && m_fd == other.m_fd ; }
85 bool operator!=(
const Fd & other )
const {
return !(*
this == other) ; }
91 using FormatFn = std::string (*)(std::string,int) ;
97 bool strict_exe {
true} ;
98 std::string exec_search_path ;
100 bool strict_id {
true} ;
101 int exec_error_exit {127} ;
102 std::string exec_error_format ;
103 FormatFn exec_error_format_fn {
nullptr} ;
110 Config & set_strict_exe(
bool =
true ) ;
111 Config & set_exec_search_path(
const std::string & ) ;
113 Config & set_strict_id(
bool =
true ) ;
114 Config & set_exec_error_exit(
int ) ;
115 Config & set_exec_error_format(
const std::string & ) ;
116 Config & set_exec_error_format_fn( FormatFn ) ;
159 int id() const noexcept ;
166 void kill(
bool yield = false ) noexcept ;
170 static
std::pair<
bool,pid_t>
fork() ;
183 static
std::
string execErrorFormat( const
std::
string & ,
int ) ;
186 std::unique_ptr<NewProcessImp> m_imp ;
213 void assign( pid_t pid ,
int fd ) ;
217 void assign( HANDLE hprocess , HANDLE hpipe ,
int ) ;
226 void waitp( std::promise<std::pair<int,std::string>> ) noexcept ;
245 int get( std::nothrow_t ,
int exit_code_on_error = 127 )
const noexcept ;
248 std::string output()
const ;
260 std::vector<char> m_buffer ;
261 std::size_t m_data_size {0U} ;
262 HANDLE m_hprocess {0} ;
269 int m_read_error {0} ;
270 bool m_test_mode {
false} ;
274inline G::NewProcess::Config & G::NewProcess::Config::set_stdin( Fd fd ) { stdin = fd ;
return *this ; }
275inline G::NewProcess::Config & G::NewProcess::Config::set_stdout( Fd fd ) { stdout = fd ;
return *this ; }
276inline G::NewProcess::Config & G::NewProcess::Config::set_stderr( Fd fd ) { stderr = fd ;
return *this ; }
277inline G::NewProcess::Config & G::NewProcess::Config::set_cd(
const Path & p ) { cd = p ;
return *this ; }
278inline G::NewProcess::Config & G::NewProcess::Config::set_strict_exe(
bool b ) { strict_exe = b ;
return *this ; }
279inline G::NewProcess::Config & G::NewProcess::Config::set_exec_search_path(
const std::string & s ) { exec_search_path = s ;
return *this ; }
280inline G::NewProcess::Config & G::NewProcess::Config::set_run_as( Identity i ) { run_as = i ;
return *this ; }
281inline G::NewProcess::Config & G::NewProcess::Config::set_strict_id(
bool b ) { strict_id = b ;
return *this ; }
282inline G::NewProcess::Config & G::NewProcess::Config::set_exec_error_exit(
int n ) { exec_error_exit = n ;
return *this ; }
283inline G::NewProcess::Config & G::NewProcess::Config::set_exec_error_format(
const std::string & s ) { exec_error_format = s ;
return *this ; }
284inline G::NewProcess::Config & G::NewProcess::Config::set_exec_error_format_fn( FormatFn f ) { exec_error_format_fn = f ;
return *this ; }
Holds a set of environment variables and also provides static methods to wrap getenv() and putenv().
static Environment minimal(bool sbin=false)
Returns a minimal, safe set of environment variables.
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.
Holds the parameters and future results of a waitpid() system call.
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...
NewProcessWaitable & waitable() noexcept
Returns a reference to the Waitable sub-object so that the caller can wait for the child process to e...
NewProcess(const Path &exe, const G::StringArray &args, const Config &)
Constructor.
A Path object represents a file system path.
std::vector< std::string > StringArray
A std::vector of std::strings.
constexpr const char * tx(const char *p)
A briefer alternative to G::gettext_noop().
Configuration structure for G::NewProcess.
Wraps up a file descriptor for passing to G::NewProcess.