in tools/common/process.cc [145:191]
int RunSubProcess(const std::vector<std::string> &args,
std::ostream *stderr_stream, bool stdout_to_stderr) {
std::vector<const char *> exec_argv = ConvertToCArgs(args);
// Set up a pipe to redirect stderr from the child process so that we can
// capture it and return it in the response message.
std::unique_ptr<PosixSpawnIORedirector> redirector =
PosixSpawnIORedirector::Create(stdout_to_stderr);
if (!redirector) {
(*stderr_stream) << "Error creating stderr pipe for child process.\n";
return 254;
}
pid_t pid;
int status =
posix_spawn(&pid, args[0].c_str(), redirector->PosixSpawnFileActions(),
nullptr, const_cast<char **>(exec_argv.data()), environ);
redirector->ConsumeAllSubprocessOutput(stderr_stream);
if (status == 0) {
int wait_status;
do {
wait_status = waitpid(pid, &status, 0);
} while ((wait_status == -1) && (errno == EINTR));
if (wait_status < 0) {
std::cerr << "Error waiting on child process '" << args[0] << "'. "
<< strerror(errno) << "\n";
return wait_status;
}
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
if (WIFSIGNALED(status)) {
return WTERMSIG(status);
}
// Unhandled case, if we hit this we should handle it above.
return 42;
} else {
std::cerr << "Error forking process '" << args[0] << "'. "
<< strerror(status) << "\n";
return status;
}
}