111 lines
2.7 KiB
Diff
111 lines
2.7 KiB
Diff
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 != '%')
|