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/11/bin/kill/kill.c 315721 2017-03-22 17:46:08Z 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#endif 60216629Sjilles 61127005Sjmallettstatic void nosig(const char *); 62127005Sjmallettstatic void printsignals(FILE *); 63127005Sjmallettstatic int signame_to_signum(const char *); 64127005Sjmallettstatic void usage(void); 651556Srgrimes 661556Srgrimesint 6790110Simpmain(int argc, char *argv[]) 681556Srgrimes{ 69315721Sbdrewery long pidl; 70315721Sbdrewery pid_t pid; 71315721Sbdrewery int errors, numsig, ret; 721556Srgrimes char *ep; 731556Srgrimes 741556Srgrimes if (argc < 2) 751556Srgrimes usage(); 761556Srgrimes 7720416Ssteve numsig = SIGTERM; 7820416Ssteve 7920416Ssteve argc--, argv++; 8020416Ssteve if (!strcmp(*argv, "-l")) { 8120416Ssteve argc--, argv++; 8220416Ssteve if (argc > 1) 8320416Ssteve usage(); 8420416Ssteve if (argc == 1) { 8520416Ssteve if (!isdigit(**argv)) 8620416Ssteve usage(); 8720416Ssteve numsig = strtol(*argv, &ep, 10); 8828554Sjlemon if (!**argv || *ep) 89216629Sjilles errx(2, "illegal signal number: %s", *argv); 9020416Ssteve if (numsig >= 128) 9120416Ssteve numsig -= 128; 92125156Snjl if (numsig <= 0 || numsig >= sys_nsig) 9320416Ssteve nosig(*argv); 9420416Ssteve printf("%s\n", sys_signame[numsig]); 95216629Sjilles return (0); 9620416Ssteve } 9720416Ssteve printsignals(stdout); 98216629Sjilles return (0); 991556Srgrimes } 1001556Srgrimes 10120416Ssteve if (!strcmp(*argv, "-s")) { 10220416Ssteve argc--, argv++; 10320416Ssteve if (argc < 1) { 10420416Ssteve warnx("option requires an argument -- s"); 10520416Ssteve usage(); 10620416Ssteve } 10720416Ssteve if (strcmp(*argv, "0")) { 10820416Ssteve if ((numsig = signame_to_signum(*argv)) < 0) 10920416Ssteve nosig(*argv); 11020416Ssteve } else 11120416Ssteve numsig = 0; 11220416Ssteve argc--, argv++; 11398158Stjr } else if (**argv == '-' && *(*argv + 1) != '-') { 1141556Srgrimes ++*argv; 1151556Srgrimes if (isalpha(**argv)) { 11620416Ssteve if ((numsig = signame_to_signum(*argv)) < 0) 1171556Srgrimes nosig(*argv); 1181556Srgrimes } else if (isdigit(**argv)) { 1191556Srgrimes numsig = strtol(*argv, &ep, 10); 12028554Sjlemon if (!**argv || *ep) 121216629Sjilles errx(2, "illegal signal number: %s", *argv); 122204308Skib if (numsig < 0) 1231556Srgrimes nosig(*argv); 1241556Srgrimes } else 1251556Srgrimes nosig(*argv); 12620416Ssteve argc--, argv++; 1271556Srgrimes } 1281556Srgrimes 12998158Stjr if (argc > 0 && strncmp(*argv, "--", 2) == 0) 13098158Stjr argc--, argv++; 13198158Stjr 13220416Ssteve if (argc == 0) 1331556Srgrimes usage(); 1341556Srgrimes 13520416Ssteve for (errors = 0; argc; argc--, argv++) { 136216629Sjilles#ifdef SHELL 137263206Sjilles if (**argv == '%') 138263206Sjilles ret = killjob(*argv, numsig); 139263206Sjilles else 140216629Sjilles#endif 141216629Sjilles { 142315721Sbdrewery pidl = strtol(*argv, &ep, 10); 143315721Sbdrewery /* Check for overflow of pid_t. */ 144315721Sbdrewery pid = (pid_t)pidl; 145315721Sbdrewery if (!**argv || *ep || pid != pidl) 146216629Sjilles errx(2, "illegal process id: %s", *argv); 147263206Sjilles ret = kill(pid, numsig); 148216629Sjilles } 149263206Sjilles if (ret == -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