#! /bin/sh /usr/share/dpatch/dpatch-run ## 92_killall5_omitpid.dpatch by Tilman Koschnick ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Add -o option to killall5, to protect processes from being killed. @DPATCH@ diff -urNad sysvinit-2.86.ds1~/man/killall5.8 sysvinit-2.86.ds1/man/killall5.8 --- sysvinit-2.86.ds1~/man/killall5.8 2007-11-26 22:03:43.486069124 +0100 +++ sysvinit-2.86.ds1/man/killall5.8 2007-11-26 22:03:55.846093972 +0100 @@ -4,11 +4,16 @@ .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 +the shell that is running the script it was called from, as well as any +processes that are excluded by providing the \fB-o\fP option. Its primary (only) use is in the \fBrc\fP scripts found in the /etc/init.d directory. .SH EXIT STATUS The program return zero if it killed processes. It return 2 if no diff -urNad sysvinit-2.86.ds1~/src/killall5.c sysvinit-2.86.ds1/src/killall5.c --- sysvinit-2.86.ds1~/src/killall5.c 2007-11-26 22:03:43.486069124 +0100 +++ sysvinit-2.86.ds1/src/killall5.c 2007-11-26 22:04:19.062140650 +0100 @@ -488,9 +488,9 @@ } #define PIDOF_SINGLE 0x01 -#define PIDOF_OMIT 0x02 +#define PID_OMIT 0x02 -#define PIDOF_OMITSZ 5 +#define PID_OMITSZ 5 /* * Pidof functionality. @@ -499,12 +499,12 @@ { PIDQ_HEAD *q; PROC *p; - pid_t opid[PIDOF_OMITSZ], spid; + pid_t opid[PID_OMITSZ], spid; int f; int first = 1; int i, oind, opt, flags = 0; - for (oind = PIDOF_OMITSZ-1; oind > 0; oind--) + for (oind = PID_OMITSZ-1; oind > 0; oind--) opid[oind] = 0; opterr = 0; @@ -514,9 +514,9 @@ closelog(); exit(1); case 'o': - if (oind >= PIDOF_OMITSZ -1) { + if (oind >= PID_OMITSZ -1) { nsyslog(LOG_ERR,"omit pid buffer size %d " - "exceeded!\n", PIDOF_OMITSZ); + "exceeded!\n", PID_OMITSZ); closelog(); exit(1); } @@ -530,7 +530,7 @@ exit(1); } oind++; - flags |= PIDOF_OMIT; + flags |= PID_OMIT; break; case 's': flags |= PIDOF_SINGLE; @@ -551,7 +551,7 @@ if ((q = pidof(argv[f])) != NULL) { spid = 0; while ((p = get_next_from_pid_q(q))) { - if (flags & PIDOF_OMIT) { + if (flags & PID_OMIT) { for (i = 0; i < oind; i++) if (opid[i] == p->pid) break; @@ -589,6 +589,8 @@ PROC *p; int pid, sid = -1; int sig = SIGKILL; + pid_t opid[PID_OMITSZ]; + int i, oind, flags = 0; /* return non-zero if no process was killed */ int retval = 2; @@ -607,10 +609,43 @@ return main_pidof(argc, argv); /* Right, so we are "killall". */ - if (argc > 1) { - if (argc != 2) usage(); - if (argv[1][0] == '-') (argv[1])++; - if ((sig = atoi(argv[1])) <= 0 || sig > 31) usage(); + for (oind = PID_OMITSZ-1; oind > 0; oind--) + opid[oind] = 0; + opterr = 0; + + for (--argc, ++argv; argc > 0; argc--, argv++) { + if (strncmp(*argv, "-o", 2) == 0) { + if (oind >= PID_OMITSZ -1) { + nsyslog(LOG_ERR,"omit pid buffer size %d " + "exceeded!\n", PID_OMITSZ); + closelog(); + exit(1); + } + if (strlen(*argv) > 2) { + (*argv)++; (*argv)++; + } else { + argc--; + argv++; + if (argc == 0) { + nsyslog(LOG_ERR,"missing argument to " + "option -o\n"); + closelog(); + exit(1); + } + } + if ((opid[oind] = atoi(*argv)) < 1) { + nsyslog(LOG_ERR, + "illegal omit pid value (%s)!\n", + *argv); + closelog(); + exit(1); + } + oind++; + flags |= PID_OMIT; + } else { + if (*argv[0] == '-') (*argv)++; + if ((sig = atoi(*argv)) <= 0 || sig > 31) usage(); + } } /* First get the /proc filesystem online. */ @@ -639,11 +674,23 @@ /* 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) + for (p = plist; p; p = p->next) { + if (flags & PID_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; + } if (p->pid != 1 && p->pid != pid && p->sid != sid && !p->kernel) { kill(p->pid, sig); retval = 0; } + } /* And let them continue. */ kill(-1, SIGCONT);