1139969Simp/*-
21556Srgrimes * Copyright (c) 1988, 1993, 1994
31556Srgrimes *	The Regents of the University of California.  All rights reserved.
41556Srgrimes *
51556Srgrimes * Redistribution and use in source and binary forms, with or without
61556Srgrimes * modification, are permitted provided that the following conditions
71556Srgrimes * are met:
81556Srgrimes * 1. Redistributions of source code must retain the above copyright
91556Srgrimes *    notice, this list of conditions and the following disclaimer.
101556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111556Srgrimes *    notice, this list of conditions and the following disclaimer in the
121556Srgrimes *    documentation and/or other materials provided with the distribution.
131556Srgrimes * 4. Neither the name of the University nor the names of its contributors
141556Srgrimes *    may be used to endorse or promote products derived from this software
151556Srgrimes *    without specific prior written permission.
161556Srgrimes *
171556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201556Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271556Srgrimes * SUCH DAMAGE.
281556Srgrimes */
29219154Sjilles/*
30219154Sjilles * Important: This file is used both as a standalone program /bin/kill and
31219154Sjilles * as a builtin for /bin/sh (#define SHELL).
32219154Sjilles */
331556Srgrimes
34114433Sobrien#if 0
351556Srgrimes#ifndef lint
3620416Sstevestatic char const copyright[] =
371556Srgrimes"@(#) Copyright (c) 1988, 1993, 1994\n\
381556Srgrimes	The Regents of the University of California.  All rights reserved.\n";
391556Srgrimes#endif /* not lint */
401556Srgrimes
411556Srgrimes#ifndef lint
4236012Scharnierstatic char sccsid[] = "@(#)kill.c	8.4 (Berkeley) 4/28/95";
43114433Sobrien#endif /* not lint */
4436012Scharnier#endif
4599109Sobrien#include <sys/cdefs.h>
4699109Sobrien__FBSDID("$FreeBSD$");
471556Srgrimes
481556Srgrimes#include <ctype.h>
491556Srgrimes#include <err.h>
501556Srgrimes#include <errno.h>
511556Srgrimes#include <signal.h>
521556Srgrimes#include <stdio.h>
531556Srgrimes#include <stdlib.h>
541556Srgrimes#include <string.h>
551556Srgrimes
56216629Sjilles#ifdef SHELL
57216629Sjilles#define main killcmd
58216629Sjilles#include "bltin/bltin.h"
59216629Sjilles#include "error.h"
60216629Sjilles#endif
61216629Sjilles
62127005Sjmallettstatic void nosig(const char *);
63127005Sjmallettstatic void printsignals(FILE *);
64127005Sjmallettstatic int signame_to_signum(const char *);
65127005Sjmallettstatic void usage(void);
661556Srgrimes
671556Srgrimesint
6890110Simpmain(int argc, char *argv[])
691556Srgrimes{
701556Srgrimes	int errors, numsig, pid;
711556Srgrimes	char *ep;
721556Srgrimes
731556Srgrimes	if (argc < 2)
741556Srgrimes		usage();
751556Srgrimes
7620416Ssteve	numsig = SIGTERM;
7720416Ssteve
7820416Ssteve	argc--, argv++;
7920416Ssteve	if (!strcmp(*argv, "-l")) {
8020416Ssteve		argc--, argv++;
8120416Ssteve		if (argc > 1)
8220416Ssteve			usage();
8320416Ssteve		if (argc == 1) {
8420416Ssteve			if (!isdigit(**argv))
8520416Ssteve				usage();
8620416Ssteve			numsig = strtol(*argv, &ep, 10);
8728554Sjlemon			if (!**argv || *ep)
88216629Sjilles				errx(2, "illegal signal number: %s", *argv);
8920416Ssteve			if (numsig >= 128)
9020416Ssteve				numsig -= 128;
91125156Snjl			if (numsig <= 0 || numsig >= sys_nsig)
9220416Ssteve				nosig(*argv);
9320416Ssteve			printf("%s\n", sys_signame[numsig]);
94216629Sjilles			return (0);
9520416Ssteve		}
9620416Ssteve		printsignals(stdout);
97216629Sjilles		return (0);
981556Srgrimes	}
991556Srgrimes
10020416Ssteve	if (!strcmp(*argv, "-s")) {
10120416Ssteve		argc--, argv++;
10220416Ssteve		if (argc < 1) {
10320416Ssteve			warnx("option requires an argument -- s");
10420416Ssteve			usage();
10520416Ssteve		}
10620416Ssteve		if (strcmp(*argv, "0")) {
10720416Ssteve			if ((numsig = signame_to_signum(*argv)) < 0)
10820416Ssteve				nosig(*argv);
10920416Ssteve		} else
11020416Ssteve			numsig = 0;
11120416Ssteve		argc--, argv++;
11298158Stjr	} else if (**argv == '-' && *(*argv + 1) != '-') {
1131556Srgrimes		++*argv;
1141556Srgrimes		if (isalpha(**argv)) {
11520416Ssteve			if ((numsig = signame_to_signum(*argv)) < 0)
1161556Srgrimes				nosig(*argv);
1171556Srgrimes		} else if (isdigit(**argv)) {
1181556Srgrimes			numsig = strtol(*argv, &ep, 10);
11928554Sjlemon			if (!**argv || *ep)
120216629Sjilles				errx(2, "illegal signal number: %s", *argv);
121204308Skib			if (numsig < 0)
1221556Srgrimes				nosig(*argv);
1231556Srgrimes		} else
1241556Srgrimes			nosig(*argv);
12520416Ssteve		argc--, argv++;
1261556Srgrimes	}
1271556Srgrimes
12898158Stjr	if (argc > 0 && strncmp(*argv, "--", 2) == 0)
12998158Stjr		argc--, argv++;
13098158Stjr
13120416Ssteve	if (argc == 0)
1321556Srgrimes		usage();
1331556Srgrimes
13420416Ssteve	for (errors = 0; argc; argc--, argv++) {
135216629Sjilles#ifdef SHELL
136216629Sjilles		if (**argv == '%')
137216629Sjilles			pid = getjobpgrp(*argv);
138216629Sjilles		else
139216629Sjilles#endif
140216629Sjilles		{
141216629Sjilles			pid = strtol(*argv, &ep, 10);
142216629Sjilles			if (!**argv || *ep)
143216629Sjilles				errx(2, "illegal process id: %s", *argv);
144216629Sjilles		}
145216629Sjilles		if (kill(pid, numsig) == -1) {
1461556Srgrimes			warn("%s", *argv);
1471556Srgrimes			errors = 1;
1481556Srgrimes		}
1491556Srgrimes	}
15020416Ssteve
151216629Sjilles	return (errors);
1521556Srgrimes}
1531556Srgrimes
154127005Sjmallettstatic int
155127005Sjmallettsigname_to_signum(const char *sig)
15620416Ssteve{
15720416Ssteve	int n;
15820416Ssteve
159250035Seadler	if (strncasecmp(sig, "SIG", 3) == 0)
16020416Ssteve		sig += 3;
161125156Snjl	for (n = 1; n < sys_nsig; n++) {
16220416Ssteve		if (!strcasecmp(sys_signame[n], sig))
16320416Ssteve			return (n);
16420416Ssteve	}
16520416Ssteve	return (-1);
16620416Ssteve}
16720416Ssteve
168127005Sjmallettstatic void
169127005Sjmallettnosig(const char *name)
1701556Srgrimes{
1711556Srgrimes
1721556Srgrimes	warnx("unknown signal %s; valid signals:", name);
17320416Ssteve	printsignals(stderr);
174216629Sjilles#ifdef SHELL
175216629Sjilles	error(NULL);
176216629Sjilles#else
177216629Sjilles	exit(2);
178216629Sjilles#endif
1791556Srgrimes}
1801556Srgrimes
181127005Sjmallettstatic void
18290110Simpprintsignals(FILE *fp)
1831556Srgrimes{
18420416Ssteve	int n;
1851556Srgrimes
186125156Snjl	for (n = 1; n < sys_nsig; n++) {
18720416Ssteve		(void)fprintf(fp, "%s", sys_signame[n]);
188125156Snjl		if (n == (sys_nsig / 2) || n == (sys_nsig - 1))
1891556Srgrimes			(void)fprintf(fp, "\n");
19020416Ssteve		else
19120416Ssteve			(void)fprintf(fp, " ");
1921556Srgrimes	}
1931556Srgrimes}
1941556Srgrimes
195127005Sjmallettstatic void
19690110Simpusage(void)
1971556Srgrimes{
1981556Srgrimes
19926465Scharnier	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
20026465Scharnier		"usage: kill [-s signal_name] pid ...",
20126465Scharnier		"       kill -l [exit_status]",
20226465Scharnier		"       kill -signal_name pid ...",
20326465Scharnier		"       kill -signal_number pid ...");
204216629Sjilles#ifdef SHELL
205216629Sjilles	error(NULL);
206216629Sjilles#else
207216629Sjilles	exit(2);
208216629Sjilles#endif
2091556Srgrimes}
210