morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base.git
Log | Files | Refs

killall5.c (2295B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <dirent.h>
      3 #include <limits.h>
      4 #include <signal.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <unistd.h>
      9 
     10 #include "proc.h"
     11 #include "queue.h"
     12 #include "util.h"
     13 
     14 struct {
     15 	const char *name;
     16 	int sig;
     17 } sigs[] = {
     18 #define SIG(n) { #n, SIG##n }
     19 	SIG(ABRT), SIG(ALRM), SIG(BUS),  SIG(CHLD), SIG(CONT), SIG(FPE),  SIG(HUP),
     20 	SIG(ILL),  SIG(INT),  SIG(KILL), SIG(PIPE), SIG(QUIT), SIG(SEGV), SIG(STOP),
     21 	SIG(TERM), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2), SIG(URG),
     22 #undef SIG
     23 };
     24 
     25 static void
     26 usage(void)
     27 {
     28 	eprintf("usage: %s [-o pid1,pid2,..,pidN] [-s signal]\n", argv0);
     29 }
     30 
     31 struct pidentry {
     32 	pid_t pid;
     33 	TAILQ_ENTRY(pidentry) entry;
     34 };
     35 
     36 static TAILQ_HEAD(omitpid_head, pidentry) omitpid_head;
     37 
     38 int
     39 main(int argc, char *argv[])
     40 {
     41 	struct pidentry *pe, *tmp;
     42 	int oflag = 0;
     43 	char *p, *arg = NULL;
     44 	DIR *dp;
     45 	struct dirent *entry;
     46 	char *end, *v;
     47 	int sig = SIGTERM;
     48 	pid_t pid;
     49 	size_t i;
     50 
     51 	ARGBEGIN {
     52 	case 's':
     53 		v = EARGF(usage());
     54 		sig = strtol(v, &end, 0);
     55 		if (*end == '\0')
     56 			break;
     57 		for (i = 0; i < LEN(sigs); i++) {
     58 			if (strcasecmp(v, sigs[i].name) == 0) {
     59 				sig = sigs[i].sig;
     60 				break;
     61 			}
     62 		}
     63 		if (i == LEN(sigs))
     64 			eprintf("%s: unknown signal\n", v);
     65 		break;
     66 	case 'o':
     67 		oflag = 1;
     68 		arg = EARGF(usage());
     69 		break;
     70 	default:
     71 		usage();
     72 	} ARGEND;
     73 
     74 	TAILQ_INIT(&omitpid_head);
     75 
     76 	for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
     77 		pe = emalloc(sizeof(*pe));
     78 		pe->pid = estrtol(p, 10);
     79 		TAILQ_INSERT_TAIL(&omitpid_head, pe, entry);
     80 	}
     81 
     82 	if (sig != SIGSTOP && sig != SIGCONT)
     83 		kill(-1, SIGSTOP);
     84 
     85 	if (!(dp = opendir("/proc")))
     86 		eprintf("opendir /proc:");
     87 	while ((entry = readdir(dp))) {
     88 		if (pidfile(entry->d_name) == 0)
     89 			continue;
     90 		pid = estrtol(entry->d_name, 10);
     91 		if (pid == 1 || pid == getpid() ||
     92 		    getsid(pid) == getsid(0) || getsid(pid) == 0)
     93 			continue;
     94 		if (oflag == 1) {
     95 			TAILQ_FOREACH(pe, &omitpid_head, entry)
     96 				if (pe->pid == pid)
     97 					break;
     98 			if (pe)
     99 				continue;
    100 		}
    101 		kill(pid, sig);
    102 	}
    103 	closedir(dp);
    104 
    105 	if (sig != SIGSTOP && sig != SIGCONT)
    106 		kill(-1, SIGCONT);
    107 
    108 	for (pe = TAILQ_FIRST(&omitpid_head); pe; pe = tmp) {
    109 		tmp = TAILQ_NEXT(pe, entry);
    110 		TAILQ_REMOVE(&omitpid_head, pe, entry);
    111 		free(pe);
    112 	}
    113 
    114 	return 0;
    115 }