From d0e8ee42ec100536eddebca79463a7baeaf73c05 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 27 Sep 2014 16:13:26 -0400 Subject: [PATCH] Patch bash's builtin kill... ... to handle the kill by name functionality. Fixes #9687 and reintroduces the ability to kill jobs. --- diff --git a/builtins/kill.def b/builtins/kill.def index 2e68f03..7fa3191 100644 --- a/builtins/kill.def +++ b/builtins/kill.def @@ -54,9 +54,12 @@ $END # include #endif +#include + #include "../bashansi.h" #include "../bashintl.h" +#include #include #include "../shell.h" @@ -79,6 +82,42 @@ static void kill_error __P((pid_t, int)); # define CONTINUE_OR_FAIL goto continue_killing #endif /* CONTINUE_AFTER_KILL_ERROR */ +int kill_by_name(int signum, const char *name) +{ + team_info teamInfo; + uint32 cookie = 0; + int status = EXECUTION_SUCCESS; + int found = 0; + + while (get_next_team_info(&cookie, &teamInfo) >= B_OK) { + char *token, *args; + + args = teamInfo.args; + token = strchr(args, ' '); + if (token) { + /* remove process argument */ + *token = 0; + } + + /* skip the path if any */ + token = basename(args); + + if (!strncmp(name, token, strlen(token))) { + found = 1; + /* name matched */ + if (kill((pid_t)teamInfo.team, signum) != 0) { + kill_error (teamInfo.team, errno); + status = EXECUTION_FAILURE; + } + } + } + + if (!found) + builtin_error (_("(%s) - %s"), name, strerror(ESRCH)); + + return status; +} + /* Here is the kill builtin. We only have it so that people can type kill -KILL %1? No, if you fill up the process table this way you can still kill some. */ @@ -179,20 +218,27 @@ kill_builtin (list) word++; /* Use the entire argument in case of minus sign presence. */ - if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value)) - { - pid = (pid_t) pid_value; - - if (kill_pid (pid, sig, pid < -1) < 0) - { - if (errno == EINVAL) - sh_invalidsig (sigspec); - else - kill_error (pid, errno); - CONTINUE_OR_FAIL; - } - else - any_succeeded++; + if (*word) + { + if (legal_number (list->word->word, &pid_value) + && (pid_value == (pid_t)pid_value)) + { + pid = (pid_t) pid_value; + + if (kill_pid (pid, sig, pid < -1) < 0) + { + if (errno == EINVAL) + sh_invalidsig (sigspec); + else + kill_error (pid, errno); + CONTINUE_OR_FAIL; + } + else + any_succeeded++; + } else { + errno = kill_by_name(sig, word); + CONTINUE_OR_FAIL; + } } #if defined (JOB_CONTROL) else if (*list->word->word && *list->word->word != '%')