xref: /openbsd-src/bin/kill/kill.c (revision 7bbe964f6b7d22ad07ca46292495604f942eba4e)
1 /*	$OpenBSD: kill.c,v 1.9 2009/10/27 23:59:21 deraadt 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 
41 extern	char *__progname;
42 
43 void nosig(char *);
44 void printsignals(FILE *);
45 int signame_to_signum(char *);
46 void usage(void);
47 
48 int
49 main(int argc, char *argv[])
50 {
51 	int errors, numsig, pid;
52 	char *ep;
53 
54 	if (argc < 2)
55 		usage();
56 
57 	numsig = SIGTERM;
58 
59 	argc--, argv++;
60 	if (!strcmp(*argv, "-l")) {
61 		argc--, argv++;
62 		if (argc > 1)
63 			usage();
64 		if (argc == 1) {
65 			if (!isdigit(**argv))
66 				usage();
67 			numsig = strtol(*argv, &ep, 10);
68 			if (!*argv || *ep)
69 				errx(1, "illegal signal number: %s", *argv);
70 			if (numsig >= 128)
71 				numsig -= 128;
72 			if (numsig <= 0 || numsig >= NSIG)
73 				nosig(*argv);
74 			printf("%s\n", sys_signame[numsig]);
75 			exit(0);
76 		}
77 		printsignals(stdout);
78 		exit(0);
79 	}
80 
81 	if (!strcmp(*argv, "-s")) {
82 		argc--, argv++;
83 		if (argc < 1) {
84 			warnx("option requires an argument -- s");
85 			usage();
86 		}
87 		if (strcmp(*argv, "0")) {
88 			if ((numsig = signame_to_signum(*argv)) < 0)
89 				nosig(*argv);
90 		} else
91 			numsig = 0;
92 		argc--, argv++;
93 	} else if (**argv == '-') {
94 		++*argv;
95 		if (isalpha(**argv)) {
96 			if ((numsig = signame_to_signum(*argv)) < 0)
97 				nosig(*argv);
98 		} else if (isdigit(**argv)) {
99 			numsig = strtol(*argv, &ep, 10);
100 			if (*ep)
101 				errx(1, "illegal signal number: %s", *argv);
102 			if (numsig < 0 || numsig >= NSIG)
103 				nosig(*argv);
104 		} else
105 			nosig(*argv);
106 		argc--, argv++;
107 	}
108 
109 	if (argc == 0)
110 		usage();
111 
112 	for (errors = 0; argc; argc--, argv++) {
113 		pid = strtol(*argv, &ep, 10);
114 		if (!**argv || *ep) {
115 			warnx("illegal process id: %s", *argv);
116 			errors = 1;
117 		} else if (kill(pid, numsig) == -1) {
118 			warn("%s", *argv);
119 			errors = 1;
120 		}
121 	}
122 
123 	exit(errors);
124 }
125 
126 int
127 signame_to_signum(char *sig)
128 {
129 	int n;
130 
131 	if (!strncasecmp(sig, "sig", 3))
132 		sig += 3;
133 	for (n = 1; n < NSIG; n++) {
134 		if (!strcasecmp(sys_signame[n], sig))
135 			return (n);
136 	}
137 	return (-1);
138 }
139 
140 void
141 nosig(char *name)
142 {
143 
144 	warnx("unknown signal %s; valid signals:", name);
145 	printsignals(stderr);
146 	exit(1);
147 }
148 
149 void
150 printsignals(FILE *fp)
151 {
152 	int n;
153 
154 	for (n = 1; n < NSIG; n++) {
155 		(void)fprintf(fp, "%s", sys_signame[n]);
156 		if (n == (NSIG / 2) || n == (NSIG - 1))
157 			(void)fprintf(fp, "\n");
158 		else
159 			(void)fprintf(fp, " ");
160 	}
161 }
162 
163 void
164 usage(void)
165 {
166 	(void)fprintf(stderr, "usage: %s [-s signal_name] pid ...\n",
167 	    __progname);
168 	(void)fprintf(stderr, "       %s -l [exit_status]\n", __progname);
169 	(void)fprintf(stderr, "       %s -signal_name pid ...\n",
170 	    __progname);
171 	(void)fprintf(stderr, "       %s -signal_number pid ...\n",
172 	    __progname);
173 	exit(1);
174 }
175