kill.c revision 50471
199461Sobrien/*
299461Sobrien * Copyright (c) 1988, 1993, 1994
399461Sobrien *	The Regents of the University of California.  All rights reserved.
499461Sobrien *
599461Sobrien * Redistribution and use in source and binary forms, with or without
699461Sobrien * modification, are permitted provided that the following conditions
799461Sobrien * are met:
899461Sobrien * 1. Redistributions of source code must retain the above copyright
999461Sobrien *    notice, this list of conditions and the following disclaimer.
1099461Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1199461Sobrien *    notice, this list of conditions and the following disclaimer in the
1299461Sobrien *    documentation and/or other materials provided with the distribution.
1399461Sobrien * 3. All advertising materials mentioning features or use of this software
1499461Sobrien *    must display the following acknowledgement:
1599461Sobrien *	This product includes software developed by the University of
1699461Sobrien *	California, Berkeley and its contributors.
1799461Sobrien * 4. Neither the name of the University nor the names of its contributors
1899461Sobrien *    may be used to endorse or promote products derived from this software
1999461Sobrien *    without specific prior written permission.
2099461Sobrien *
2199461Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2299461Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2399461Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2499461Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2599461Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2699461Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2799461Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2899461Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2999461Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3099461Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3199461Sobrien * SUCH DAMAGE.
3299461Sobrien */
3399461Sobrien
3499461Sobrien#ifndef lint
3599461Sobrienstatic char const copyright[] =
3699461Sobrien"@(#) Copyright (c) 1988, 1993, 1994\n\
3799461Sobrien	The Regents of the University of California.  All rights reserved.\n";
3899461Sobrien#endif /* not lint */
3999461Sobrien
4099461Sobrien#ifndef lint
4199461Sobrien#if 0
4299461Sobrienstatic char sccsid[] = "@(#)kill.c	8.4 (Berkeley) 4/28/95";
4399461Sobrien#endif
4499461Sobrienstatic const char rcsid[] =
4599461Sobrien  "$FreeBSD: head/bin/kill/kill.c 50471 1999-08-27 23:15:48Z peter $";
4699461Sobrien#endif /* not lint */
4799461Sobrien
4899461Sobrien#include <ctype.h>
4999461Sobrien#include <err.h>
5099461Sobrien#include <errno.h>
5199461Sobrien#include <signal.h>
5299461Sobrien#include <stdio.h>
5399461Sobrien#include <stdlib.h>
5499461Sobrien#include <string.h>
5599461Sobrien
5699461Sobrienvoid nosig __P((char *));
5799461Sobrienvoid printsignals __P((FILE *));
5899461Sobrienint signame_to_signum __P((char *));
5999461Sobrienvoid usage __P((void));
6099461Sobrien
6199461Sobrienint
6299461Sobrienmain(argc, argv)
6399461Sobrien	int argc;
6499461Sobrien	char *argv[];
6599461Sobrien{
6699461Sobrien	int errors, numsig, pid;
6799461Sobrien	char *ep;
6899461Sobrien
6999461Sobrien	if (argc < 2)
7099461Sobrien		usage();
7199461Sobrien
7299461Sobrien	numsig = SIGTERM;
7399461Sobrien
7499461Sobrien	argc--, argv++;
7599461Sobrien	if (!strcmp(*argv, "-l")) {
7699461Sobrien		argc--, argv++;
7799461Sobrien		if (argc > 1)
7899461Sobrien			usage();
7999461Sobrien		if (argc == 1) {
8099461Sobrien			if (!isdigit(**argv))
8199461Sobrien				usage();
8299461Sobrien			numsig = strtol(*argv, &ep, 10);
8399461Sobrien			if (!**argv || *ep)
8499461Sobrien				errx(1, "illegal signal number: %s", *argv);
8599461Sobrien			if (numsig >= 128)
8699461Sobrien				numsig -= 128;
8799461Sobrien			if (numsig <= 0 || numsig >= NSIG)
8899461Sobrien				nosig(*argv);
8999461Sobrien			printf("%s\n", sys_signame[numsig]);
9099461Sobrien			exit(0);
9199461Sobrien		}
9299461Sobrien		printsignals(stdout);
9399461Sobrien		exit(0);
9499461Sobrien	}
9599461Sobrien
9699461Sobrien	if (!strcmp(*argv, "-s")) {
9799461Sobrien		argc--, argv++;
9899461Sobrien		if (argc < 1) {
9999461Sobrien			warnx("option requires an argument -- s");
10099461Sobrien			usage();
10199461Sobrien		}
10299461Sobrien		if (strcmp(*argv, "0")) {
10399461Sobrien			if ((numsig = signame_to_signum(*argv)) < 0)
10499461Sobrien				nosig(*argv);
10599461Sobrien		} else
10699461Sobrien			numsig = 0;
10799461Sobrien		argc--, argv++;
10899461Sobrien	} else if (**argv == '-') {
10999461Sobrien		++*argv;
11099461Sobrien		if (isalpha(**argv)) {
11199461Sobrien			if ((numsig = signame_to_signum(*argv)) < 0)
11299461Sobrien				nosig(*argv);
11399461Sobrien		} else if (isdigit(**argv)) {
11499461Sobrien			numsig = strtol(*argv, &ep, 10);
11599461Sobrien			if (!**argv || *ep)
11699461Sobrien				errx(1, "illegal signal number: %s", *argv);
11799461Sobrien			if (numsig < 0 || numsig >= NSIG)
11899461Sobrien				nosig(*argv);
11999461Sobrien		} else
12099461Sobrien			nosig(*argv);
12199461Sobrien		argc--, argv++;
12299461Sobrien	}
12399461Sobrien
12499461Sobrien	if (argc == 0)
12599461Sobrien		usage();
12699461Sobrien
12799461Sobrien	for (errors = 0; argc; argc--, argv++) {
12899461Sobrien		pid = strtol(*argv, &ep, 10);
12999461Sobrien		if (!**argv || *ep) {
13099461Sobrien			warnx("illegal process id: %s", *argv);
13199461Sobrien			errors = 1;
13299461Sobrien		} else if (kill(pid, numsig) == -1) {
13399461Sobrien			warn("%s", *argv);
13499461Sobrien			errors = 1;
13599461Sobrien		}
13699461Sobrien	}
13799461Sobrien
13899461Sobrien	exit(errors);
13999461Sobrien}
14099461Sobrien
14199461Sobrienint
14299461Sobriensigname_to_signum(sig)
14399461Sobrien	char *sig;
14499461Sobrien{
14599461Sobrien	int n;
14699461Sobrien
14799461Sobrien	if (!strncasecmp(sig, "sig", 3))
14899461Sobrien		sig += 3;
14999461Sobrien	for (n = 1; n < NSIG; n++) {
15099461Sobrien		if (!strcasecmp(sys_signame[n], sig))
15199461Sobrien			return (n);
15299461Sobrien	}
15399461Sobrien	return (-1);
15499461Sobrien}
15599461Sobrien
15699461Sobrienvoid
15799461Sobriennosig(name)
15899461Sobrien	char *name;
15999461Sobrien{
16099461Sobrien
16199461Sobrien	warnx("unknown signal %s; valid signals:", name);
16299461Sobrien	printsignals(stderr);
16399461Sobrien	exit(1);
16499461Sobrien}
16599461Sobrien
16699461Sobrienvoid
16799461Sobrienprintsignals(fp)
16899461Sobrien	FILE *fp;
16999461Sobrien{
17099461Sobrien	int n;
17199461Sobrien
17299461Sobrien	for (n = 1; n < NSIG; n++) {
17399461Sobrien		(void)fprintf(fp, "%s", sys_signame[n]);
17499461Sobrien		if (n == (NSIG / 2) || n == (NSIG - 1))
17599461Sobrien			(void)fprintf(fp, "\n");
17699461Sobrien		else
17799461Sobrien			(void)fprintf(fp, " ");
17899461Sobrien	}
17999461Sobrien}
18099461Sobrien
18199461Sobrienvoid
18299461Sobrienusage()
18399461Sobrien{
18499461Sobrien
18599461Sobrien	(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
18699461Sobrien		"usage: kill [-s signal_name] pid ...",
18799461Sobrien		"       kill -l [exit_status]",
18899461Sobrien		"       kill -signal_name pid ...",
18999461Sobrien		"       kill -signal_number pid ...");
19099461Sobrien	exit(1);
19199461Sobrien}
19299461Sobrien