#! /bin/sh /usr/share/dpatch/dpatch-run ## 82_killall_exclude_pids.dpatch by Colin Watson <cjwatson@ubuntu.com> ## Modified for Debian by Petter Reinholdtsen <pere@hungry.com> ## ## 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. @DPATCH@ diff -urNad trunk~/man/killall5.8 trunk/man/killall5.8 --- trunk~/man/killall5.8 2008-03-26 09:31:24.000000000 +0100 +++ trunk/man/killall5.8 2008-03-26 09:31:24.000000000 +0100 @@ -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 EXIT STATUS The program return zero if it killed processes. It return 2 if no process were killed, and 1 if it was unable to find any processes diff -urNad trunk~/src/killall5.c trunk/src/killall5.c --- trunk~/src/killall5.c 2008-03-26 09:31:24.000000000 +0100 +++ trunk/src/killall5.c 2008-03-26 09:31:24.000000000 +0100 @@ -583,11 +583,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, omit = 0; int sig = SIGKILL; /* return non-zero if no process was killed */ @@ -607,10 +611,34 @@ 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++; + omit = 1; + } + else if ((sig = atoi(argv[1])) <= 0 || sig > 31) + usage(); + } } /* First get the /proc filesystem online. */ @@ -639,11 +667,20 @@ /* Now kill all processes except init (pid 1) and our session. */ sid = (int)getsid(0); pid = (int)getpid(); - for (p = plist; p; p = p->next) - if (p->pid != 1 && p->pid != pid && p->sid != sid && !p->kernel) { - kill(p->pid, sig); - retval = 0; + for (p = plist; p; p = p->next) { + if (p->pid == 1 || p->pid == pid || p->sid == sid || p->kernel) + continue; + if (omit) { + 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); + retval = 0; + } /* And let them continue. */ kill(-1, SIGCONT);