diff options
author | Petri Latvala <petri.latvala@intel.com> | 2018-04-26 14:04:00 +0300 |
---|---|---|
committer | Petri Latvala <petri.latvala@intel.com> | 2018-04-26 14:04:00 +0300 |
commit | 8cdb20dcc85f7c1bc7bf998ab85ddabdfa182879 (patch) | |
tree | 8ae0e7fa93cfbd6d17488179cb9dbbb8ed693c43 | |
parent | 117c92bb4f99a01b75bed932e55d16445975cc52 (diff) |
Handle SIGINT and pals
-rw-r--r-- | runner/executor.c | 94 |
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"); |