13 #ifndef __PROCESS_POSIX_SUBPROCESS_HPP__
14 #define __PROCESS_POSIX_SUBPROCESS_HPP__
17 #include <sys/prctl.h>
19 #include <sys/types.h>
23 #include <glog/logging.h>
49 static void close(std::initializer_list<int_fd> fds);
63 }
else if (pid == 0) {
90 foreach (
int fd, fds) {
107 const std::string& path,
115 const std::vector<Subprocess::ChildHook>& child_hooks)
151 ::close(stdinfds.
read);
157 ::close(stdoutfds.
write);
164 ::close(stderrfds.
write);
172 while ((length = ::
read(pipes[0], &dummy,
sizeof(dummy))) == -1 &&
175 if (length !=
sizeof(dummy)) {
176 ABORT(
"Failed to synchronize with parent");
189 ABORT(
"Failed to execute Subprocess::ChildHook: " + callback.
error());
196 errno,
"Failed to os::execvpe on path '%s': %d", path.c_str(), errno);
201 const std::string& path,
202 std::vector<std::string> argv,
204 const Option<lambda::function<
205 pid_t(
const lambda::function<
int()>&)>>& _clone,
206 const std::vector<Subprocess::ParentHook>& parent_hooks,
207 const std::vector<Subprocess::ChildHook>& child_hooks,
215 char** _argv =
new char*[argv.size() + 1];
216 for (
size_t i = 0; i < argv.size(); i++) {
217 _argv[i] = (
char*) argv[i].c_str();
219 _argv[argv.size()] =
nullptr;
232 const std::string& key,
234 std::string entry = key +
"=" + value;
235 envp[
index] =
new char[entry.size() + 1];
236 strncpy(envp[index], entry.c_str(), entry.size() + 1);
240 envp[
index] =
nullptr;
245 lambda::function<pid_t(const lambda::function<int()>&)>
clone =
250 std::array<int, 2> pipes;
251 const bool blocking = !parent_hooks.empty();
284 delete[] envp[
index];
293 internal::close(stdinfds, stdoutfds, stderrfds);
305 internal::close({stdinfds.
read, stdoutfds.
write, stderrfds.
write});
318 <<
"Failed to execute Subprocess::ParentHook in parent for child '"
319 << pid <<
"': " << parentSetup.
error();
327 "Failed to execute Subprocess::ParentHook in parent for child '" +
336 while ((length = ::
write(pipes[1], &dummy,
sizeof(dummy))) == -1 &&
341 if (length !=
sizeof(dummy)) {
345 return Error(
"Failed to synchronize child process");
355 #endif // __PROCESS_POSIX_SUBPROCESS_HPP__
Try< Nothing > dup2(int oldFd, int newFd)
Definition: os.hpp:428
SSIZE_T ssize_t
Definition: windows.hpp:192
Definition: nothing.hpp:16
Definition: errorbase.hpp:35
Definition: option.hpp:28
Try< pid_t > clone(pid_t target, int nstypes, const lambda::function< int()> &f, int flags)
Performs an os::clone after entering a set of namespaces for the specified target process...
#define ABORT(...)
Definition: abort.hpp:40
Subprocess::IO::OutputFileDescriptors OutputFileDescriptors
Definition: subprocess.hpp:342
const mode_t SIGKILL
Definition: windows.hpp:346
A ChildHook can be passed to a subprocess call.
Definition: subprocess.hpp:189
Definition: hashset.hpp:53
For output file descriptors a child writes to the write file descriptor and a parent may read from th...
Definition: subprocess.hpp:88
pid_t defaultClone(const lambda::function< int()> &func)
Definition: subprocess_posix.hpp:58
Definition: errorbase.hpp:49
#define STDERR_FILENO
Definition: windows.hpp:161
Try< Nothing > cloexec(const InputFileDescriptors &stdinfds, const OutputFileDescriptors &stdoutfds, const OutputFileDescriptors &stderrfds)
Definition: subprocess_posix.hpp:76
bool isSome() const
Definition: option.hpp:115
Subprocess::IO::InputFileDescriptors InputFileDescriptors
Definition: subprocess.hpp:341
Environment * environment
DWORD pid_t
Definition: windows.hpp:187
Result< int > index(const std::string &link)
#define CHECK_SOME(expression)
Definition: check.hpp:44
#define STDOUT_FILENO
Definition: windows.hpp:160
int_fd write
Definition: subprocess.hpp:91
Try< Nothing > close(int fd)
Definition: close.hpp:24
Try< Nothing > cloexec(int fd)
Definition: fcntl.hpp:27
Try< std::array< int, 2 > > pipe()
Definition: pipe.hpp:26
const T & get() const &
Definition: option.hpp:118
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
Try< pid_t > cloneChild(const std::string &path, std::vector< std::string > argv, const Option< std::map< std::string, std::string >> &environment, const Option< lambda::function< pid_t(const lambda::function< int()> &)>> &_clone, const std::vector< Subprocess::ParentHook > &parent_hooks, const std::vector< Subprocess::ChildHook > &child_hooks, const InputFileDescriptors stdinfds, const OutputFileDescriptors stdoutfds, const OutputFileDescriptors stderrfds)
Definition: subprocess_posix.hpp:200
#define STDIN_FILENO
Definition: windows.hpp:159
static Try error(const E &e)
Definition: try.hpp:42
#define UNREACHABLE()
Definition: unreachable.hpp:22
const lambda::function< Try< Nothing >pid_t)> parent_setup
The callback that must be specified for execution after the child has been cloned, but before it starts executing the new process.
Definition: subprocess.hpp:162
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
bool isError() const
Definition: try.hpp:71
Result< Credentials > read(const Path &path)
Definition: credentials.hpp:35
std::string error(const std::string &msg, uint32_t code)
int execvpe(const std::string &command, const std::vector< std::string > &argv, const std::map< std::string, std::string > &envp)
Definition: shell.hpp:394
Protocol< WriteRequest, WriteResponse > write
Option< int_fd > read
Definition: subprocess.hpp:90
Try< Nothing > kill(const std::string &hierarchy, const std::string &cgroup, int signal)
Try< Nothing > bind(int_fd s, const Address &address)
Definition: network.hpp:46
A hook can be passed to a subprocess call.
Definition: subprocess.hpp:151
std::string stringify(int flags)
T getOrElse(const T &_t) const
Definition: option.hpp:127
#define SAFE_EXIT(status, fmt,...)
Definition: exit.hpp:42
const T & get() const
Definition: try.hpp:73
int childMain(const std::string &path, char **argv, char **envp, const InputFileDescriptors &stdinfds, const OutputFileDescriptors &stdoutfds, const OutputFileDescriptors &stderrfds, bool blocking, int pipes[2], const std::vector< Subprocess::ChildHook > &child_hooks)
Definition: subprocess_posix.hpp:106
char ** environment()
Definition: environment.hpp:66