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