diff options
Diffstat (limited to 'src/main/tools/process-wrapper.cc')
-rw-r--r-- | src/main/tools/process-wrapper.cc | 94 |
1 files changed, 5 insertions, 89 deletions
diff --git a/src/main/tools/process-wrapper.cc b/src/main/tools/process-wrapper.cc index c60de6e4e3..09c1a88038 100644 --- a/src/main/tools/process-wrapper.cc +++ b/src/main/tools/process-wrapper.cc @@ -22,6 +22,8 @@ // die with raise(SIGTERM) even if the child process handles SIGTERM with // exit(0). +#include "src/main/tools/process-wrapper.h" + #include <err.h> #include <errno.h> #include <signal.h> @@ -38,21 +40,9 @@ #include "src/main/tools/logging.h" #include "src/main/tools/process-tools.h" +#include "src/main/tools/process-wrapper-legacy.h" -static double global_kill_delay; -static pid_t global_child_pid; -static volatile sig_atomic_t global_signal; - -// Options parsing result. -struct Options { - double timeout_secs; - double kill_delay_secs; - std::string stdout_path; - std::string stderr_path; - std::vector<char *> args; -}; - -static struct Options opt; +struct Options opt; // Print out a usage error and exit with EXIT_FAILURE. static void Usage(char *program_name) { @@ -86,83 +76,9 @@ static void ParseCommandLine(std::vector<char *> args) { opt.args.push_back(nullptr); } -// Called when timeout or signal occurs. -void OnSignal(int sig) { - global_signal = sig; - - // Nothing to do if we received a signal before spawning the child. - if (global_child_pid == -1) { - return; - } - - if (sig == SIGALRM) { - // SIGALRM represents a timeout, so we should give the process a bit of - // time to die gracefully if it needs it. - KillEverything(global_child_pid, true, global_kill_delay); - } else { - // Signals should kill the process quickly, as it's typically blocking - // the return of the prompt after a user hits "Ctrl-C". - KillEverything(global_child_pid, false, global_kill_delay); - } -} - -// Run the command specified by the argv array and kill it after timeout -// seconds. -static void SpawnCommand(const std::vector<char *> &args, double timeout_secs) { - global_child_pid = fork(); - if (global_child_pid < 0) { - DIE("fork"); - } else if (global_child_pid == 0) { - // In child. - if (setsid() < 0) { - DIE("setsid"); - } - ClearSignalMask(); - - // Force umask to include read and execute for everyone, to make - // output permissions predictable. - umask(022); - - // Does not return unless something went wrong. - if (execvp(args[0], args.data()) < 0) { - DIE("execvp(%s, ...)", args[0]); - } - } else { - // In parent. - - // Set up a signal handler which kills all subprocesses when the given - // signal is triggered. - InstallSignalHandler(SIGALRM, OnSignal); - InstallSignalHandler(SIGTERM, OnSignal); - InstallSignalHandler(SIGINT, OnSignal); - if (timeout_secs > 0) { - SetTimeout(timeout_secs); - } - - int status = WaitChild(global_child_pid); - - // The child is done for, but may have grandchildren that we still have to - // kill. - kill(-global_child_pid, SIGKILL); - - if (global_signal > 0) { - // Don't trust the exit code if we got a timeout or signal. - InstallDefaultSignalHandler(global_signal); - raise(global_signal); - } else if (WIFEXITED(status)) { - exit(WEXITSTATUS(status)); - } else { - int sig = WTERMSIG(status); - InstallDefaultSignalHandler(sig); - raise(sig); - } - } -} - int main(int argc, char *argv[]) { std::vector<char *> args(argv, argv + argc); ParseCommandLine(args); - global_kill_delay = opt.kill_delay_secs; SwitchToEuid(); SwitchToEgid(); @@ -170,7 +86,7 @@ int main(int argc, char *argv[]) { Redirect(opt.stdout_path, STDOUT_FILENO); Redirect(opt.stderr_path, STDERR_FILENO); - SpawnCommand(opt.args, opt.timeout_secs); + LegacyProcessWrapper::RunCommand(); return 0; } |