Skip to content

Commit

Permalink
Automated g4 rollback of commit 7f520a8.
Browse files Browse the repository at this point in the history
*** 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: 156884488
  • Loading branch information
iirina committed May 23, 2017
1 parent 6206d1e commit 5608765
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 189 deletions.
3 changes: 0 additions & 3 deletions src/main/tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ cc_binary(
"//src:windows_msvc": ["process-wrapper-windows.cc"],
"//conditions:default": [
"process-wrapper.cc",
"process-wrapper.h",
"process-wrapper-legacy.cc",
"process-wrapper-legacy.h",
],
}),
linkopts = ["-lm"],
Expand Down
100 changes: 0 additions & 100 deletions src/main/tools/process-wrapper-legacy.cc

This file was deleted.

49 changes: 0 additions & 49 deletions src/main/tools/process-wrapper-legacy.h

This file was deleted.

94 changes: 89 additions & 5 deletions src/main/tools/process-wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
// 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>
Expand All @@ -40,9 +38,21 @@

#include "src/main/tools/logging.h"
#include "src/main/tools/process-tools.h"
#include "src/main/tools/process-wrapper-legacy.h"

struct Options opt;
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;

// Print out a usage error and exit with EXIT_FAILURE.
static void Usage(char *program_name) {
Expand Down Expand Up @@ -76,17 +86,91 @@ 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();

Redirect(opt.stdout_path, STDOUT_FILENO);
Redirect(opt.stderr_path, STDERR_FILENO);

LegacyProcessWrapper::RunCommand();
SpawnCommand(opt.args, opt.timeout_secs);

return 0;
}
32 changes: 0 additions & 32 deletions src/main/tools/process-wrapper.h

This file was deleted.

0 comments on commit 5608765

Please sign in to comment.