kill.c (2706B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <ctype.h> 3 #include <errno.h> 4 #include <signal.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <strings.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 12 #include "util.h" 13 14 struct { 15 const char *name; 16 int sig; 17 } sigs[] = { 18 { "0", 0 }, 19 #define SIG(n) { #n, SIG##n } 20 SIG(ABRT), SIG(ALRM), SIG(BUS), SIG(CHLD), SIG(CONT), SIG(FPE), SIG(HUP), 21 SIG(ILL), SIG(INT), SIG(KILL), SIG(PIPE), SIG(QUIT), SIG(SEGV), SIG(STOP), 22 SIG(TERM), SIG(TSTP), SIG(TTIN), SIG(TTOU), SIG(USR1), SIG(USR2), SIG(URG), 23 #undef SIG 24 }; 25 26 const char *sig2name(int); 27 int name2sig(const char *); 28 29 static void 30 usage(void) 31 { 32 weprintf("usage: %s [-s signame | -signum | -signame] pid ...\n", argv0); 33 weprintf(" %s -l [exit_status]\n", argv0); 34 exit(1); 35 } 36 37 int 38 main(int argc, char *argv[]) 39 { 40 char *end; 41 int ret = 0; 42 int sig = SIGTERM; 43 pid_t pid; 44 size_t i; 45 46 argv0 = argv[0]; 47 if (argc < 2) 48 usage(); 49 50 argc--, argv++; 51 if (strcmp(argv[0], "-l") == 0) { 52 argc--, argv++; 53 if (argc == 0) { 54 for (i = 0; i < LEN(sigs); i++) 55 puts(sigs[i].name); 56 exit(0); 57 } else if (argc > 1) 58 usage(); 59 errno = 0; 60 sig = strtol(argv[0], &end, 10); 61 if (*end != '\0' || errno != 0) 62 eprintf("%s: bad signal number\n", argv[0]); 63 if (sig > 128) 64 sig = WTERMSIG(sig); 65 puts(sig2name(sig)); 66 exit(0); 67 } 68 69 if (strcmp(argv[0], "-s") == 0) { 70 argc--, argv++; 71 if (argc == 0) 72 usage(); 73 sig = name2sig(argv[0]); 74 argc--, argv++; 75 } else if (argv[0][0] == '-') { 76 if (isdigit(argv[0][1])) { 77 /* handle XSI extension -signum */ 78 errno = 0; 79 sig = strtol(&argv[0][1], &end, 10); 80 if (*end != '\0' || errno != 0) 81 eprintf("%s: bad signal number\n", &argv[0][1]); 82 sig2name(sig); 83 argc--, argv++; 84 } else if (argv[0][1] != '-') { 85 /* handle XSI extension -signame */ 86 sig = name2sig(&argv[0][1]); 87 argc--, argv++; 88 } 89 } 90 91 if (argc > 0 && strcmp(argv[0], "--") == 0) 92 argc--, argv++; 93 94 if (argc == 0) 95 usage(); 96 97 for (; argc; argc--, argv++) { 98 errno = 0; 99 pid = strtol(argv[0], &end, 10); 100 if (*end == '\0' && errno == 0) { 101 if (kill(pid, sig) < 0) { 102 weprintf("kill %d:", pid); 103 ret = 1; 104 } 105 } else { 106 weprintf("%s: bad pid\n", argv[0]); 107 ret = 1; 108 } 109 } 110 111 exit(ret); 112 } 113 114 const char * 115 sig2name(int sig) 116 { 117 size_t i; 118 119 for (i = 0; i < LEN(sigs); i++) 120 if (sigs[i].sig == sig) 121 return sigs[i].name; 122 eprintf("%d: bad signal number\n", sig); 123 /* unreachable */ 124 return NULL; 125 } 126 127 int 128 name2sig(const char *name) 129 { 130 size_t i; 131 132 for (i = 0; i < LEN(sigs); i++) 133 if (strcasecmp(sigs[i].name, name) == 0) 134 return sigs[i].sig; 135 eprintf("%s: bad signal name\n", name); 136 /* unreachable */ 137 return -1; 138 }