1This file is kill.def, from which is created kill.c. 2It implements the builtin "kill" in Bash. 3 4Copyright (C) 1987-2009 Free Software Foundation, Inc. 5 6This file is part of GNU Bash, the Bourne Again SHell. 7 8Bash is free software: you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation, either version 3 of the License, or 11(at your option) any later version. 12 13Bash is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with Bash. If not, see <http://www.gnu.org/licenses/>. 20 21$PRODUCES kill.c 22 23$BUILTIN kill 24$FUNCTION kill_builtin 25$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] 26Send a signal to a job. 27 28Send the processes identified by PID or JOBSPEC the signal named by 29SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then 30SIGTERM is assumed. 31 32Options: 33 -s sig SIG is a signal name 34 -n sig SIG is a signal number 35 -l list the signal names; if arguments follow `-l' they are 36 assumed to be signal numbers for which names should be listed 37 38Kill is a shell builtin for two reasons: it allows job IDs to be used 39instead of process IDs, and allows processes to be killed if the limit 40on processes that you can create is reached. 41 42Exit Status: 43Returns success unless an invalid option is given or an error occurs. 44$END 45 46#include <config.h> 47 48#include <stdio.h> 49#include <errno.h> 50#if defined (HAVE_UNISTD_H) 51# ifdef _MINIX 52# include <sys/types.h> 53# endif 54# include <unistd.h> 55#endif 56 57#include "../bashansi.h" 58#include "../bashintl.h" 59 60#include "../shell.h" 61#include "../trap.h" 62#include "../jobs.h" 63#include "common.h" 64 65/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ 66#if !defined (errno) 67extern int errno; 68#endif /* !errno */ 69 70extern int posixly_correct; 71 72static void kill_error __P((pid_t, int)); 73 74#if !defined (CONTINUE_AFTER_KILL_ERROR) 75# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE) 76#else 77# define CONTINUE_OR_FAIL goto continue_killing 78#endif /* CONTINUE_AFTER_KILL_ERROR */ 79 80/* Here is the kill builtin. We only have it so that people can type 81 kill -KILL %1? No, if you fill up the process table this way you 82 can still kill some. */ 83int 84kill_builtin (list) 85 WORD_LIST *list; 86{ 87 int sig, any_succeeded, listing, saw_signal, dflags; 88 char *sigspec, *word; 89 pid_t pid; 90 intmax_t pid_value; 91 92 if (list == 0) 93 { 94 builtin_usage (); 95 return (EXECUTION_FAILURE); 96 } 97 98 any_succeeded = listing = saw_signal = 0; 99 sig = SIGTERM; 100 sigspec = "TERM"; 101 102 dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0); 103 /* Process options. */ 104 while (list) 105 { 106 word = list->word->word; 107 108 if (ISOPTION (word, 'l')) 109 { 110 listing++; 111 list = list->next; 112 } 113 else if (ISOPTION (word, 's') || ISOPTION (word, 'n')) 114 { 115 list = list->next; 116 if (list) 117 { 118 sigspec = list->word->word; 119 if (sigspec[0] == '0' && sigspec[1] == '\0') 120 sig = 0; 121 else 122 sig = decode_signal (sigspec, dflags); 123 list = list->next; 124 } 125 else 126 { 127 sh_needarg (word); 128 return (EXECUTION_FAILURE); 129 } 130 } 131 else if (ISOPTION (word, '-')) 132 { 133 list = list->next; 134 break; 135 } 136 else if (ISOPTION (word, '?')) 137 { 138 builtin_usage (); 139 return (EXECUTION_SUCCESS); 140 } 141 /* If this is a signal specification then process it. We only process 142 the first one seen; other arguments may signify process groups (e.g, 143 -num == process group num). */ 144 else if ((*word == '-') && !saw_signal) 145 { 146 sigspec = word + 1; 147 sig = decode_signal (sigspec, dflags); 148 saw_signal++; 149 list = list->next; 150 } 151 else 152 break; 153 } 154 155 if (listing) 156 return (display_signal_list (list, 0)); 157 158 /* OK, we are killing processes. */ 159 if (sig == NO_SIG) 160 { 161 sh_invalidsig (sigspec); 162 return (EXECUTION_FAILURE); 163 } 164 165 if (list == 0) 166 { 167 builtin_usage (); 168 return (EXECUTION_FAILURE); 169 } 170 171 while (list) 172 { 173 word = list->word->word; 174 175 if (*word == '-') 176 word++; 177 178 /* Use the entire argument in case of minus sign presence. */ 179 if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value)) 180 { 181 pid = (pid_t) pid_value; 182 183 if (kill_pid (pid, sig, pid < -1) < 0) 184 { 185 if (errno == EINVAL) 186 sh_invalidsig (sigspec); 187 else 188 kill_error (pid, errno); 189 CONTINUE_OR_FAIL; 190 } 191 else 192 any_succeeded++; 193 } 194#if defined (JOB_CONTROL) 195 else if (*list->word->word && *list->word->word != '%') 196 { 197 builtin_error (_("%s: arguments must be process or job IDs"), list->word->word); 198 CONTINUE_OR_FAIL; 199 } 200 else if (*word) 201 /* Posix.2 says you can kill without job control active (4.32.4) */ 202 { /* Must be a job spec. Check it out. */ 203 int job; 204 sigset_t set, oset; 205 JOB *j; 206 207 BLOCK_CHILD (set, oset); 208 job = get_job_spec (list); 209 210 if (INVALID_JOB (job)) 211 { 212 if (job != DUP_JOB) 213 sh_badjob (list->word->word); 214 UNBLOCK_CHILD (oset); 215 CONTINUE_OR_FAIL; 216 } 217 218 j = get_job_by_jid (job); 219 /* Job spec used. Kill the process group. If the job was started 220 without job control, then its pgrp == shell_pgrp, so we have 221 to be careful. We take the pid of the first job in the pipeline 222 in that case. */ 223 pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid; 224 225 UNBLOCK_CHILD (oset); 226 227 if (kill_pid (pid, sig, 1) < 0) 228 { 229 if (errno == EINVAL) 230 sh_invalidsig (sigspec); 231 else 232 kill_error (pid, errno); 233 CONTINUE_OR_FAIL; 234 } 235 else 236 any_succeeded++; 237 } 238#endif /* !JOB_CONTROL */ 239 else 240 { 241 sh_badpid (list->word->word); 242 CONTINUE_OR_FAIL; 243 } 244 continue_killing: 245 list = list->next; 246 } 247 248 return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE); 249} 250 251static void 252kill_error (pid, e) 253 pid_t pid; 254 int e; 255{ 256 char *x; 257 258 x = strerror (e); 259 if (x == 0) 260 x = _("Unknown error"); 261 builtin_error ("(%ld) - %s", (long)pid, x); 262} 263