## 82_killall_exclude_pids.dpatch by Colin Watson ## Modified for Debian by Petter Reinholdtsen ## Modified for ArchLinux by Anton Fiuman ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Implement '-o omitpid' option, to allow sendsigs to avoid killing ## DP: processes that are e.g. implementing the root filesystem. --- sysvinit-2.86/man/killall5.8 2004-06-09 14:47:45.000000000 +0200 +++ b/man/killall5.8 2008-05-31 16:28:39.000000000 +0200 @@ -4,12 +4,19 @@ .SH SYNOPSIS .B killall5 .RB -signalnumber +.RB [ \-o +.IR omitpid ] +.RB [ \-o +.IR omitpid.. ] .SH DESCRIPTION .B killall5 is the SystemV killall command. It sends a signal to all processes except kernel threads and the processes in its own session, so it won't kill the shell that is running the script it was called from. Its primary (only) use is in the \fBrc\fP scripts found in the /etc/init.d directory. +.SH OPTIONS +.IP "-o \fIomitpid\fP" +Tells \fIkillall5\fP to omit processes with that process id. .SH SEE ALSO .BR halt (8), .BR reboot (8) --- sysvinit-2.86/src/killall5.c 2004-07-30 14:16:23.000000000 +0200 +++ b/src/killall5.c 2008-05-31 17:43:55.000000000 +0200 @@ -7,7 +7,7 @@ * * Version: 2.86 30-Jul-2004 MvS * - * Usage: killall5 [-][signal] + * Usage: killall5 [-][signal] [-o omitpid [-o omitpid]] * pidof [-s] [-o omitpid [-o omitpid]] program [program..] * * Authors: Miquel van Smoorenburg, miquels@cistron.nl @@ -434,7 +434,7 @@ /* Give usage message and exit. */ void usage(void) { - nsyslog(LOG_ERR, "only one argument, a signal number, allowed"); + nsyslog(LOG_ERR, "killall5 [-][signal] [-o omitpid [-o omitpid]]"); closelog(); exit(1); } @@ -554,12 +554,15 @@ } +#define KILLALL_OMITSZ 16 /* Main for either killall or pidof. */ int main(int argc, char **argv) { PROC *p; int pid, sid = -1; + pid_t opid[KILLALL_OMITSZ]; + int i, oind; int sig = SIGKILL; /* Get program name. */ @@ -576,10 +579,35 @@ return main_pidof(argc, argv); /* Right, so we are "killall". */ + for (oind = KILLALL_OMITSZ-1; oind > 0; oind--) + opid[oind] = 0; + if (argc > 1) { - if (argc != 2) usage(); - if (argv[1][0] == '-') (argv[1])++; - if ((sig = atoi(argv[1])) <= 0 || sig > 31) usage(); + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') + (argv[i])++; + if (argv[i][0] == 'o') { + if (++i >= argc) + usage(); + if (oind >= KILLALL_OMITSZ -1) { + nsyslog(LOG_ERR,"omit pid buffer size " + "%d exceeded!\n", + KILLALL_OMITSZ); + closelog(); + exit(1); + } + if ((opid[oind] = atoi(argv[i])) < 1) { + nsyslog(LOG_ERR, + "illegal omit pid value " + "(%s)!\n", argv[i]); + closelog(); + exit(1); + } + oind++; + } + else if ((sig = atoi(argv[1])) <= 0 || sig > 31) + usage(); + } } /* First get the /proc filesystem online. */ @@ -608,9 +636,19 @@ /* Now kill all processes except our session. */ sid = (int)getsid(0); pid = (int)getpid(); - for (p = plist; p; p = p->next) - if (p->pid != pid && p->sid != sid && !p->kernel) - kill(p->pid, sig); + for (p = plist; p; p = p->next) { + if (p->pid == pid || p->sid == sid || p->kernel) + continue; + if (oind) { + for (i = 0; i < oind; i++) + if (opid[i] == p->pid) + break; + /* On a match, continue with the for loop above. */ + if (i < oind) + continue; + } + kill(p->pid, sig); + } /* And let them continue. */ kill(-1, SIGCONT);