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: stable/10/bin/kill/kill.c 315722 2017-03-22 17:49:56Z bdrewery $"); 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{ 70315722Sbdrewery long pidl; 71315722Sbdrewery pid_t pid; 72315722Sbdrewery int errors, numsig; 731556Srgrimes char *ep; 741556Srgrimes 751556Srgrimes if (argc < 2) 761556Srgrimes usage(); 771556Srgrimes 7820416Ssteve numsig = SIGTERM; 7920416Ssteve 8020416Ssteve argc--, argv++; 8120416Ssteve if (!strcmp(*argv, "-l")) { 8220416Ssteve argc--, argv++; 8320416Ssteve if (argc > 1) 8420416Ssteve usage(); 8520416Ssteve if (argc == 1) { 8620416Ssteve if (!isdigit(**argv)) 8720416Ssteve usage(); 8820416Ssteve numsig = strtol(*argv, &ep, 10); 8928554Sjlemon if (!**argv || *ep) 90216629Sjilles errx(2, "illegal signal number: %s", *argv); 9120416Ssteve if (numsig >= 128) 9220416Ssteve numsig -= 128; 93125156Snjl if (numsig <= 0 || numsig >= sys_nsig) 9420416Ssteve nosig(*argv); 9520416Ssteve printf("%s\n", sys_signame[numsig]); 96216629Sjilles return (0); 9720416Ssteve } 9820416Ssteve printsignals(stdout); 99216629Sjilles return (0); 1001556Srgrimes } 1011556Srgrimes 10220416Ssteve if (!strcmp(*argv, "-s")) { 10320416Ssteve argc--, argv++; 10420416Ssteve if (argc < 1) { 10520416Ssteve warnx("option requires an argument -- s"); 10620416Ssteve usage(); 10720416Ssteve } 10820416Ssteve if (strcmp(*argv, "0")) { 10920416Ssteve if ((numsig = signame_to_signum(*argv)) < 0) 11020416Ssteve nosig(*argv); 11120416Ssteve } else 11220416Ssteve numsig = 0; 11320416Ssteve argc--, argv++; 11498158Stjr } else if (**argv == '-' && *(*argv + 1) != '-') { 1151556Srgrimes ++*argv; 1161556Srgrimes if (isalpha(**argv)) { 11720416Ssteve if ((numsig = signame_to_signum(*argv)) < 0) 1181556Srgrimes nosig(*argv); 1191556Srgrimes } else if (isdigit(**argv)) { 1201556Srgrimes numsig = strtol(*argv, &ep, 10); 12128554Sjlemon if (!**argv || *ep) 122216629Sjilles errx(2, "illegal signal number: %s", *argv); 123204308Skib if (numsig < 0) 1241556Srgrimes nosig(*argv); 1251556Srgrimes } else 1261556Srgrimes nosig(*argv); 12720416Ssteve argc--, argv++; 1281556Srgrimes } 1291556Srgrimes 13098158Stjr if (argc > 0 && strncmp(*argv, "--", 2) == 0) 13198158Stjr argc--, argv++; 13298158Stjr 13320416Ssteve if (argc == 0) 1341556Srgrimes usage(); 1351556Srgrimes 13620416Ssteve for (errors = 0; argc; argc--, argv++) { 137216629Sjilles#ifdef SHELL 138216629Sjilles if (**argv == '%') 139216629Sjilles pid = getjobpgrp(*argv); 140216629Sjilles else 141216629Sjilles#endif 142216629Sjilles { 143315722Sbdrewery pidl = strtol(*argv, &ep, 10); 144315722Sbdrewery /* Check for overflow of pid_t. */ 145315722Sbdrewery pid = (pid_t)pidl; 146315722Sbdrewery if (!**argv || *ep || pid != pidl) 147216629Sjilles errx(2, "illegal process id: %s", *argv); 148216629Sjilles } 149216629Sjilles if (kill(pid, numsig) == -1) { 1501556Srgrimes warn("%s", *argv); 1511556Srgrimes errors = 1; 1521556Srgrimes } 1531556Srgrimes } 15420416Ssteve 155216629Sjilles return (errors); 1561556Srgrimes} 1571556Srgrimes 158127005Sjmallettstatic int 159127005Sjmallettsigname_to_signum(const char *sig) 16020416Ssteve{ 16120416Ssteve int n; 16220416Ssteve 163250035Seadler if (strncasecmp(sig, "SIG", 3) == 0) 16420416Ssteve sig += 3; 165125156Snjl for (n = 1; n < sys_nsig; n++) { 16620416Ssteve if (!strcasecmp(sys_signame[n], sig)) 16720416Ssteve return (n); 16820416Ssteve } 16920416Ssteve return (-1); 17020416Ssteve} 17120416Ssteve 172127005Sjmallettstatic void 173127005Sjmallettnosig(const char *name) 1741556Srgrimes{ 1751556Srgrimes 1761556Srgrimes warnx("unknown signal %s; valid signals:", name); 17720416Ssteve printsignals(stderr); 178216629Sjilles#ifdef SHELL 179216629Sjilles error(NULL); 180216629Sjilles#else 181216629Sjilles exit(2); 182216629Sjilles#endif 1831556Srgrimes} 1841556Srgrimes 185127005Sjmallettstatic void 18690110Simpprintsignals(FILE *fp) 1871556Srgrimes{ 18820416Ssteve int n; 1891556Srgrimes 190125156Snjl for (n = 1; n < sys_nsig; n++) { 19120416Ssteve (void)fprintf(fp, "%s", sys_signame[n]); 192125156Snjl if (n == (sys_nsig / 2) || n == (sys_nsig - 1)) 1931556Srgrimes (void)fprintf(fp, "\n"); 19420416Ssteve else 19520416Ssteve (void)fprintf(fp, " "); 1961556Srgrimes } 1971556Srgrimes} 1981556Srgrimes 199127005Sjmallettstatic void 20090110Simpusage(void) 2011556Srgrimes{ 2021556Srgrimes 20326465Scharnier (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", 20426465Scharnier "usage: kill [-s signal_name] pid ...", 20526465Scharnier " kill -l [exit_status]", 20626465Scharnier " kill -signal_name pid ...", 20726465Scharnier " kill -signal_number pid ..."); 208216629Sjilles#ifdef SHELL 209216629Sjilles error(NULL); 210216629Sjilles#else 211216629Sjilles exit(2); 212216629Sjilles#endif 2131556Srgrimes} 214