URI: 
       killall5.c - ubase - suckless linux base utils
  HTML git clone git://git.suckless.org/ubase
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR 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 }