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