From d0e8ee42ec100536eddebca79463a7baeaf73c05 Mon Sep 17 00:00:00 2001
From: Rene Gollent <rene@gollent.com>
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 <unistd.h>
 #endif

+#include <OS.h>
+
 #include "../bashansi.h"
 #include "../bashintl.h"

+#include <libgen.h>
 #include <signal.h>

 #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 != '%')
