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_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER))
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_LASH(APPLET(lash, _BB_DIR_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 ]"
#define kill_trivial_usage \
"[-signal] process-id [process-id ...]"
"[-l] [-signal] process-id [process-id ...]"
#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" \
"\t-l\tList all signal names and numbers"
#define kill_example_usage \
@ -1501,15 +1501,22 @@ USE_FEATURE_DATE_ISOFMT( \
"$ kill 252\n"
#define killall_trivial_usage \
"[-q] [-signal] process-name [process-name ...]"
"[-l] [-q] [-signal] process-name [process-name ...]"
#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" \
"\t-l\tList all signal names and numbers\n" \
"\t-q\tDo not complain if no processes were killed"
#define killall_example_usage \
"$ 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 \
"[-c n] [-n]"
#define klogd_full_usage \

View File

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

View File

@ -13,17 +13,18 @@
int kill_main(int argc, char **argv)
{
char *arg;
int killall, signo = SIGTERM, errors = 0, quiet = 0;
killall = (ENABLE_KILLALL && bb_applet_name[4]=='a') ? 1 : 0;
pid_t pid;
int signo = SIGTERM, errors = 0, quiet = 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 */
argc--;
arg = *++argv;
if (argc<1)
bb_show_usage();
if (arg[0]!='-') {
if (argc<1 || arg[0]!='-') {
goto do_it_now;
}
@ -79,42 +80,48 @@ int kill_main(int argc, char **argv)
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)
bb_show_usage();
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();
if (killall) {
/* Looks like they want to do a killall. Do that */
pid = getpid();
while (arg) {
long* pidList;
pidList = find_pid_by_name(arg);
if (!pidList || *pidList<=0) {
errors++;
if (quiet==0)
if (!quiet)
bb_error_msg("%s: no process killed", arg);
} else {
long *pl;
for (pl = pidList; *pl!=0 ; pl++) {
if (*pl==myPid)
for (pl = pidList; *pl!=0; pl++) {
if (*pl==pid)
continue;
if (kill(*pl, signo)!=0) {
errors++;
@ -126,7 +133,20 @@ do_it_now:
free(pidList);
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;
}