1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 char copyright[] = 36 "@(#) Copyright (c) 1988 Regents of the University of California.\n\ 37 All rights reserved.\n"; 38 #endif /* not lint */ 39 40 #ifndef lint 41 static char sccsid[] = "@(#)kill.c 5.3 (Berkeley) 7/1/91"; 42 static char rcsid[] = "$Header: /cvsroot/src/bin/kill/kill.c,v 1.4 1993/07/22 16:42:18 jtc Exp $"; 43 #endif /* not lint */ 44 45 #include <signal.h> 46 #include <errno.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <ctype.h> 51 52 static char *signals[] = { 53 "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", /* 1 - 6 */ 54 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 55 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 56 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 57 "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1", /* 25 - 30 */ 58 "USR2", NULL, /* 31 - 32 */ 59 }; 60 61 main(argc, argv) 62 int argc; 63 char **argv; 64 { 65 register int errors, numsig, pid; 66 register char **p; 67 char *ep; 68 69 if (argc < 2) 70 usage(); 71 72 numsig = SIGTERM; 73 argc--, argv++; 74 if (strcmp(*argv, "-l") == 0) { 75 if (argc > 2) { 76 usage (); 77 /* NOTREACHED */ 78 } 79 if (argc == 2) { 80 argv++; 81 if (isdigit(**argv)) { 82 numsig = strtol(*argv, &ep, 10); 83 if (*argv && !*ep) { 84 if (numsig > 0 && numsig < NSIG) { 85 printsig (numsig); 86 exit (0); 87 } 88 89 numsig -= 128; 90 if (numsig > 0 && numsig < NSIG) { 91 printsig (numsig); 92 exit (0); 93 } 94 } 95 (void)fprintf(stderr, 96 "kill: illegal signal number %s\n", *argv); 97 exit(1); 98 } 99 usage (); 100 /* NOTREACHED */ 101 } 102 printsignals(stdout); 103 exit(0); 104 } else if (strcmp(*argv, "-s") == 0) { 105 if (argc < 2) { 106 (void)fprintf(stderr, 107 "kill: option requires an argument -- s\n"); 108 usage(); 109 } 110 argc--,argv++; 111 if (strcmp (*argv, "0") == 0) { 112 numsig = 0; 113 } else { 114 if ((numsig = signame_to_signum (*argv)) < 0) { 115 nosig(*argv); 116 /* NOTREACHED */ 117 } 118 } 119 argc--,argv++; 120 } else if (**argv == '-') { 121 ++*argv; 122 if (isalpha(**argv)) { 123 if ((numsig = signame_to_signum (*argv)) < 0) { 124 nosig(*argv); 125 /* NOTREACHED */ 126 } 127 } else if (isdigit(**argv)) { 128 numsig = strtol(*argv, &ep, 10); 129 if (!*argv || *ep) { 130 (void)fprintf(stderr, 131 "kill: illegal signal number %s\n", *argv); 132 exit(1); 133 } 134 if (numsig <= 0 || numsig >= NSIG) { 135 nosig(*argv); 136 /* NOTREACHED */ 137 } 138 } else 139 nosig(*argv); 140 argc--,argv++; 141 } 142 143 if (!*argv) 144 usage(); 145 146 for (errors = 0; *argv; ++argv) { 147 pid = strtol(*argv, &ep, 10); 148 if (!*argv || *ep) { 149 (void)fprintf(stderr, 150 "kill: illegal process id %s\n", *argv); 151 continue; 152 } 153 if (kill(pid, numsig) == -1) { 154 (void)fprintf(stderr, 155 "kill: %s: %s\n", *argv, strerror(errno)); 156 errors = 1; 157 } 158 } 159 exit(errors); 160 } 161 162 int 163 signame_to_signum (sig) 164 char *sig; 165 { 166 char **p; 167 168 if (!strncasecmp(sig, "sig", 3)) 169 sig += 3; 170 for (p = signals; *p; ++p) { 171 if (!strcasecmp(*p, sig)) { 172 return p - signals + 1; 173 } 174 } 175 return -1; 176 } 177 178 nosig(name) 179 char *name; 180 { 181 (void)fprintf(stderr, 182 "kill: unknown signal %s; valid signals:\n", name); 183 printsignals(stderr); 184 exit(1); 185 } 186 187 printsig(sig) 188 int sig; 189 { 190 printf ("%s\n", signals[sig - 1]); 191 } 192 193 printsignals(fp) 194 FILE *fp; 195 { 196 register char **p = signals;; 197 198 /* From POSIX 1003.2, Draft 11.2: 199 When the -l option is specified, the symbolic name of each 200 signal shall be written in the following format: 201 "%s%c", <signal_name>, <separator> 202 where the <signal_name> is in uppercase, without the SIG prefix, 203 and the <separator> shall either be a <newline> or a <space>. 204 For the last signal written, <separator> shall be a <newline> */ 205 206 /* This looses if the signals array is empty; But, since it 207 will "never happen", there is no need to add wrap this 208 in a conditional that will always succeed. */ 209 (void)fprintf(fp, "%s", *p); 210 211 for (++p ; *p; ++p) { 212 (void)fprintf(fp, " %s", *p); 213 } 214 (void)fprintf(fp, "\n"); 215 } 216 217 usage() 218 { 219 (void)fprintf(stderr, "usage: kill [-s signal_name] pid ...\n"); 220 (void)fprintf(stderr, " kill -l [exit_status]\n"); 221 (void)fprintf(stderr, "obsolete usage:\n"); 222 (void)fprintf(stderr, " kill -signal_name pid ...\n"); 223 (void)fprintf(stderr, " kill -signal_number pid ...\n"); 224 exit(1); 225 } 226