From a0ab943492c123690f41b751136e8c9cf261e195 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 7 Feb 2009 22:30:39 +0000 Subject: function old new delta kill_main 706 884 +178 --- include/usage.h | 3 ++- procps/kill.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/include/usage.h b/include/usage.h index 367da1d3d..52af47e58 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2123,11 +2123,12 @@ "$ killall apache\n" #define killall5_trivial_usage \ - "[-l] [-SIG]" + "[-l] [-SIG] [-o PID]..." #define killall5_full_usage "\n\n" \ "Send a signal (default is TERM) to all processes outside current session\n" \ "\nOptions:" \ "\n -l List all signal names and numbers" \ + "\n -o PID Do not signal this PID" \ /* "\n -s SIG Yet another way of specifying SIG" */ \ #define klogd_trivial_usage \ diff --git a/procps/kill.c b/procps/kill.c index 140550018..1f8206986 100644 --- a/procps/kill.c +++ b/procps/kill.c @@ -92,11 +92,18 @@ int kill_main(int argc, char **argv) quiet = 1; arg = *++argv; argc--; - if (argc < 1) bb_show_usage(); - if (arg[0] != '-') goto do_it_now; + if (argc < 1) + bb_show_usage(); + if (arg[0] != '-') + goto do_it_now; } arg++; /* skip '-' */ + + /* -o PID? (if present, it always is at the end of command line) */ + if (killall5 && arg[0] == 'o') + goto do_it_now; + if (argc > 1 && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */ argc--; arg = *++argv; @@ -109,25 +116,57 @@ int kill_main(int argc, char **argv) arg = *++argv; argc--; -do_it_now: + do_it_now: pid = getpid(); if (killall5) { pid_t sid; procps_status_t* p = NULL; + int ret = 0; - /* Find out our own session id */ + /* Find out our session id */ sid = getsid(pid); - /* Now stop all processes */ + /* Stop all processes */ kill(-1, SIGSTOP); - /* Now kill all processes except our session */ + /* Signal all processes except those in our session */ while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) { - if (p->sid != (unsigned)sid && p->pid != (unsigned)pid && p->pid != 1) - kill(p->pid, signo); + int i; + + if (p->sid == (unsigned)sid + || p->pid == (unsigned)pid + || p->pid == 1) + continue; + + /* All remaining args must be -o PID options. + * Check p->pid against them. */ + for (i = 0; i < argc; i++) { + pid_t omit; + + arg = argv[i]; + if (arg[0] != '-' || arg[1] != 'o') { + bb_error_msg("bad option '%s'", arg); + ret = 1; + goto resume; + } + arg += 2; + if (!arg[0] && argv[++i]) + arg = argv[i]; + omit = bb_strtoi(arg, NULL, 10); + if (errno) { + bb_error_msg("bad pid '%s'", arg); + ret = 1; + goto resume; + } + if (p->pid == omit) + goto dont_kill; + } + kill(p->pid, signo); + dont_kill: ; } + resume: /* And let them continue */ kill(-1, SIGCONT); - return 0; + return ret; } /* Pid or name is required for kill/killall */ -- cgit v1.2.3