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