From 61a91af63dbc91f85058efda5c542dfc859ab1be Mon Sep 17 00:00:00 2001 From: Kang-Che Sung Date: Mon, 9 Jan 2017 18:46:58 +0100 Subject: 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 Signed-off-by: Denys Vlasenko --- procps/Kbuild.src | 3 --- procps/kill.c | 46 ++++++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/procps/Kbuild.src b/procps/Kbuild.src index dedef8881..6b4fb7470 100644 --- a/procps/Kbuild.src +++ b/procps/Kbuild.src @@ -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 diff --git a/procps/kill.c b/procps/kill.c index 7c0822542..0ef1716a4 100644 --- a/procps/kill.c +++ b/procps/kill.c @@ -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 } -- cgit v1.2.3