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