xref: /openbsd-src/bin/kill/kill.c (revision 0b7734b3d77bb9b21afec6f4621cae6c805dbd45)
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