kill: implement killall5. OpenWRT folks will be happy.

However their code was unusably different from sysvinit original.
Run tested.
This commit is contained in:
Denis Vlasenko 2006-09-27 14:25:33 +00:00
parent a77947f5bb
commit 0bb628f4f3
4 changed files with 65 additions and 32 deletions

View File

@ -159,6 +159,7 @@ USE_IPROUTE(APPLET(iproute, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall))
USE_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall5))
USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER))

View File

@ -1485,9 +1485,9 @@ USE_FEATURE_DATE_ISOFMT( \
"\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]" "\t\t\t[ ttl TTL ] [ tos TOS ] [ [no]pmtudisc ] [ dev PHYS_DEV ]"
#define kill_trivial_usage \ #define kill_trivial_usage \
"[-signal] process-id [process-id ...]" "[-l] [-signal] process-id [process-id ...]"
#define kill_full_usage \ #define kill_full_usage \
"Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ "Send a signal (default is TERM) to the specified process(es).\n\n" \
"Options:\n" \ "Options:\n" \
"\t-l\tList all signal names and numbers" "\t-l\tList all signal names and numbers"
#define kill_example_usage \ #define kill_example_usage \
@ -1501,15 +1501,22 @@ USE_FEATURE_DATE_ISOFMT( \
"$ kill 252\n" "$ kill 252\n"
#define killall_trivial_usage \ #define killall_trivial_usage \
"[-q] [-signal] process-name [process-name ...]" "[-l] [-q] [-signal] process-name [process-name ...]"
#define killall_full_usage \ #define killall_full_usage \
"Send a signal (default is SIGTERM) to the specified process(es).\n\n" \ "Send a signal (default is TERM) to the specified process(es).\n\n" \
"Options:\n" \ "Options:\n" \
"\t-l\tList all signal names and numbers\n" \ "\t-l\tList all signal names and numbers\n" \
"\t-q\tDo not complain if no processes were killed" "\t-q\tDo not complain if no processes were killed"
#define killall_example_usage \ #define killall_example_usage \
"$ killall apache\n" "$ killall apache\n"
#define killall5_trivial_usage \
"[-l] [-signal]"
#define killall5_full_usage \
"Send a signal (default is TERM) to all processes outside current session.\n\n" \
"Options:\n" \
"\t-l\tList all signal names and numbers\n" \
#define klogd_trivial_usage \ #define klogd_trivial_usage \
"[-c n] [-n]" "[-c n] [-n]"
#define klogd_full_usage \ #define klogd_full_usage \

View File

@ -38,6 +38,11 @@ config CONFIG_KILLALL
specified commands. If no signal name is specified, SIGTERM is specified commands. If no signal name is specified, SIGTERM is
sent. sent.
config CONFIG_KILLALL5
bool "killall5"
default n
depends on CONFIG_KILL
config CONFIG_PIDOF config CONFIG_PIDOF
bool "pidof" bool "pidof"
default n default n

View File

@ -13,17 +13,18 @@
int kill_main(int argc, char **argv) int kill_main(int argc, char **argv)
{ {
char *arg; char *arg;
int killall, signo = SIGTERM, errors = 0, quiet = 0; pid_t pid;
int signo = SIGTERM, errors = 0, quiet = 0;
killall = (ENABLE_KILLALL && bb_applet_name[4]=='a') ? 1 : 0; const int killall = (ENABLE_KILLALL && bb_applet_name[4]=='a'
&& (!ENABLE_KILLALL5 || bb_applet_name[7]!='5'));
const int killall5 = (ENABLE_KILLALL5 && bb_applet_name[4]=='a'
&& (!ENABLE_KILLALL || bb_applet_name[7]=='5'));
/* Parse any options */ /* Parse any options */
argc--; argc--;
arg = *++argv; arg = *++argv;
if (argc<1)
bb_show_usage();
if (arg[0]!='-') { if (argc<1 || arg[0]!='-') {
goto do_it_now; goto do_it_now;
} }
@ -79,42 +80,48 @@ int kill_main(int argc, char **argv)
do_it_now: do_it_now:
/* Pid or name required */ if (killall5) {
pid_t sid;
procps_status_t* p;
/* kill(-1, sig) on Linux (at least 2.1.x)
* might send signal to the calling process too */
signal(SIGTERM, SIG_IGN);
/* Now stop all processes */
kill(-1, SIGSTOP);
/* Find out our own session id */
pid = getpid();
sid = getsid(pid);
/* Now kill all processes except our session */
while ((p = procps_scan(0))!=0) {
if (getsid(p->pid)!=sid && p->pid!=pid && p->pid!=1)
kill(p->pid, signo);
}
/* And let them continue */
kill(-1, SIGCONT);
return 0;
}
/* Pid or name required for kill/killall */
if (argc<1) if (argc<1)
bb_show_usage(); bb_show_usage();
if (!killall) { if (killall) {
/* Looks like they want to do a kill. Do that */
while (arg) {
int pid;
if (!isdigit(arg[0]) && arg[0]!='-')
bb_error_msg_and_die("bad pid '%s'", arg);
pid = strtol(arg, NULL, 0);
if (kill(pid, signo)!=0) {
bb_perror_msg("cannot kill pid %d", pid);
errors++;
}
arg = *++argv;
}
} else {
pid_t myPid = getpid();
/* Looks like they want to do a killall. Do that */ /* Looks like they want to do a killall. Do that */
pid = getpid();
while (arg) { while (arg) {
long* pidList; long* pidList;
pidList = find_pid_by_name(arg); pidList = find_pid_by_name(arg);
if (!pidList || *pidList<=0) { if (!pidList || *pidList<=0) {
errors++; errors++;
if (quiet==0) if (!quiet)
bb_error_msg("%s: no process killed", arg); bb_error_msg("%s: no process killed", arg);
} else { } else {
long *pl; long *pl;
for (pl = pidList; *pl!=0 ; pl++) { for (pl = pidList; *pl!=0; pl++) {
if (*pl==myPid) if (*pl==pid)
continue; continue;
if (kill(*pl, signo)!=0) { if (kill(*pl, signo)!=0) {
errors++; errors++;
@ -126,7 +133,20 @@ do_it_now:
free(pidList); free(pidList);
arg = *++argv; arg = *++argv;
} }
return errors;
} }
/* Looks like they want to do a kill. Do that */
while (arg) {
if (!isdigit(arg[0]) && arg[0]!='-')
bb_error_msg_and_die("bad pid '%s'", arg);
pid = strtol(arg, NULL, 0);
/* FIXME: better overflow check? */
if (kill(pid, signo)!=0) {
bb_perror_msg("cannot kill pid %ld", (long)pid);
errors++;
}
arg = *++argv;
}
return errors; return errors;
} }