kill.c revision 216629
1280849Scy/*-
2280849Scy * Copyright (c) 1988, 1993, 1994
3280849Scy *	The Regents of the University of California.  All rights reserved.
4280849Scy *
5280849Scy * Redistribution and use in source and binary forms, with or without
6280849Scy * modification, are permitted provided that the following conditions
7280849Scy * are met:
8280849Scy * 1. Redistributions of source code must retain the above copyright
9280849Scy *    notice, this list of conditions and the following disclaimer.
10280849Scy * 2. Redistributions in binary form must reproduce the above copyright
11280849Scy *    notice, this list of conditions and the following disclaimer in the
12280849Scy *    documentation and/or other materials provided with the distribution.
13280849Scy * 4. Neither the name of the University nor the names of its contributors
14280849Scy *    may be used to endorse or promote products derived from this software
15280849Scy *    without specific prior written permission.
16280849Scy *
17280849Scy * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18280849Scy * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19280849Scy * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20280849Scy * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21280849Scy * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22280849Scy * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23275970Scy * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24275970Scy * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25275970Scy * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26275970Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27275970Scy * SUCH DAMAGE.
28275970Scy */
29275970Scy
30275970Scy#if 0
31275970Scy#ifndef lint
32275970Scystatic char const copyright[] =
33275970Scy"@(#) Copyright (c) 1988, 1993, 1994\n\
34275970Scy	The Regents of the University of California.  All rights reserved.\n";
35275970Scy#endif /* not lint */
36275970Scy
37275970Scy#ifndef lint
38275970Scystatic char sccsid[] = "@(#)kill.c	8.4 (Berkeley) 4/28/95";
39275970Scy#endif /* not lint */
40275970Scy#endif
41275970Scy#include <sys/cdefs.h>
42275970Scy__FBSDID("$FreeBSD: head/bin/kill/kill.c 216629 2010-12-21 22:47:34Z jilles $");
43275970Scy
44275970Scy#include <ctype.h>
45275970Scy#include <err.h>
46275970Scy#include <errno.h>
47275970Scy#include <signal.h>
48275970Scy#include <stdio.h>
49275970Scy#include <stdlib.h>
50275970Scy#include <string.h>
51275970Scy
52275970Scy#ifdef SHELL
53280849Scy#define main killcmd
54275970Scy#include "bltin/bltin.h"
55275970Scy#include "error.h"
56275970Scy#endif
57275970Scy
58275970Scystatic void nosig(const char *);
59275970Scystatic void printsignals(FILE *);
60275970Scystatic int signame_to_signum(const char *);
61275970Scystatic void usage(void);
62275970Scy
63275970Scyint
64275970Scymain(int argc, char *argv[])
65275970Scy{
66275970Scy	int errors, numsig, pid;
67289997Sglebius	char *ep;
68275970Scy
69275970Scy	if (argc < 2)
70275970Scy		usage();
71275970Scy
72275970Scy	numsig = SIGTERM;
73275970Scy
74275970Scy	argc--, argv++;
75275970Scy	if (!strcmp(*argv, "-l")) {
76275970Scy		argc--, argv++;
77275970Scy		if (argc > 1)
78275970Scy			usage();
79275970Scy		if (argc == 1) {
80275970Scy			if (!isdigit(**argv))
81330567Sgordon				usage();
82330567Sgordon			numsig = strtol(*argv, &ep, 10);
83330567Sgordon			if (!**argv || *ep)
84330567Sgordon				errx(2, "illegal signal number: %s", *argv);
85330567Sgordon			if (numsig >= 128)
86330567Sgordon				numsig -= 128;
87289997Sglebius			if (numsig <= 0 || numsig >= sys_nsig)
88275970Scy				nosig(*argv);
89275970Scy			printf("%s\n", sys_signame[numsig]);
90275970Scy			return (0);
91275970Scy		}
92275970Scy		printsignals(stdout);
93275970Scy		return (0);
94275970Scy	}
95275970Scy
96275970Scy	if (!strcmp(*argv, "-s")) {
97293650Sglebius		argc--, argv++;
98275970Scy		if (argc < 1) {
99275970Scy			warnx("option requires an argument -- s");
100293650Sglebius			usage();
101275970Scy		}
102275970Scy		if (strcmp(*argv, "0")) {
103275970Scy			if ((numsig = signame_to_signum(*argv)) < 0)
104275970Scy				nosig(*argv);
105275970Scy		} else
106275970Scy			numsig = 0;
107275970Scy		argc--, argv++;
108275970Scy	} else if (**argv == '-' && *(*argv + 1) != '-') {
109275970Scy		++*argv;
110275970Scy		if (isalpha(**argv)) {
111275970Scy			if ((numsig = signame_to_signum(*argv)) < 0)
112275970Scy				nosig(*argv);
113275970Scy		} else if (isdigit(**argv)) {
114275970Scy			numsig = strtol(*argv, &ep, 10);
115275970Scy			if (!**argv || *ep)
116289997Sglebius				errx(2, "illegal signal number: %s", *argv);
117289997Sglebius			if (numsig < 0)
118289997Sglebius				nosig(*argv);
119275970Scy		} else
120275970Scy			nosig(*argv);
121275970Scy		argc--, argv++;
122275970Scy	}
123275970Scy
124275970Scy	if (argc > 0 && strncmp(*argv, "--", 2) == 0)
125275970Scy		argc--, argv++;
126275970Scy
127275970Scy	if (argc == 0)
128275970Scy		usage();
129275970Scy
130275970Scy	for (errors = 0; argc; argc--, argv++) {
131275970Scy#ifdef SHELL
132275970Scy		if (**argv == '%')
133275970Scy			pid = getjobpgrp(*argv);
134275970Scy		else
135275970Scy#endif
136275970Scy		{
137275970Scy			pid = strtol(*argv, &ep, 10);
138275970Scy			if (!**argv || *ep)
139275970Scy				errx(2, "illegal process id: %s", *argv);
140275970Scy		}
141275970Scy		if (kill(pid, numsig) == -1) {
142289997Sglebius			warn("%s", *argv);
143289997Sglebius			errors = 1;
144289997Sglebius		}
145289997Sglebius	}
146289997Sglebius
147289997Sglebius	return (errors);
148289997Sglebius}
149289997Sglebius
150289997Sglebiusstatic int
151289997Sglebiussigname_to_signum(const char *sig)
152289997Sglebius{
153289997Sglebius	int n;
154289997Sglebius
155289997Sglebius	if (!strncasecmp(sig, "sig", (size_t)3))
156289997Sglebius		sig += 3;
157289997Sglebius	for (n = 1; n < sys_nsig; n++) {
158275970Scy		if (!strcasecmp(sys_signame[n], sig))
159275970Scy			return (n);
160275970Scy	}
161275970Scy	return (-1);
162275970Scy}
163275970Scy
164275970Scystatic void
165275970Scynosig(const char *name)
166275970Scy{
167275970Scy
168275970Scy	warnx("unknown signal %s; valid signals:", name);
169275970Scy	printsignals(stderr);
170275970Scy#ifdef SHELL
171275970Scy	error(NULL);
172275970Scy#else
173275970Scy	exit(2);
174275970Scy#endif
175275970Scy}
176275970Scy
177275970Scystatic void
178275970Scyprintsignals(FILE *fp)
179275970Scy{
180275970Scy	int n;
181275970Scy
182275970Scy	for (n = 1; n < sys_nsig; n++) {
183275970Scy		(void)fprintf(fp, "%s", sys_signame[n]);
184275970Scy		if (n == (sys_nsig / 2) || n == (sys_nsig - 1))
185275970Scy			(void)fprintf(fp, "\n");
186275970Scy		else
187275970Scy			(void)fprintf(fp, " ");
188275970Scy	}
189316722Sdelphij}
190316722Sdelphij
191316722Sdelphijstatic void
192275970Scyusage(void)
193275970Scy{
194275970Scy
195275970Scy	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
196275970Scy		"usage: kill [-s signal_name] pid ...",
197275970Scy		"       kill -l [exit_status]",
198275970Scy		"       kill -signal_name pid ...",
199275970Scy		"       kill -signal_number pid ...");
200275970Scy#ifdef SHELL
201	error(NULL);
202#else
203	exit(2);
204#endif
205}
206