summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetri Latvala <petri.latvala@intel.com>2018-04-26 14:04:00 +0300
committerPetri Latvala <petri.latvala@intel.com>2018-04-26 14:04:00 +0300
commit8cdb20dcc85f7c1bc7bf998ab85ddabdfa182879 (patch)
tree8ae0e7fa93cfbd6d17488179cb9dbbb8ed693c43
parent117c92bb4f99a01b75bed932e55d16445975cc52 (diff)
Handle SIGINT and pals
-rw-r--r--runner/executor.c94
1 files changed, 63 insertions, 31 deletions
diff --git a/runner/executor.c b/runner/executor.c
index d7df9be6..0b7d6608 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -245,6 +245,25 @@ static void dump_dmesg(int kmsgfd, int outfd)
}
}
+static bool kill_child(bool use_sigkill,
+ struct settings *settings,
+ pid_t child)
+{
+ int sig = use_sigkill ? SIGKILL : SIGTERM;
+
+ /*
+ * Send the signal to the child directly, and to the child's
+ * process group.
+ */
+ kill(-child, sig);
+ if (kill(child, sig) && errno == ESRCH) {
+ fprintf(stderr, "Child process does not exist. This shouldn't happen.\n");
+ return false;
+ }
+
+ return true;
+}
+
static char starting_subtest[] = "Starting subtest: ";
static size_t starting_len = sizeof(starting_subtest) - 1;
static char subtest_result_beg[] = "Subtest ";
@@ -272,6 +291,7 @@ static int monitor_output(pid_t child,
int timeout = settings->inactivity_timeout;
int killed = 0; /* 1 = sigterm sent, 2 = sigkill sent */
struct timespec time_beg, time_end;
+ bool aborting = false;
gettime(&time_beg);
@@ -306,20 +326,11 @@ static int monitor_output(pid_t child,
switch (killed) {
case 0:
if (settings->log_level >= LOG_LEVEL_NORMAL) {
- printf("Timeout. Killing the test with SIGTERM.\n");
+ printf("Timeout. Killing the current test with SIGTERM.\n");
}
- /*
- * Send the signal to the child
- * directly, and to the child's
- * process group.
- */
- kill(-child, SIGTERM);
- if (kill(child, SIGTERM) && errno == ESRCH) {
- fprintf(stderr, "Child process does not exist. This shouldn't happen.\n");
+ if (!kill_child(false, settings, child))
return 0;
- }
-
killed = 1;
/*
@@ -330,14 +341,11 @@ static int monitor_output(pid_t child,
break;
case 1:
if (settings->log_level >= LOG_LEVEL_NORMAL) {
- printf("Killing the test with SIGKILL.\n");
+ printf("Timeout. Killing the current test with SIGKILL.\n");
}
- kill(-child, SIGKILL);
- if (kill(child, SIGKILL) && errno == ESRCH) {
- fprintf(stderr, "Child process does not exist. This shouldn't happen.\n");
+ if (!kill_child(true, settings, child))
return 0;
- }
killed = 2;
break;
@@ -460,18 +468,33 @@ static int monitor_output(pid_t child,
if (s < 0) {
fprintf(stderr, "Error reading from signalfd: %s\n",
strerror(errno));
- } else if (child != waitpid(child, &status, WNOHANG)) {
- fprintf(stderr, "Failed to reap child\n");
- status = 9999;
- } else if (WIFEXITED(status)) {
- status = WEXITSTATUS(status);
- if (status >= 128) {
- status = 128 - status;
+ continue;
+ } else if (siginfo.ssi_signo == SIGCHLD) {
+ if (child != waitpid(child, &status, WNOHANG)) {
+ fprintf(stderr, "Failed to reap child\n");
+ status = 9999;
+ } else if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ if (status >= 128) {
+ status = 128 - status;
+ }
+ } else if (WIFSIGNALED(status)) {
+ status = -WTERMSIG(status);
+ } else {
+ status = 9999;
}
- } else if (WIFSIGNALED(status)) {
- status = -WTERMSIG(status);
} else {
- status = 9999;
+ /* We're dying, so we're taking them with us */
+ if (settings->log_level >= LOG_LEVEL_NORMAL)
+ printf("Abort requested, terminating children\n");
+
+ if (!kill_child(false, settings, child))
+ return 0;
+ aborting = true;
+ timeout = 2;
+ killed = 1;
+
+ continue;
}
gettime(&time_end);
@@ -480,11 +503,13 @@ static int monitor_output(pid_t child,
if (time < 0.0)
time = 0.0;
- dprintf(outputs[_F_JOURNAL], "%s:%d (%.3fs)\n",
- killed ? "timeout" : "exit",
- status, time);
- if (settings->sync) {
- fdatasync(outputs[_F_JOURNAL]);
+ if (!aborting) {
+ dprintf(outputs[_F_JOURNAL], "%s:%d (%.3fs)\n",
+ killed ? "timeout" : "exit",
+ status, time);
+ if (settings->sync) {
+ fdatasync(outputs[_F_JOURNAL]);
+ }
}
close(sigfd);
@@ -502,6 +527,9 @@ static int monitor_output(pid_t child,
close(kmsgfd);
close(sigfd);
+ if (aborting)
+ return 0;
+
return killed ? -1 : 1;
}
@@ -621,8 +649,12 @@ static int execute_entry(size_t idx,
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGTERM);
+ sigaddset(&mask, SIGQUIT);
sigprocmask(SIG_BLOCK, &mask, NULL);
sigfd = signalfd(-1, &mask, O_CLOEXEC);
+
if (sigfd < 0) {
/* TODO: Handle better */
fprintf(stderr, "Cannot monitor child process with signalfd\n");