hrev45523 adds 2 changesets to branch 'master' old head: 103977d0a94f8218b2df110ee2f8a8157edf692f new head: 1e77e4f85290ba74a1cdcc65f59e829cf71ef530 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=1e77e4f+%5E103977d ---------------------------------------------------------------------------- cc2c83f: Applied patch by Prasad Joshi to add kill by process name support. Thanks. Closed #1944. 1e77e4f: Tokenize directly in team_info.args buffer. [ Philippe Houdoin <philippe.houdoin@xxxxxxxxx> ] ---------------------------------------------------------------------------- 3 files changed, 107 insertions(+), 25 deletions(-) src/bin/bash/builtins/common.c | 4 +- src/bin/bash/builtins/kill.def | 1 + src/bin/coreutils/src/kill.c | 127 ++++++++++++++++++++++++++++++------- ############################################################################ Commit: cc2c83fa5ce13347f19da08a40f43c256e96d9a6 URL: http://cgit.haiku-os.org/haiku/commit/?id=cc2c83f Author: Philippe Houdoin <philippe.houdoin@xxxxxxxxx> Date: Wed Apr 17 22:07:05 2013 UTC Ticket: https://dev.haiku-os.org/ticket/1944 Applied patch by Prasad Joshi to add kill by process name support. Thanks. Closed #1944. ---------------------------------------------------------------------------- diff --git a/src/bin/bash/builtins/common.c b/src/bin/bash/builtins/common.c index 6ba641b..2c75b84 100644 --- a/src/bin/bash/builtins/common.c +++ b/src/bin/bash/builtins/common.c @@ -760,7 +760,7 @@ display_signal_list (list, forcecols) list = list->next; continue; } -#if defined (JOB_CONTROL) +#if defined (JOB_CONTROL) && defined(HAVE_KILL_BUILTIN) /* 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,8 +771,10 @@ 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) { diff --git a/src/bin/bash/builtins/kill.def b/src/bin/bash/builtins/kill.def index 734da25..4cff928 100644 --- a/src/bin/bash/builtins/kill.def +++ b/src/bin/bash/builtins/kill.def @@ -22,6 +22,7 @@ $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. diff --git a/src/bin/coreutils/src/kill.c b/src/bin/coreutils/src/kill.c index dab4fa8..e7e0de0 100644 --- a/src/bin/coreutils/src/kill.c +++ b/src/bin/coreutils/src/kill.c @@ -21,6 +21,7 @@ #include <getopt.h> #include <sys/types.h> #include <signal.h> +#include <libgen.h> #if HAVE_SYS_WAIT_H # include <sys/wait.h> @@ -36,6 +37,7 @@ #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" @@ -85,7 +87,7 @@ usage (int status) else { printf (_("\ -Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\ +Usage: %s [-s SIGNAL | -SIGNAL] <PID | PROCESS> ...\n\ or: %s -l [SIGNAL]...\n\ or: %s -t [SIGNAL]...\n\ "), @@ -109,6 +111,8 @@ 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 (); @@ -196,38 +200,121 @@ 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; + + 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; + } + + args = strdup(args); + if (args == NULL) { + error (0, errno, "%s", name); + status = EXIT_FAILURE; + continue; + } + + /* skip the path if any */ + token = basename(args); + + if (!strncmp(name, token, strlen(token))) { + /* name matched */ + if (kill((pid_t)teamInfo.team, signum) != 0) { + error (0, errno, "%s", name); + status = EXIT_FAILURE; + } + } + free(args); + } + 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; + int status = EXIT_SUCCESS; + char const *arg = *argv; + pid_t pid; - 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)); + 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; + } + continue; + } - return status; + /* not a valid pid, kill by process name */ + if (kill_by_name(signum, arg) != EXIT_SUCCESS) + status = EXIT_FAILURE; + + } while ((arg = *argv++)); + + return status; } - + + int main (int argc, char **argv) { ############################################################################ Revision: hrev45523 Commit: 1e77e4f85290ba74a1cdcc65f59e829cf71ef530 URL: http://cgit.haiku-os.org/haiku/commit/?id=1e77e4f Author: Philippe Houdoin <philippe.houdoin@xxxxxxxxx> Date: Wed Apr 17 22:17:26 2013 UTC Tokenize directly in team_info.args buffer. ---------------------------------------------------------------------------- diff --git a/src/bin/coreutils/src/kill.c b/src/bin/coreutils/src/kill.c index e7e0de0..baba4f4 100644 --- a/src/bin/coreutils/src/kill.c +++ b/src/bin/coreutils/src/kill.c @@ -262,13 +262,6 @@ int kill_by_name(int signum, const char *name) *token = 0; } - args = strdup(args); - if (args == NULL) { - error (0, errno, "%s", name); - status = EXIT_FAILURE; - continue; - } - /* skip the path if any */ token = basename(args); @@ -279,7 +272,6 @@ int kill_by_name(int signum, const char *name) status = EXIT_FAILURE; } } - free(args); } return status; }