1/* $OpenBSD: kill.c,v 1.14 2017/03/29 22:40:15 millert 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 <limits.h> 37#include <signal.h> 38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41#include <unistd.h> 42 43extern char *__progname; 44 45void nosig(char *); 46void printsignals(FILE *); 47int signame_to_signum(char *); 48void usage(void); 49 50int 51main(int argc, char *argv[]) 52{ 53 int errors, numsig, pid; 54 const char *errstr; 55 56 if (pledge("stdio proc", NULL) == -1) 57 err(1, "pledge"); 58 59 if (argc < 2) 60 usage(); 61 62 numsig = SIGTERM; 63 64 argc--, argv++; 65 if (!strcmp(*argv, "-l")) { 66 argc--, argv++; 67 if (argc > 0 && !strcmp(*argv, "--")) 68 argc--, argv++; 69 if (argc > 1) 70 usage(); 71 if (argc == 1) { 72 if (!isdigit((unsigned char)**argv)) 73 usage(); 74 numsig = strtonum(*argv, 1, NSIG + 127, &errstr); 75 if (errstr != NULL) { 76 if (errno == ERANGE) 77 nosig(*argv); 78 errx(1, "illegal signal number: %s", *argv); 79 } 80 printf("%s\n", sys_signame[numsig & 127]); 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 = strtonum(*argv, 0, NSIG - 1, &errstr); 109 if (errstr != NULL) { 110 if (errno == ERANGE) 111 nosig(*argv); 112 errx(1, "illegal signal number: %s", *argv); 113 } 114 } else 115 nosig(*argv); 116 } 117 argc--, argv++; 118 } 119 120 if (argc == 0) 121 usage(); 122 123 for (errors = 0; argc; argc--, argv++) { 124 pid = strtonum(*argv, -INT_MAX, INT_MAX, &errstr); 125 if (errstr != NULL) { 126 warnx("illegal process id: %s", *argv); 127 errors = 1; 128 } else if (kill(pid, numsig) == -1) { 129 warn("%s", *argv); 130 errors = 1; 131 } 132 } 133 134 exit(errors); 135} 136 137int 138signame_to_signum(char *sig) 139{ 140 int n; 141 142 if (!strncasecmp(sig, "sig", 3)) 143 sig += 3; 144 for (n = 1; n < NSIG; n++) { 145 if (!strcasecmp(sys_signame[n], sig)) 146 return (n); 147 } 148 return (-1); 149} 150 151void 152nosig(char *name) 153{ 154 155 warnx("unknown signal %s; valid signals:", name); 156 printsignals(stderr); 157 exit(1); 158} 159 160void 161printsignals(FILE *fp) 162{ 163 int n; 164 165 for (n = 1; n < NSIG; n++) { 166 (void)fprintf(fp, "%s", sys_signame[n]); 167 if (n == (NSIG / 2) || n == (NSIG - 1)) 168 (void)fprintf(fp, "\n"); 169 else 170 (void)fprintf(fp, " "); 171 } 172} 173 174void 175usage(void) 176{ 177 (void)fprintf(stderr, "usage: %s [-s signal_name] pid ...\n", 178 __progname); 179 (void)fprintf(stderr, " %s -l [exit_status]\n", __progname); 180 (void)fprintf(stderr, " %s -signal_name pid ...\n", 181 __progname); 182 (void)fprintf(stderr, " %s -signal_number pid ...\n", 183 __progname); 184 exit(1); 185} 186