source: vendor/bash/3.1/builtins/kill.def

Last change on this file was 3228, checked in by bird, 18 years ago

bash 3.1

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