Revert changes to coreutils kill.c...

..introduced by cc2c83fa5c and subsequent
cleanups. Instead, patch bash's builtin kill directly to handle the kill
by name functionality. Fixes #9687 and reintroduces the ability to kill
jobs.
This commit is contained in:
Rene Gollent
2013-05-18 10:20:39 -04:00
parent 81abe2a6a3
commit 74875a2e90
3 changed files with 89 additions and 124 deletions
+1 -3
View File
@@ -760,7 +760,7 @@ display_signal_list (list, forcecols)
list = list->next; list = list->next;
continue; continue;
} }
#if defined (JOB_CONTROL) && defined(HAVE_KILL_BUILTIN) #if defined (JOB_CONTROL)
/* POSIX.2 says that `kill -l signum' prints the signal name without /* POSIX.2 says that `kill -l signum' prints the signal name without
the `SIG' prefix. */ the `SIG' prefix. */
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
@@ -771,10 +771,8 @@ display_signal_list (list, forcecols)
else else
{ {
dflags = DSIG_NOCASE; dflags = DSIG_NOCASE;
#if defined(HAVE_KILL_BUILTIN)
if (posixly_correct == 0 || this_shell_builtin != kill_builtin) if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
dflags |= DSIG_SIGPREFIX; dflags |= DSIG_SIGPREFIX;
#endif
signum = decode_signal (list->word->word, dflags); signum = decode_signal (list->word->word, dflags);
if (signum == NO_SIG) if (signum == NO_SIG)
{ {
+50 -2
View File
@@ -22,7 +22,6 @@ $PRODUCES kill.c
$BUILTIN kill $BUILTIN kill
$FUNCTION kill_builtin $FUNCTION kill_builtin
$DEPENDS_ON HAVE_KILL_BUILTIN
$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] $SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Send a signal to a job. Send a signal to a job.
@@ -55,6 +54,8 @@ $END
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <OS.h>
#include "../bashansi.h" #include "../bashansi.h"
#include "../bashintl.h" #include "../bashintl.h"
@@ -78,6 +79,46 @@ static void kill_error __P((pid_t, int));
# define CONTINUE_OR_FAIL goto continue_killing # define CONTINUE_OR_FAIL goto continue_killing
#endif /* CONTINUE_AFTER_KILL_ERROR */ #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 /* 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 kill -KILL %1? No, if you fill up the process table this way you
can still kill some. */ can still kill some. */
@@ -177,7 +218,10 @@ kill_builtin (list)
word++; word++;
/* Use the entire argument in case of minus sign presence. */ /* 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)) if (*word)
{
if (legal_number (list->word->word, &pid_value)
&& (pid_value == (pid_t)pid_value))
{ {
pid = (pid_t) pid_value; pid = (pid_t) pid_value;
@@ -191,6 +235,10 @@ kill_builtin (list)
} }
else else
any_succeeded++; any_succeeded++;
} else {
errno = kill_by_name(sig, word);
CONTINUE_OR_FAIL;
}
} }
#if defined (JOB_CONTROL) #if defined (JOB_CONTROL)
else if (*list->word->word && *list->word->word != '%') else if (*list->word->word && *list->word->word != '%')
+18 -99
View File
@@ -21,7 +21,6 @@
#include <getopt.h> #include <getopt.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
#include <libgen.h>
#if HAVE_SYS_WAIT_H #if HAVE_SYS_WAIT_H
# include <sys/wait.h> # include <sys/wait.h>
@@ -37,7 +36,6 @@
#include "error.h" #include "error.h"
#include "sig2str.h" #include "sig2str.h"
#include "operand2sig.h" #include "operand2sig.h"
#include "OS.h"
/* The official name of this program (e.g., no `g' prefix). */ /* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "kill" #define PROGRAM_NAME "kill"
@@ -87,7 +85,7 @@ usage (int status)
else else
{ {
printf (_("\ printf (_("\
Usage: %s [-s SIGNAL | -SIGNAL] <PID | PROCESS> ...\n\ Usage: %s [-s SIGNAL | -SIGNAL] PID...\n\
or: %s -l [SIGNAL]...\n\ or: %s -l [SIGNAL]...\n\
or: %s -t [SIGNAL]...\n\ or: %s -t [SIGNAL]...\n\
"), "),
@@ -111,8 +109,6 @@ 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\ 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\ or the exit status of a process terminated by a signal.\n\
PID is an integer; if negative it identifies a process group.\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); "), stdout);
printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME); printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
emit_ancillary_info (); emit_ancillary_info ();
@@ -200,89 +196,7 @@ list_signals (bool table, char *const *argv)
return status; 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;
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) {
error (0, errno, "%s", name);
status = EXIT_FAILURE;
}
}
}
if (!found)
error (0, ESRCH, "%s", name);
return status;
}
/* Send signal SIGNUM to all the processes or process groups specified /* Send signal SIGNUM to all the processes or process groups specified
by ARGV. Return a suitable exit status. */ by ARGV. Return a suitable exit status. */
@@ -291,24 +205,29 @@ send_signals (int signum, char *const *argv)
{ {
int status = EXIT_SUCCESS; int status = EXIT_SUCCESS;
char const *arg = *argv; char const *arg = *argv;
pid_t pid;
do { do
bool is_pid = is_number(arg, (intmax_t *) &pid); {
if (is_pid) { char *endp;
if (kill(pid, signum) != 0) { 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); error (0, errno, "%s", arg);
status = EXIT_FAILURE; status = EXIT_FAILURE;
} }
} else if (kill_by_name(signum, arg) != EXIT_SUCCESS) }
status = EXIT_FAILURE; while ((arg = *++argv));
} while ((arg = *++argv));
return status; return status;
} }
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {