Automated g4 rollback of commit 5608765ab737ebb8a98a04a6068143d53ae7065c.

*** Reason for rollback ***

Rollforward with fix for FreeBSD. I added the missing headers and verified that it now builds fine on FreeBSD 11, too.

*** Original change description ***

Automated g4 rollback of commit 7f520a8286c39c5145b6d816cd0be5a6b7b18250.

*** Reason for rollback ***

This broke Bazel CI on freebsd:

http://ci.bazel.io/view/Dashboard/job/Bazel/JAVA_VERSION=1.8,PLATFORM_NAME=freebsd-11/1516/console#

*** Original change description ***

Refactor process-wrapper code so the spawn/wait code is pluggable.

In an upcoming change I'll reintroduce the new platform-specific implementations that can kill and wait for all descendant processes spawned by the wrapped process.

This has no functional changes.

PiperOrigin-RevId: 158133159
diff --git a/src/main/tools/process-wrapper.cc b/src/main/tools/process-wrapper.cc
index c60de6e..09c1a88 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 @@
   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 @@
   Redirect(opt.stdout_path, STDOUT_FILENO);
   Redirect(opt.stderr_path, STDERR_FILENO);
 
-  SpawnCommand(opt.args, opt.timeout_secs);
+  LegacyProcessWrapper::RunCommand();
 
   return 0;
 }