0
0
Fork 0
haikuports/app-shells/bash/patches/bash-kill_by_name.patch

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