smgl/simpleinit-msb: initial commit
[grimoire-witchcraft.git] / smgl / simpleinit-msb / patches / killall5.c.diff
blob5f74e435e585377b90272e57bdc3a08907e28d19
1 --- killall5.c 2001-09-26 12:59:46.000000000 +0200
2 +++ ../../sysvinit-2.86.ds1/src/killall5.c 2004-07-30 14:16:23.000000000 +0200
3 @@ -5,7 +5,7 @@
5 * pidof.c Tries to get the pid of the process[es] named.
7 - * Version: 2.81 31-Jul-2001 MvS
8 + * Version: 2.86 30-Jul-2004 MvS
10 * Usage: killall5 [-][signal]
11 * pidof [-s] [-o omitpid [-o omitpid]] program [program..]
12 @@ -20,7 +20,7 @@
13 * - swapped out programs pids are caught now
15 * This file is part of the sysvinit suite,
16 - * Copyright 1991-2001 Miquel van Smoorenburg.
17 + * Copyright 1991-2004 Miquel van Smoorenburg.
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 @@ -30,6 +30,7 @@
22 #include <sys/types.h>
23 #include <stdio.h>
24 #include <string.h>
25 +#include <errno.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/wait.h>
29 @@ -40,34 +41,43 @@
30 #include <getopt.h>
31 #include <stdarg.h>
33 -char *Version = "@(#)killall5 2.81 31-Jul-2001 miquels@cistron.nl";
34 +char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl";
36 +#define STATNAMELEN 15
38 /* Info about a process. */
39 -typedef struct _proc_
41 - char *fullname; /* Name as found out from argv[0] */
42 - char *basename; /* Only the part after the last / */
43 - char *statname; /* the statname without braces */
44 - ino_t ino; /* Inode number */
45 - dev_t dev; /* Device it is on */
46 - pid_t pid; /* Process ID. */
47 - int sid; /* Session ID. */
48 - struct _proc_ *next; /* Pointer to next struct. */
49 +typedef struct proc {
50 + char *argv0; /* Name as found out from argv[0] */
51 + char *argv0base; /* `basename argv[1]` */
52 + char *argv1; /* Name as found out from argv[1] */
53 + char *argv1base; /* `basename argv[1]` */
54 + char *statname; /* the statname without braces */
55 + ino_t ino; /* Inode number */
56 + dev_t dev; /* Device it is on */
57 + pid_t pid; /* Process ID. */
58 + int sid; /* Session ID. */
59 + int kernel; /* Kernel thread or zombie. */
60 + struct proc *next; /* Pointer to next struct. */
61 } PROC;
63 /* pid queue */
64 -typedef struct _pidq_ {
65 - struct _pidq_ *front;
66 - struct _pidq_ *next;
67 - struct _pidq_ *rear;
68 - PROC *proc;
70 +typedef struct pidq {
71 + PROC *proc;
72 + struct pidq *next;
73 } PIDQ;
75 +typedef struct {
76 + PIDQ *head;
77 + PIDQ *tail;
78 + PIDQ *next;
79 +} PIDQ_HEAD;
81 /* List of processes. */
82 PROC *plist;
84 -/* Did we stop a number of processes? */
85 -int stopped;
86 +/* Did we stop all processes ? */
87 +int sent_sigstop;
89 int scripts_too = 0;
91 @@ -85,7 +95,7 @@
92 void *p;
94 if ((p = malloc(bytes)) == NULL) {
95 - if (stopped) kill(-1, SIGCONT);
96 + if (sent_sigstop) kill(-1, SIGCONT);
97 nsyslog(LOG_ERR, "out of memory");
98 exit(1);
100 @@ -97,13 +107,14 @@
102 int mount_proc(void)
104 - struct stat st;
105 - int pid, wst;
106 - char *args[] = { "mount", "-t", "proc", "none", "/proc", NULL };
107 - int did_mount = 0;
108 + struct stat st;
109 + char *args[] = { "mount", "-t", "proc", "proc", "/proc", 0 };
110 + pid_t pid, rc;
111 + int wst;
112 + int did_mount = 0;
114 /* Stat /proc/version to see if /proc is mounted. */
115 - if (stat("/proc/version", &st) < 0) {
116 + if (stat("/proc/version", &st) < 0 && errno == ENOENT) {
118 /* It's not there, so mount it. */
119 if ((pid = fork()) < 0) {
120 @@ -113,7 +124,6 @@
121 if (pid == 0) {
122 /* Try a few mount binaries. */
123 execv("/sbin/mount", args);
124 - execv("/etc/mount", args);
125 execv("/bin/mount", args);
127 /* Okay, I give up. */
128 @@ -121,9 +131,10 @@
129 exit(1);
131 /* Wait for child. */
132 - while (wait(&wst) != pid)
134 - if (WEXITSTATUS(wst) != 0)
135 + while ((rc = wait(&wst)) != pid)
136 + if (rc < 0 && errno == ECHILD)
137 + break;
138 + if (rc != pid || WEXITSTATUS(wst) != 0)
139 nsyslog(LOG_ERR, "mount returned non-zero exit status");
141 did_mount = 1;
142 @@ -131,28 +142,42 @@
144 /* See if mount succeeded. */
145 if (stat("/proc/version", &st) < 0) {
146 - nsyslog(LOG_ERR, "/proc not mounted, failed to mount.");
147 + if (errno == ENOENT)
148 + nsyslog(LOG_ERR, "/proc not mounted, failed to mount.");
149 + else
150 + nsyslog(LOG_ERR, "/proc unavailable.");
151 exit(1);
154 return did_mount;
157 +int readarg(FILE *fp, char *buf, int sz)
159 + int c = 0, f = 0;
161 + while (f < (sz-1) && (c = fgetc(fp)) != EOF && c)
162 + buf[f++] = c;
163 + buf[f] = 0;
165 + return (c == EOF && f == 0) ? c : f;
169 * Read the proc filesystem.
171 int readproc()
173 - DIR *dir;
174 - struct dirent *d;
175 - char path[256];
176 - char buf[256];
177 - char *s, *q;
178 - FILE *fp;
179 - int pid, f;
180 - PROC *p, *n;
181 - struct stat st;
182 - int c;
183 + DIR *dir;
184 + FILE *fp;
185 + PROC *p, *n;
186 + struct dirent *d;
187 + struct stat st;
188 + char path[256];
189 + char buf[256];
190 + char *s, *q;
191 + unsigned long startcode, endcode;
192 + int pid, f;
194 /* Open the /proc directory. */
195 if ((dir = opendir("/proc")) == NULL) {
196 @@ -164,7 +189,8 @@
197 n = plist;
198 for (p = plist; n; p = n) {
199 n = p->next;
200 - if (p->fullname) free(p->fullname);
201 + if (p->argv0) free(p->argv0);
202 + if (p->argv1) free(p->argv1);
203 free(p);
205 plist = NULL;
206 @@ -185,7 +211,7 @@
207 /* Read SID & statname from it. */
208 if ((fp = fopen(path, "r")) != NULL) {
209 buf[0] = 0;
210 - fgets(buf, 256, fp);
211 + fgets(buf, sizeof(buf), fp);
213 /* See if name starts with '(' */
214 s = buf;
215 @@ -212,14 +238,21 @@
216 p->statname = (char *)xmalloc(strlen(s)+1);
217 strcpy(p->statname, s);
219 - /* This could be replaced by getsid(pid) */
220 - if (sscanf(q, "%*c %*d %*d %d", &p->sid) != 1) {
221 + /* Get session, startcode, endcode. */
222 + startcode = endcode = 0;
223 + if (sscanf(q, "%*c %*d %*d %d %*d %*d %*u %*u "
224 + "%*u %*u %*u %*u %*u %*d %*d "
225 + "%*d %*d %*d %*d %*u %*u %*d "
226 + "%*u %lu %lu",
227 + &p->sid, &startcode, &endcode) != 3) {
228 p->sid = 0;
229 nsyslog(LOG_ERR, "can't read sid from %s\n",
230 path);
231 free(p);
232 continue;
234 + if (startcode == 0 && endcode == 0)
235 + p->kernel = 1;
236 fclose(fp);
237 } else {
238 /* Process disappeared.. */
239 @@ -227,24 +260,44 @@
240 continue;
243 - /* Now read argv[0] */
244 snprintf(path, sizeof(path), "/proc/%s/cmdline", d->d_name);
245 if ((fp = fopen(path, "r")) != NULL) {
246 - f = 0;
247 - while(f < 127 && (c = fgetc(fp)) != EOF && c)
248 - buf[f++] = c;
249 - buf[f++] = 0;
251 + /* Now read argv[0] */
252 + f = readarg(fp, buf, sizeof(buf));
254 + if (buf[0]) {
255 + /* Store the name into malloced memory. */
256 + p->argv0 = (char *)xmalloc(f + 1);
257 + strcpy(p->argv0, buf);
259 + /* Get a pointer to the basename. */
260 + p->argv0base = strrchr(p->argv0, '/');
261 + if (p->argv0base != NULL)
262 + p->argv0base++;
263 + else
264 + p->argv0base = p->argv0;
267 + /* And read argv[1] */
268 + while ((f = readarg(fp, buf, sizeof(buf))) != EOF)
269 + if (buf[0] != '-') break;
271 + if (buf[0]) {
272 + /* Store the name into malloced memory. */
273 + p->argv1 = (char *)xmalloc(f + 1);
274 + strcpy(p->argv1, buf);
276 + /* Get a pointer to the basename. */
277 + p->argv1base = strrchr(p->argv1, '/');
278 + if (p->argv1base != NULL)
279 + p->argv1base++;
280 + else
281 + p->argv1base = p->argv1;
284 fclose(fp);
286 - /* Store the name into malloced memory. */
287 - p->fullname = (char *)xmalloc(f);
288 - strcpy(p->fullname, buf);
290 - /* Get a pointer to the basename. */
291 - if ((p->basename = strrchr(p->fullname, '/')) != NULL)
292 - p->basename++;
293 - else
294 - p->basename = p->fullname;
295 } else {
296 /* Process disappeared.. */
297 free(p);
298 @@ -269,19 +322,18 @@
299 return 0;
302 -PIDQ *init_pid_q(PIDQ *q)
303 +PIDQ_HEAD *init_pid_q(PIDQ_HEAD *q)
305 - q->front = q->next = q->rear = NULL;
306 - q->proc = NULL;
307 + q->head = q->next = q->tail = NULL;
308 return q;
311 -int empty_q(PIDQ *q)
312 +int empty_q(PIDQ_HEAD *q)
314 - return (q->front == NULL);
315 + return (q->head == NULL);
318 -int add_pid_to_q(PIDQ *q, PROC *p)
319 +int add_pid_to_q(PIDQ_HEAD *q, PROC *p)
321 PIDQ *tmp;
323 @@ -291,23 +343,23 @@
324 tmp->next = NULL;
326 if (empty_q(q)) {
327 - q->front = tmp;
328 - q->rear = tmp;
329 + q->head = tmp;
330 + q->tail = tmp;
331 } else {
332 - q->rear->next = tmp;
333 - q->rear = tmp;
334 + q->tail->next = tmp;
335 + q->tail = tmp;
337 return 0;
340 -PROC *get_next_from_pid_q(PIDQ *q)
341 +PROC *get_next_from_pid_q(PIDQ_HEAD *q)
343 - PROC *p;
344 - PIDQ *tmp = q->front;
345 + PROC *p;
346 + PIDQ *tmp = q->head;
348 if (!empty_q(q)) {
349 - p = q->front->proc;
350 - q->front = tmp->next;
351 + p = q->head->proc;
352 + q->head = tmp->next;
353 free(tmp);
354 return p;
356 @@ -316,15 +368,15 @@
359 /* Try to get the process ID of a given process. */
360 -PIDQ *pidof(char *prog)
361 +PIDQ_HEAD *pidof(char *prog)
363 - struct stat st;
364 - int dostat = 0;
365 - PROC *p;
366 - PIDQ *q;
367 - char *s;
368 - int foundone = 0;
369 - int ok = 0;
370 + PROC *p;
371 + PIDQ_HEAD *q;
372 + struct stat st;
373 + char *s;
374 + int dostat = 0;
375 + int foundone = 0;
376 + int ok = 0;
378 /* Try to stat the executable. */
379 if (prog[0] == '/' && stat(prog, &st) == 0) dostat++;
380 @@ -335,7 +387,7 @@
381 else
382 s++;
384 - q = (PIDQ *)xmalloc(sizeof(PIDQ));
385 + q = (PIDQ_HEAD *)xmalloc(sizeof(PIDQ_HEAD));
386 q = init_pid_q(q);
388 /* First try to find a match based on dev/ino pair. */
389 @@ -349,20 +401,31 @@
392 /* If we didn't find a match based on dev/ino, try the name. */
393 - if (!foundone) {
394 - for (p = plist; p; p = p->next) {
395 - ok = 0;
396 + if (!foundone) for (p = plist; p; p = p->next) {
397 + ok = 0;
399 - ok += (strcmp(p->fullname, prog) == 0);
400 - ok += (strcmp(p->basename, s) == 0);
402 - if (p->fullname[0] == 0 ||
403 - strchr(p->fullname, ' ') ||
404 - scripts_too)
405 - ok += (strcmp(p->statname, s) == 0);
406 + /* Compare name (both basename and full path) */
407 + ok += (p->argv0 && strcmp(p->argv0, prog) == 0);
408 + ok += (p->argv0 && strcmp(p->argv0base, s) == 0);
410 + /* For scripts, compare argv[1] as well. */
411 + if (scripts_too && p->argv1 &&
412 + !strncmp(p->statname, p->argv1base, STATNAMELEN)) {
413 + ok += (strcmp(p->argv1, prog) == 0);
414 + ok += (strcmp(p->argv1base, s) == 0);
417 - if (ok) add_pid_to_q(q, p);
418 + /*
419 + * if we have a space in argv0, process probably
420 + * used setproctitle so try statname.
421 + */
422 + if (strlen(s) <= STATNAMELEN &&
423 + (p->argv0 == NULL ||
424 + p->argv0[0] == 0 ||
425 + strchr(p->argv0, ' '))) {
426 + ok += (strcmp(p->statname, s) == 0);
428 + if (ok) add_pid_to_q(q, p);
431 return q;
432 @@ -407,12 +470,12 @@
434 int main_pidof(int argc, char **argv)
436 - PROC *p;
437 - PIDQ *q;
438 - int f;
439 - int first = 1;
440 - int i,oind, opt, flags = 0;
441 - pid_t opid[PIDOF_OMITSZ], spid;
442 + PIDQ_HEAD *q;
443 + PROC *p;
444 + pid_t opid[PIDOF_OMITSZ], spid;
445 + int f;
446 + int first = 1;
447 + int i, oind, opt, flags = 0;
449 for (oind = PIDOF_OMITSZ-1; oind > 0; oind--)
450 opid[oind] = 0;
451 @@ -495,9 +558,9 @@
452 /* Main for either killall or pidof. */
453 int main(int argc, char **argv)
455 - PROC *p;
456 - int pid, sid = -1;
457 - int sig = SIGKILL;
458 + PROC *p;
459 + int pid, sid = -1;
460 + int sig = SIGKILL;
462 /* Get program name. */
463 if ((progname = strrchr(argv[0], '/')) == NULL)
464 @@ -508,9 +571,6 @@
465 /* Now connect to syslog. */
466 openlog(progname, LOG_CONS|LOG_PID, LOG_DAEMON);
468 - /* First get the /proc filesystem online. */
469 - mount_proc();
471 /* Were we called as 'pidof' ? */
472 if (strcmp(progname, "pidof") == 0)
473 return main_pidof(argc, argv);
474 @@ -522,6 +582,9 @@
475 if ((sig = atoi(argv[1])) <= 0 || sig > 31) usage();
478 + /* First get the /proc filesystem online. */
479 + mount_proc();
482 * Ignoring SIGKILL and SIGSTOP do not make sense, but
483 * someday kill(-1, sig) might kill ourself if we don't
484 @@ -534,24 +597,19 @@
486 /* Now stop all processes. */
487 kill(-1, SIGSTOP);
488 - stopped = 1;
489 + sent_sigstop = 1;
491 - /* Find out our own 'sid'. */
492 + /* Read /proc filesystem */
493 if (readproc() < 0) {
494 kill(-1, SIGCONT);
495 exit(1);
498 - pid = getpid();
499 - for (p = plist; p; p = p->next)
500 - if (p->pid == pid) {
501 - sid = p->sid;
502 - break;
505 /* Now kill all processes except our session. */
506 + sid = (int)getsid(0);
507 + pid = (int)getpid();
508 for (p = plist; p; p = p->next)
509 - if (p->pid != pid && p->sid != sid)
510 + if (p->pid != pid && p->sid != sid && !p->kernel)
511 kill(p->pid, sig);
513 /* And let them continue. */