E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gnewprocess.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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 gnewprocess.h
19 ///
20
21 #ifndef G_NEW_PROCESS_H
22 #define G_NEW_PROCESS_H
23 #define G_NEW_PROCESS_WITH_WAIT_FUTURE
24
25 #include "gdef.h"
26 #include "gexception.h"
27 #include "gidentity.h"
28 #include "gprocess.h"
29 #include "gpath.h"
30 #include "gstrings.h"
31 #include <string>
32
33 namespace G
34 {
35 class NewProcess ;
36 class NewProcessImp ;
37 class NewProcessWaitFuture ;
38 class Pipe ;
39 }
40
41 /// \class G::NewProcess
42 /// A class for creating new processes.
43 ///
44 /// Eg:
45 /// \code
46 /// {
47 /// NewProcess task( "foo" , args ) ;
48 /// int rc = task.wait().run().get() ;
49 /// std::string s = task.wait().output() ;
50 /// ...
51 /// }
52 /// \endcode
53 ///
54 /// \see G::Daemon, G::NewProcessWaitFuture
55 ///
56 class G::NewProcess
57 {
58 public:
59 G_EXCEPTION( CannotFork , "cannot fork()" ) ;
60 G_EXCEPTION( WaitError , "cannot wait()" ) ;
61 G_EXCEPTION( ChildError , "child process terminated abnormally or stopped" ) ;
62 G_EXCEPTION( Insecure , "refusing to exec() while the user-id is zero" ) ;
63 G_EXCEPTION( PipeError , "pipe error" ) ;
64 G_EXCEPTION( InvalidPath , "invalid executable path -- must be absolute" ) ;
65 G_EXCEPTION( CreateProcessError , "CreateProcess() error" ) ; // windows
66
67 NewProcess( const Path & exe , const StringArray & args ,
68 int capture_stdxxx = 1 , bool clean_environment = true , bool strict_path = true ,
69 Identity run_as_id = Identity::invalid() , bool strict_id = true ,
70 int exec_error_exit = 127 ,
71 const std::string & exec_error_format = std::string() ,
72 std::string (*exec_error_format_fn)(std::string,int) = 0 ) ;
73 ///< Constructor. Spawns the given program to run independently in a
74 ///< child process.
75 ///<
76 ///< The parent process can capture the child process's stdout or
77 ///< stderr (ie. stdxxx) by redirecting it to an internal pipe going
78 ///< from child to parent.
79 ///<
80 ///< The child process is optionally given a clean, minimalist
81 ///< environment.
82 ///<
83 ///< If 'strict_path' then the program must be given as an absolute path.
84 ///< Otherwise it can be relative and the PATH environment is used
85 ///< to find it. (The PATH search is done after the environment has
86 ///< been either cleaned or not.)
87 ///<
88 ///< If a valid identity is supplied then the child process runs as
89 ///< that identity. If 'strict_id' is also true then the id is not
90 ///< allowed to be root. See Process::beOrdinaryForExec().
91 ///<
92 ///< By default the child process runs with stdin and stderr attached to
93 ///< the null device and stdout attached to the internal pipe. The
94 ///< internal pipe is also used for error messages in case the exec()
95 ///< fails.
96 ///<
97 ///< If the exec() fails then the 'exec_error_exit' argument is used as
98 ///< the child process exit code, and if either of the other 'exec_whatever'
99 ///< arguments is supplied then an exec error message is written into
100 ///< the child process's end of the internal pipe.
101 ///<
102 ///< The exec error message is assembled by the given callback function,
103 ///< with the 'exec_error_format' argument passed as its second parameter.
104 ///< The first parameter is the exec() errno. The default callback function
105 ///< does text substitution for "__errno__" and "__strerror__"
106 ///< substrings that appear within the error format string.
107
108 ~NewProcess() ;
109 ///< Destructor. Kills the spawned process if the WaitFuture has
110 ///< not been resolved.
111
112 int id() const ;
113 ///< Returns the process id.
114
115 NewProcessWaitFuture & wait() ;
116 ///< Returns a reference to the WaitFuture sub-object so that the caller
117 ///< can wait for the child process to exit.
118
119 void kill() ;
120 ///< Tries to kill the spawned process.
121
122 static std::pair<bool,pid_t> fork() ;
123 ///< A utility function that forks the calling process and returns
124 ///< twice; once in the parent and once in the child. Returns
125 ///< an "is-in-child/child-pid" pair.
126 /// \see G::Daemon
127
128 private:
129 NewProcess( const NewProcess & ) ;
130 void operator=( const NewProcess & ) ;
131 static std::string execErrorFormat( const std::string & , int ) ;
132
133 private:
134 NewProcessImp * m_imp ;
135 } ;
136
137 /// \class G::NewProcessWaitFuture
138 /// A class that holds the parameters and the results of a waitpid() system
139 /// call. The run() method can be run from a worker thread and the results
140 /// collected by the main thread using get() once the worker thread has
141 /// signalled that it has finished. The signalling mechanism is outside the
142 /// scope of this class.
143 ///
144 class G::NewProcessWaitFuture
145 {
146 public:
147 NewProcessWaitFuture() ;
148 ///< Default constructor for an object where run() does nothing
149 ///< and get() returns zero.
150
151 explicit NewProcessWaitFuture( pid_t pid , int fd = -1 ) ;
152 ///< Constructor taking a posix process-id and optional
153 ///< readable file descriptor.
154
155 NewProcessWaitFuture( HANDLE hprocess , HANDLE hpipe , int ) ;
156 ///< Constructor taking process and pipe handles.
157 ///< Used in the windows implementation.
158
159 NewProcessWaitFuture & run() ;
160 ///< Waits for the process identified by the constructor
161 ///< parameter to exit. Returns *this. This method can be
162 ///< called from a separate worker thread.
163
164 int get() ;
165 ///< Returns the result of the run() as either the process
166 ///< exit code or as a thrown exception. Typically called
167 ///< by the main thread after the run() worker thread has
168 ///< signalled its completion.
169
170 std::string output() ;
171 ///< Returns the first bit of child-process output.
172 ///< Used after get().
173
174 private:
175 std::vector<char> m_buffer ;
176 HANDLE m_hprocess ;
177 HANDLE m_hpipe ;
178 pid_t m_pid ;
179 int m_fd ;
180 int m_rc ;
181 int m_status ;
182 int m_error ;
183 int m_read_error ;
184 } ;
185
186 #endif
G::NewProcess::kill
void kill()
Tries to kill the spawned process.
Definition: gnewprocess_unix.cpp:125
gstrings.h
G::Identity::invalid
static Identity invalid()
Returns an invalid identity.
Definition: gidentity_unix.cpp:107
gidentity.h
G::NewProcessWaitFuture
A class that holds the parameters and the results of a waitpid() system call.
Definition: gnewprocess.h:144
G::Identity
A combination of user-id and group-id, with a very low-level interface to the get/set/e/uid/gid funct...
Definition: gidentity.h:42
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
G::NewProcess::id
int id() const
Returns the process id.
Definition: gnewprocess_unix.cpp:120
G::NewProcess::fork
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...
Definition: gnewprocess_unix.cpp:115
G::NewProcess::~NewProcess
~NewProcess()
Destructor.
Definition: gnewprocess_unix.cpp:105
G::NewProcessWaitFuture::output
std::string output()
Returns the first bit of child-process output.
Definition: gnewprocess_unix.cpp:438
G::NewProcessWaitFuture::run
NewProcessWaitFuture & run()
Waits for the process identified by the constructor parameter to exit.
Definition: gnewprocess_unix.cpp:365
G
Low-level classes.
Definition: garg.h:29
G::NewProcess::wait
NewProcessWaitFuture & wait()
Returns a reference to the WaitFuture sub-object so that the caller can wait for the child process to...
Definition: gnewprocess_unix.cpp:110
G::NewProcessWaitFuture::NewProcessWaitFuture
NewProcessWaitFuture()
Default constructor for an object where run() does nothing and get() returns zero.
Definition: gnewprocess_unix.cpp:342
gprocess.h
G::NewProcessImp
A pimple-pattern implementation class used by G::NewProcess.
Definition: gnewprocess_unix.cpp:65
gexception.h
gpath.h
G::NewProcess::NewProcess
NewProcess(const Path &exe, const StringArray &args, int capture_stdxxx=1, bool clean_environment=true, 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)=0)
Constructor.
Definition: gnewprocess_unix.cpp:95
G::Path
A Path object represents a file system path.
Definition: gpath.h:72
G::NewProcess
A class for creating new processes.
Definition: gnewprocess.h:56