hrev45699 adds 1 changeset to branch 'master' old head: 81abe2a6a3721cdf22b87acf7447b944f6d1a5c6 new head: 74875a2e9040ffb838fb9de7833964d4f2af7900 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=74875a2+%5E81abe2a ---------------------------------------------------------------------------- 74875a2: Revert changes to coreutils kill.c... ..introduced by cc2c83fa5ce13347f19da08a40f43c256e96d9a6 and subsequent cleanups. Instead, patch bash's builtin kill directly to handle the kill by name functionality. Fixes #9687 and reintroduces the ability to kill jobs. [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev45699 Commit: 74875a2e9040ffb838fb9de7833964d4f2af7900 URL: http://cgit.haiku-os.org/haiku/commit/?id=74875a2 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sat May 18 14:17:41 2013 UTC Ticket: https://dev.haiku-os.org/ticket/9687 ---------------------------------------------------------------------------- 3 files changed, 91 insertions(+), 126 deletions(-) src/bin/bash/builtins/common.c | 10 ++- src/bin/bash/builtins/kill.def | 78 +++++++++++++++++----- src/bin/coreutils/src/kill.c | 129 +++++++------------------------------ ---------------------------------------------------------------------------- diff --git a/src/bin/bash/builtins/common.c b/src/bin/bash/builtins/common.c index 2c75b84..4e43618 100644 --- a/src/bin/bash/builtins/common.c +++ b/src/bin/bash/builtins/common.c @@ -64,7 +64,7 @@ #endif #if !defined (errno) -extern int errno; +extern int errno; #endif /* !errno */ extern int indirection_level, subshell_environment; @@ -494,7 +494,7 @@ get_exitstat (list) list = list->next; if (list == 0) - return (last_command_exit_value); + return (last_command_exit_value); arg = list->word->word; if (arg == 0 || legal_number (arg, &sval) == 0) @@ -760,7 +760,7 @@ display_signal_list (list, forcecols) list = list->next; continue; } -#if defined (JOB_CONTROL) && defined(HAVE_KILL_BUILTIN) +#if defined (JOB_CONTROL) /* POSIX.2 says that `kill -l signum' prints the signal name without the `SIG' prefix. */ printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); @@ -771,10 +771,8 @@ display_signal_list (list, forcecols) else { dflags = DSIG_NOCASE; -#if defined(HAVE_KILL_BUILTIN) if (posixly_correct == 0 || this_shell_builtin != kill_builtin) dflags |= DSIG_SIGPREFIX; -#endif signum = decode_signal (list->word->word, dflags); if (signum == NO_SIG) { @@ -869,7 +867,7 @@ find_special_builtin (name) current_builtin->function : (sh_builtin_func_t *)NULL); } - + static int shell_builtin_compare (sbp1, sbp2) struct builtin *sbp1, *sbp2; diff --git a/src/bin/bash/builtins/kill.def b/src/bin/bash/builtins/kill.def index 4cff928..d4a415b 100644 --- a/src/bin/bash/builtins/kill.def +++ b/src/bin/bash/builtins/kill.def @@ -22,7 +22,6 @@ $PRODUCES kill.c $BUILTIN kill $FUNCTION kill_builtin -$DEPENDS_ON HAVE_KILL_BUILTIN $SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] Send a signal to a job. @@ -55,6 +54,8 @@ $END # include <unistd.h> #endif +#include <OS.h> + #include "../bashansi.h" #include "../bashintl.h" @@ -78,6 +79,46 @@ 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. */ @@ -177,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 != '%') diff --git a/src/bin/coreutils/src/kill.c b/src/bin/coreutils/src/kill.c index f65b0ca..dab4fa8 100644 --- a/src/bin/coreutils/src/kill.c +++ b/src/bin/coreutils/src/kill.c @@ -21,7 +21,6 @@ #include <getopt.h> #include <sys/types.h> #include <signal.h> -#include <libgen.h> #if HAVE_SYS_WAIT_H # include <sys/wait.h> @@ -37,7 +36,6 @@ #include "error.h" #include "sig2str.h" #include "operand2sig.h" -#include "OS.h" /* The official name of this program (e.g., no `g' prefix). */ #define PROGRAM_NAME "kill" @@ -87,7 +85,7 @@ usage (int status) else { printf (_("\ -Usage: %s [-s SIGNAL | -SIGNAL] <PID | PROCESS> ...\n\ +Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\ or: %s -l [SIGNAL]...\n\ or: %s -t [SIGNAL]...\n\ "), @@ -111,8 +109,6 @@ Mandatory arguments to long options are mandatory for short options too.\n\ SIGNAL may be a signal name like `HUP', or a signal number like `1',\n\ or the exit status of a process terminated by a signal.\n\ PID is an integer; if negative it identifies a process group.\n\ -PROCESS is name of the process to be killed. The signal will be sent \n\ -to all of the processes matching the given PROCESS name.\n\ "), stdout); printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); emit_ancillary_info (); @@ -200,115 +196,38 @@ list_signals (bool table, char *const *argv) return status; } - - -/* - * Checks if passed string is a valid number - * - * Returns: - * true: on valid number - * The converted number is returned in NUM if it is not NULL - * - * false: on invalid number - * - */ -bool is_number(const char *str, intmax_t *_number) -{ - char *end; - intmax_t number; - - if (!str) - return 0; - - errno = 0; - number = strtoimax(str, &end, 10); - if (errno == ERANGE || str == end) { - /* not a valid number */ - return false; - } - - /* skip all whitespace if there are any */ - while (*end == ' ' || *end == '\t') - end++; - - if (*end == '\0') { - if (_number) - *_number = number; - return true; - } - return false; -} - - -/* - * kill the processes if they match given name - * - * Returns EXIT_SUCCESS signal was successfully sent to all matched processes, - * otherwise EXIT_FAILURE is returned. - */ -int kill_by_name(int signum, const char *name) -{ - team_info teamInfo; - uint32 cookie = 0; - int status = EXIT_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) { - error (0, errno, "%s", name); - status = EXIT_FAILURE; - } - } - } - - if (!found) - error (0, ESRCH, "%s", name); - - return status; -} - - + /* Send signal SIGNUM to all the processes or process groups specified by ARGV. Return a suitable exit status. */ static int send_signals (int signum, char *const *argv) { - int status = EXIT_SUCCESS; - char const *arg = *argv; - pid_t pid; - - do { - bool is_pid = is_number(arg, (intmax_t *) &pid); - if (is_pid) { - if (kill(pid, signum) != 0) { - error (0, errno, "%s", arg); - status = EXIT_FAILURE; - } - } else if (kill_by_name(signum, arg) != EXIT_SUCCESS) - status = EXIT_FAILURE; + int status = EXIT_SUCCESS; + char const *arg = *argv; - } while ((arg = *++argv)); + do + { + char *endp; + intmax_t n = (errno = 0, strtoimax (arg, &endp, 10)); + pid_t pid = n; + + if (errno == ERANGE || pid != n || arg == endp || *endp) + { + error (0, 0, _("%s: invalid process id"), arg); + status = EXIT_FAILURE; + } + else if (kill (pid, signum) != 0) + { + error (0, errno, "%s", arg); + status = EXIT_FAILURE; + } + } + while ((arg = *++argv)); - return status; + return status; } - - + int main (int argc, char **argv) {