ubase

suckless linux base utils
git clone git://git.2f30.org/ubase.git
Log | Files | Refs | README | LICENSE

killall5.c (2155B)


      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 struct pidentry {
     26 	pid_t pid;
     27 	SLIST_ENTRY(pidentry) entry;
     28 };
     29 
     30 static SLIST_HEAD(, pidentry) omitpid_head;
     31 
     32 static void
     33 usage(void)
     34 {
     35 	eprintf("usage: %s [-o pid1,pid2,..,pidN] [-s signal]\n", argv0);
     36 }
     37 
     38 int
     39 main(int argc, char *argv[])
     40 {
     41 	struct pidentry *pe;
     42 	struct dirent *entry;
     43 	DIR *dp;
     44 	char *p, *arg = NULL;
     45 	char *end, *v;
     46 	int oflag = 0;
     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 	SLIST_INIT(&omitpid_head);
     75 
     76 	if (oflag) {
     77 		for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
     78 			pe = emalloc(sizeof(*pe));
     79 			pe->pid = estrtol(p, 10);
     80 			SLIST_INSERT_HEAD(&omitpid_head, pe, entry);
     81 		}
     82 	}
     83 
     84 	if (sig != SIGSTOP && sig != SIGCONT)
     85 		kill(-1, SIGSTOP);
     86 
     87 	if (!(dp = opendir("/proc")))
     88 		eprintf("opendir /proc:");
     89 	while ((entry = readdir(dp))) {
     90 		if (pidfile(entry->d_name) == 0)
     91 			continue;
     92 		pid = estrtol(entry->d_name, 10);
     93 		if (pid == 1 || pid == getpid() ||
     94 		    getsid(pid) == getsid(0) || getsid(pid) == 0)
     95 			continue;
     96 		if (oflag == 1) {
     97 			SLIST_FOREACH(pe, &omitpid_head, entry)
     98 				if (pe->pid == pid)
     99 					break;
    100 			if (pe)
    101 				continue;
    102 		}
    103 		kill(pid, sig);
    104 	}
    105 	closedir(dp);
    106 
    107 	if (sig != SIGSTOP && sig != SIGCONT)
    108 		kill(-1, SIGCONT);
    109 
    110 	return 0;
    111 }