1 /* $OpenBSD: kill.c,v 1.13 2015/10/10 21:15:25 doug Exp $ */ 2 /* $NetBSD: kill.c,v 1.11 1995/09/07 06:30:27 jtc Exp $ */ 3 4 /* 5 * Copyright (c) 1988, 1993, 1994 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <ctype.h> 34 #include <err.h> 35 #include <errno.h> 36 #include <signal.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 42 extern char *__progname; 43 44 void nosig(char *); 45 void printsignals(FILE *); 46 int signame_to_signum(char *); 47 void usage(void); 48 49 int 50 main(int argc, char *argv[]) 51 { 52 int errors, numsig, pid; 53 char *ep; 54 55 if (pledge("stdio proc", NULL) == -1) 56 err(1, "pledge"); 57 58 if (argc < 2) 59 usage(); 60 61 numsig = SIGTERM; 62 63 argc--, argv++; 64 if (!strcmp(*argv, "-l")) { 65 argc--, argv++; 66 if (argc > 0 && !strcmp(*argv, "--")) 67 argc--, argv++; 68 if (argc > 1) 69 usage(); 70 if (argc == 1) { 71 if (!isdigit((unsigned char)**argv)) 72 usage(); 73 numsig = strtol(*argv, &ep, 10); 74 if (*ep) 75 errx(1, "illegal signal number: %s", *argv); 76 if (numsig >= 128) 77 numsig -= 128; 78 if (numsig <= 0 || numsig >= NSIG) 79 nosig(*argv); 80 printf("%s\n", sys_signame[numsig]); 81 exit(0); 82 } 83 printsignals(stdout); 84 exit(0); 85 } 86 87 if (!strcmp(*argv, "-s")) { 88 argc--, argv++; 89 if (argc > 0 && !strcmp(*argv, "--")) 90 argc--, argv++; 91 if (argc < 1) { 92 warnx("option requires an argument -- s"); 93 usage(); 94 } 95 if (strcmp(*argv, "0")) { 96 if ((numsig = signame_to_signum(*argv)) < 0) 97 nosig(*argv); 98 } else 99 numsig = 0; 100 argc--, argv++; 101 } else if (**argv == '-') { 102 if (strcmp(*argv, "--")) { 103 ++*argv; 104 if (isalpha((unsigned char)**argv)) { 105 if ((numsig = signame_to_signum(*argv)) < 0) 106 nosig(*argv); 107 } else if (isdigit((unsigned char)**argv)) { 108 numsig = strtol(*argv, &ep, 10); 109 if (*ep) 110 errx(1, "illegal signal number: %s", *argv); 111 if (numsig < 0 || numsig >= NSIG) 112 nosig(*argv); 113 } else 114 nosig(*argv); 115 } 116 argc--, argv++; 117 } 118 119 if (argc == 0) 120 usage(); 121 122 for (errors = 0; argc; argc--, argv++) { 123 pid = strtol(*argv, &ep, 10); 124 if (!**argv || *ep) { 125 warnx("illegal process id: %s", *argv); 126 errors = 1; 127 } else if (kill(pid, numsig) == -1) { 128 warn("%s", *argv); 129 errors = 1; 130 } 131 } 132 133 exit(errors); 134 } 135 136 int 137 signame_to_signum(char *sig) 138 { 139 int n; 140 141 if (!strncasecmp(sig, "sig", 3)) 142 sig += 3; 143 for (n = 1; n < NSIG; n++) { 144 if (!strcasecmp(sys_signame[n], sig)) 145 return (n); 146 } 147 return (-1); 148 } 149 150 void 151 nosig(char *name) 152 { 153 154 warnx("unknown signal %s; valid signals:", name); 155 printsignals(stderr); 156 exit(1); 157 } 158 159 void 160 printsignals(FILE *fp) 161 { 162 int n; 163 164 for (n = 1; n < NSIG; n++) { 165 (void)fprintf(fp, "%s", sys_signame[n]); 166 if (n == (NSIG / 2) || n == (NSIG - 1)) 167 (void)fprintf(fp, "\n"); 168 else 169 (void)fprintf(fp, " "); 170 } 171 } 172 173 void 174 usage(void) 175 { 176 (void)fprintf(stderr, "usage: %s [-s signal_name] pid ...\n", 177 __progname); 178 (void)fprintf(stderr, " %s -l [exit_status]\n", __progname); 179 (void)fprintf(stderr, " %s -signal_name pid ...\n", 180 __progname); 181 (void)fprintf(stderr, " %s -signal_number pid ...\n", 182 __progname); 183 exit(1); 184 } 185