kill: optimizations for single-applet build
* Fix a bug with a configuration in which the shell's kill builtin would be mistreated as a killall command (i.e. '-q' works, and 'kill process_name' succeeds when it shouldn't): CONFIG_ASH_JOB_CONTROL=y CONFIG_HUSH_KILL=y # CONFIG_KILL is not set CONFIG_KILLALL=y # CONFIG_KILLALL5 is not set * Optimize out unneeded code when the relevant applets are not selected. * Move kbuild lines about shells' kill builtins from Kbuild.src to kill.c, to accompany the new HAVE_SH_KILL macro. I hope this would make maintanence a little bit easier. Signed-off-by: Kang-Che Sung <explorer09@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
1cc6804f69
commit
61a91af63d
@ -7,6 +7,3 @@
|
||||
lib-y:=
|
||||
|
||||
INSERT
|
||||
|
||||
lib-$(CONFIG_ASH_JOB_CONTROL) += kill.o # used for built-in kill by ash
|
||||
lib-$(CONFIG_HUSH_KILL) += kill.o # used for built-in kill by hush
|
||||
|
@ -92,28 +92,34 @@
|
||||
* This is needed to avoid collision with kill -9 ... syntax
|
||||
*/
|
||||
|
||||
//kbuild:lib-$(CONFIG_ASH_JOB_CONTROL) += kill.o
|
||||
//kbuild:lib-$(CONFIG_HUSH_KILL) += kill.o
|
||||
|
||||
#define SH_KILL (ENABLE_ASH_JOB_CONTROL || ENABLE_HUSH_KILL)
|
||||
/* If shells want to have "kill", for ifdefs it's like ENABLE_KILL=1 */
|
||||
#if SH_KILL
|
||||
# undef ENABLE_KILL
|
||||
# define ENABLE_KILL 1
|
||||
#endif
|
||||
#define KILL_APPLET_CNT (ENABLE_KILL + ENABLE_KILLALL + ENABLE_KILLALL5)
|
||||
|
||||
int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
char *arg;
|
||||
pid_t pid;
|
||||
int signo = SIGTERM, errors = 0, quiet = 0;
|
||||
#if ENABLE_KILL && !ENABLE_KILLALL && !ENABLE_KILLALL5
|
||||
# define killall 0
|
||||
# define killall5 0
|
||||
#elif !ENABLE_KILL && ENABLE_KILLALL && !ENABLE_KILLALL5
|
||||
# define killall 1
|
||||
# define killall5 0
|
||||
#elif !ENABLE_KILL && !ENABLE_KILLALL && ENABLE_KILLALL5
|
||||
# define killall 0
|
||||
# define killall5 1
|
||||
|
||||
#if KILL_APPLET_CNT == 1
|
||||
# define is_killall ENABLE_KILLALL
|
||||
# define is_killall5 ENABLE_KILLALL5
|
||||
#else
|
||||
/* How to determine who we are? find 3rd char from the end:
|
||||
* kill, killall, killall5
|
||||
* ^i ^a ^l - it's unique
|
||||
* (checking from the start is complicated by /bin/kill... case) */
|
||||
const char char3 = argv[0][strlen(argv[0]) - 3];
|
||||
# define killall (ENABLE_KILLALL && char3 == 'a')
|
||||
# define killall5 (ENABLE_KILLALL5 && char3 == 'l')
|
||||
# define is_killall (ENABLE_KILLALL && char3 == 'a')
|
||||
# define is_killall5 (ENABLE_KILLALL5 && char3 == 'l')
|
||||
#endif
|
||||
|
||||
/* Parse any options */
|
||||
@ -162,7 +168,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
|
||||
/* The -q quiet option */
|
||||
if (killall && arg[1] == 'q' && arg[2] == '\0') {
|
||||
if (is_killall && arg[1] == 'q' && arg[2] == '\0') {
|
||||
quiet = 1;
|
||||
arg = *++argv;
|
||||
if (!arg)
|
||||
@ -174,7 +180,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
arg++; /* skip '-' */
|
||||
|
||||
/* -o PID? (if present, it always is at the end of command line) */
|
||||
if (killall5 && arg[0] == 'o')
|
||||
if (is_killall5 && arg[0] == 'o')
|
||||
goto do_it_now;
|
||||
|
||||
if (argv[1] && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */
|
||||
@ -190,7 +196,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
do_it_now:
|
||||
pid = getpid();
|
||||
|
||||
if (killall5) {
|
||||
if (is_killall5) {
|
||||
pid_t sid;
|
||||
procps_status_t* p = NULL;
|
||||
/* compat: exitcode 2 is "no one was signaled" */
|
||||
@ -248,13 +254,14 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ENABLE_KILL || ENABLE_KILLALL
|
||||
/* Pid or name is required for kill/killall */
|
||||
if (!arg) {
|
||||
bb_error_msg("you need to specify whom to kill");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (killall) {
|
||||
if (!ENABLE_KILL || is_killall) {
|
||||
/* Looks like they want to do a killall. Do that */
|
||||
do {
|
||||
pid_t* pidList;
|
||||
@ -282,10 +289,12 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
} while (arg);
|
||||
return errors;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_KILL
|
||||
/* Looks like they want to do a kill. Do that */
|
||||
while (arg) {
|
||||
#if ENABLE_ASH_JOB_CONTROL || ENABLE_HUSH_KILL
|
||||
# if SH_KILL
|
||||
/*
|
||||
* We need to support shell's "hack formats" of
|
||||
* " -PRGP_ID" (yes, with a leading space)
|
||||
@ -307,7 +316,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
}
|
||||
arg = end; /* can only point to ' ' or '\0' now */
|
||||
}
|
||||
#else
|
||||
# else /* ENABLE_KILL but !SH_KILL */
|
||||
pid = bb_strtoi(arg, NULL, 10);
|
||||
if (errno) {
|
||||
bb_error_msg("invalid number '%s'", arg);
|
||||
@ -316,8 +325,9 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
|
||||
bb_perror_msg("can't kill pid %d", (int)pid);
|
||||
errors++;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
arg = *++argv;
|
||||
}
|
||||
return errors;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user