[haiku-commits] haiku: hrev45523 - in src/bin: coreutils/src bash/builtins

  • From: philippe.houdoin@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 18 Apr 2013 00:21:14 +0200 (CEST)

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;
 }


Other related posts: