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