blob: 2b7e0c7b10b21c943edd3797c55d2384f4352cfc [file] [log] [blame]
Dan Pasanenc6e37862014-10-02 14:08:59 -05001/* kill.c, created from kill.def. */
2#line 22 "./kill.def"
3
4#line 45 "./kill.def"
5
6#include <config.h>
7
8#include <stdio.h>
9#include <errno.h>
10#if defined (HAVE_UNISTD_H)
11# ifdef _MINIX
12# include <sys/types.h>
13# endif
14# include <unistd.h>
15#endif
16
17#include "../bashansi.h"
18#include "../bashintl.h"
19
20#include <signal.h>
21
22#include "../shell.h"
23#include "../trap.h"
24#include "../jobs.h"
25#include "common.h"
26
27/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
28#if !defined (errno)
Ricardo Cerqueiraa02fbff2013-07-25 22:35:34 +010029#include <errno.h>
Dan Pasanenc6e37862014-10-02 14:08:59 -050030#endif /* !errno */
31
32extern int posixly_correct;
33
34static void kill_error __P((pid_t, int));
35
36#if !defined (CONTINUE_AFTER_KILL_ERROR)
37# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
38#else
39# define CONTINUE_OR_FAIL goto continue_killing
40#endif /* CONTINUE_AFTER_KILL_ERROR */
41
42/* Here is the kill builtin. We only have it so that people can type
43 kill -KILL %1? No, if you fill up the process table this way you
44 can still kill some. */
45int
46kill_builtin (list)
47 WORD_LIST *list;
48{
49 int sig, any_succeeded, listing, saw_signal, dflags;
50 char *sigspec, *word;
51 pid_t pid;
52 intmax_t pid_value;
53
54 if (list == 0)
55 {
56 builtin_usage ();
57 return (EX_USAGE);
58 }
59
60 any_succeeded = listing = saw_signal = 0;
61 sig = SIGTERM;
62 sigspec = "TERM";
63
64 dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0);
65 /* Process options. */
66 while (list)
67 {
68 word = list->word->word;
69
70 if (ISOPTION (word, 'l'))
71 {
72 listing++;
73 list = list->next;
74 }
75 else if (ISOPTION (word, 's') || ISOPTION (word, 'n'))
76 {
77 list = list->next;
78 if (list)
79 {
80 sigspec = list->word->word;
81 if (sigspec[0] == '0' && sigspec[1] == '\0')
82 sig = 0;
83 else
84 sig = decode_signal (sigspec, dflags);
85 list = list->next;
86 saw_signal++;
87 }
88 else
89 {
90 sh_needarg (word);
91 return (EXECUTION_FAILURE);
92 }
93 }
94 else if (ISOPTION (word, '-'))
95 {
96 list = list->next;
97 break;
98 }
99 else if (ISOPTION (word, '?'))
100 {
101 builtin_usage ();
102 return (EX_USAGE);
103 }
104 /* If this is a signal specification then process it. We only process
105 the first one seen; other arguments may signify process groups (e.g,
106 -num == process group num). */
107 else if (*word == '-' && saw_signal == 0)
108 {
109 sigspec = word + 1;
110 sig = decode_signal (sigspec, dflags);
111 saw_signal++;
112 list = list->next;
113 }
114 else
115 break;
116 }
117
118 if (listing)
119 return (display_signal_list (list, 0));
120
121 /* OK, we are killing processes. */
122 if (sig == NO_SIG)
123 {
124 sh_invalidsig (sigspec);
125 return (EXECUTION_FAILURE);
126 }
127
128 if (list == 0)
129 {
130 builtin_usage ();
131 return (EX_USAGE);
132 }
133
134 while (list)
135 {
136 word = list->word->word;
137
138 if (*word == '-')
139 word++;
140
141 /* Use the entire argument in case of minus sign presence. */
142 if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
143 {
144 pid = (pid_t) pid_value;
145
146 if (kill_pid (pid, sig, pid < -1) < 0)
147 {
148 if (errno == EINVAL)
149 sh_invalidsig (sigspec);
150 else
151 kill_error (pid, errno);
152 CONTINUE_OR_FAIL;
153 }
154 else
155 any_succeeded++;
156 }
157#if defined (JOB_CONTROL)
158 else if (*list->word->word && *list->word->word != '%')
159 {
160 builtin_error (_("%s: arguments must be process or job IDs"), list->word->word);
161 CONTINUE_OR_FAIL;
162 }
163 else if (*word)
164 /* Posix.2 says you can kill without job control active (4.32.4) */
165 { /* Must be a job spec. Check it out. */
166 int job;
167 sigset_t set, oset;
168 JOB *j;
169
170 BLOCK_CHILD (set, oset);
171 job = get_job_spec (list);
172
173 if (INVALID_JOB (job))
174 {
175 if (job != DUP_JOB)
176 sh_badjob (list->word->word);
177 UNBLOCK_CHILD (oset);
178 CONTINUE_OR_FAIL;
179 }
180
181 j = get_job_by_jid (job);
182 /* Job spec used. Kill the process group. If the job was started
183 without job control, then its pgrp == shell_pgrp, so we have
184 to be careful. We take the pid of the first job in the pipeline
185 in that case. */
186 pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
187
188 UNBLOCK_CHILD (oset);
189
190 if (kill_pid (pid, sig, 1) < 0)
191 {
192 if (errno == EINVAL)
193 sh_invalidsig (sigspec);
194 else
195 kill_error (pid, errno);
196 CONTINUE_OR_FAIL;
197 }
198 else
199 any_succeeded++;
200 }
201#endif /* !JOB_CONTROL */
202 else
203 {
204 sh_badpid (list->word->word);
205 CONTINUE_OR_FAIL;
206 }
207 continue_killing:
208 list = list->next;
209 }
210
211 return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
212}
213
214static void
215kill_error (pid, e)
216 pid_t pid;
217 int e;
218{
219 char *x;
220
221 x = strerror (e);
222 if (x == 0)
223 x = _("Unknown error");
224 builtin_error ("(%ld) - %s", (long)pid, x);
225}