]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/kill.def
commit bash-20080207 snapshot
[thirdparty/bash.git] / builtins / kill.def
CommitLineData
726f6388
JA
1This file is kill.def, from which is created kill.c.
2It implements the builtin "kill" in Bash.
3
9cbcc93b 4Copyright (C) 1987-2008 Free Software Foundation, Inc.
726f6388
JA
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
8Bash is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
bb70624e 10Software Foundation; either version 2, or (at your option) any later
726f6388
JA
11version.
12
13Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License along
19with Bash; see the file COPYING. If not, write to the Free Software
bb70624e 20Foundation, 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
27Send the processes identified by PID or JOBSPEC the signal named by
28SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then
29SIGTERM is assumed.
30
31Options:
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
37Kill is a shell builtin for two reasons: it allows job IDs to be used
38instead of process IDs, and allows processes to be killed if the limit
39on 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)
63extern int errno;
64#endif /* !errno */
726f6388 65
726f6388
JA
66extern int posixly_correct;
67
d3a24ed2
CR
68static 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. */
79int
80kill_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
247static void
248kill_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}