kill.c (2415B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <sys/wait.h> 3 4 #include <ctype.h> 5 #include <limits.h> 6 #include <signal.h> 7 #include <stdio.h> 8 #include <string.h> 9 #include <strings.h> 10 11 #include "util.h" 12 13 struct { 14 const char *name; 15 const int sig; 16 } sigs[] = { 17 { "0", 0 }, 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 const char * 26 sig2name(const int sig) 27 { 28 size_t i; 29 30 for (i = 0; i < LEN(sigs); i++) 31 if (sigs[i].sig == sig) 32 return sigs[i].name; 33 eprintf("%d: bad signal number\n", sig); 34 35 return NULL; /* not reached */ 36 } 37 38 int 39 name2sig(const char *name) 40 { 41 size_t i; 42 43 for (i = 0; i < LEN(sigs); i++) 44 if (!strcasecmp(sigs[i].name, name)) 45 return sigs[i].sig; 46 eprintf("%s: bad signal name\n", name); 47 48 return -1; /* not reached */ 49 } 50 51 static void 52 usage(void) 53 { 54 eprintf("usage: %s [-s signame | -num | -signame] pid ...\n" 55 " %s -l [num]\n", argv0, argv0); 56 } 57 58 int 59 main(int argc, char *argv[]) 60 { 61 pid_t pid; 62 size_t i; 63 int ret = 0, sig = SIGTERM; 64 65 argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0; 66 67 if (!argc) 68 usage(); 69 70 if ((*argv)[0] == '-') { 71 switch ((*argv)[1]) { 72 case 'l': 73 if ((*argv)[2]) 74 goto longopt; 75 argc--, argv++; 76 if (!argc) { 77 for (i = 0; i < LEN(sigs); i++) 78 puts(sigs[i].name); 79 } else if (argc == 1) { 80 sig = estrtonum(*argv, 0, INT_MAX); 81 if (sig > 128) 82 sig = WTERMSIG(sig); 83 puts(sig2name(sig)); 84 } else { 85 usage(); 86 } 87 return fshut(stdout, "<stdout>"); 88 case 's': 89 if ((*argv)[2]) 90 goto longopt; 91 argc--, argv++; 92 if (!argc) 93 usage(); 94 sig = name2sig(*argv); 95 argc--, argv++; 96 break; 97 case '-': 98 if ((*argv)[2]) 99 goto longopt; 100 argc--, argv++; 101 break; 102 default: 103 longopt: 104 /* XSI-extensions -argnum and -argname*/ 105 if (isdigit((*argv)[1])) { 106 sig = estrtonum((*argv) + 1, 0, INT_MAX); 107 sig2name(sig); 108 } else { 109 sig = name2sig((*argv) + 1); 110 } 111 argc--, argv++; 112 } 113 } 114 115 if (argc && !strcmp(*argv, "--")) 116 argc--, argv++; 117 118 if (!argc) 119 usage(); 120 121 for (; *argv; argc--, argv++) { 122 pid = estrtonum(*argv, INT_MIN, INT_MAX); 123 if (kill(pid, sig) < 0) { 124 weprintf("kill %d:", pid); 125 ret = 1; 126 } 127 } 128 129 return ret; 130 }