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