]>
Commit | Line | Data |
---|---|---|
3185942a | 1 | /* nojobs.c - functions that make children, remember them, and handle their termination. */ |
726f6388 | 2 | |
ccc6cda3 JA |
3 | /* This file works under BSD, System V, minix, and Posix systems. It does |
4 | not implement job control. */ | |
726f6388 | 5 | |
ac50fbac | 6 | /* Copyright (C) 1987-2011 Free Software Foundation, Inc. |
726f6388 JA |
7 | |
8 | This file is part of GNU Bash, the Bourne Again SHell. | |
9 | ||
3185942a JA |
10 | Bash is free software: you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | |
12 | the Free Software Foundation, either version 3 of the License, or | |
13 | (at your option) any later version. | |
726f6388 | 14 | |
3185942a JA |
15 | Bash is distributed in the hope that it will be useful, |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | GNU General Public License for more details. | |
726f6388 | 19 | |
3185942a JA |
20 | You should have received a copy of the GNU General Public License |
21 | along with Bash. If not, see <http://www.gnu.org/licenses/>. | |
22 | */ | |
726f6388 | 23 | |
ccc6cda3 JA |
24 | #include "config.h" |
25 | ||
726f6388 | 26 | #include "bashtypes.h" |
ccc6cda3 JA |
27 | #include "filecntl.h" |
28 | ||
29 | #if defined (HAVE_UNISTD_H) | |
30 | # include <unistd.h> | |
31 | #endif | |
32 | ||
33 | #include <stdio.h> | |
726f6388 | 34 | #include <signal.h> |
726f6388 JA |
35 | #include <errno.h> |
36 | ||
726f6388 JA |
37 | #if defined (BUFFERED_INPUT) |
38 | # include "input.h" | |
39 | #endif | |
40 | ||
bb70624e JA |
41 | /* Need to include this up here for *_TTY_DRIVER definitions. */ |
42 | #include "shtty.h" | |
ccc6cda3 | 43 | |
b80f6443 JA |
44 | #include "bashintl.h" |
45 | ||
bb70624e JA |
46 | #include "shell.h" |
47 | #include "jobs.h" | |
17345e5a | 48 | #include "execute_cmd.h" |
bb70624e JA |
49 | |
50 | #include "builtins/builtext.h" /* for wait_builtin */ | |
51 | ||
7117c2d2 | 52 | #define DEFAULT_CHILD_MAX 32 |
bb70624e | 53 | |
ccc6cda3 | 54 | #if defined (_POSIX_VERSION) || !defined (HAVE_KILLPG) |
726f6388 JA |
55 | # define killpg(pg, sig) kill(-(pg),(sig)) |
56 | #endif /* USG || _POSIX_VERSION */ | |
57 | ||
b80f6443 | 58 | #if !defined (HAVE_SIGINTERRUPT) && !defined (HAVE_POSIX_SIGNALS) |
726f6388 | 59 | # define siginterrupt(sig, code) |
b80f6443 | 60 | #endif /* !HAVE_SIGINTERRUPT && !HAVE_POSIX_SIGNALS */ |
726f6388 | 61 | |
ccc6cda3 | 62 | #if defined (HAVE_WAITPID) |
726f6388 JA |
63 | # define WAITPID(pid, statusp, options) waitpid (pid, statusp, options) |
64 | #else | |
65 | # define WAITPID(pid, statusp, options) wait (statusp) | |
ccc6cda3 | 66 | #endif /* !HAVE_WAITPID */ |
726f6388 | 67 | |
d166f048 JA |
68 | /* Return the fd from which we are actually getting input. */ |
69 | #define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr) | |
70 | ||
726f6388 JA |
71 | #if !defined (errno) |
72 | extern int errno; | |
73 | #endif /* !errno */ | |
74 | ||
75 | extern int interactive, interactive_shell, login_shell; | |
76 | extern int subshell_environment; | |
b80f6443 | 77 | extern int last_command_exit_value, last_command_exit_signal; |
bb70624e | 78 | extern int interrupt_immediately; |
f73dda09 | 79 | extern sh_builtin_func_t *this_shell_builtin; |
ccc6cda3 | 80 | #if defined (HAVE_POSIX_SIGNALS) |
726f6388 JA |
81 | extern sigset_t top_level_mask; |
82 | #endif | |
bb70624e | 83 | extern procenv_t wait_intr_buf; |
7117c2d2 | 84 | extern int wait_signal_received; |
726f6388 | 85 | |
ac50fbac CR |
86 | volatile pid_t last_made_pid = NO_PID; |
87 | volatile pid_t last_asynchronous_pid = NO_PID; | |
726f6388 JA |
88 | |
89 | /* Call this when you start making children. */ | |
90 | int already_making_children = 0; | |
91 | ||
d166f048 JA |
92 | /* The controlling tty for this shell. */ |
93 | int shell_tty = -1; | |
94 | ||
ccc6cda3 JA |
95 | /* If this is non-zero, $LINES and $COLUMNS are reset after every process |
96 | exits from get_tty_state(). */ | |
ac50fbac CR |
97 | int check_window_size = CHECKWINSIZE_DEFAULT; |
98 | ||
99 | /* We don't have job control. */ | |
100 | int job_control = 0; | |
ccc6cda3 | 101 | |
bb70624e JA |
102 | /* STATUS and FLAGS are only valid if pid != NO_PID |
103 | STATUS is only valid if (flags & PROC_RUNNING) == 0 */ | |
726f6388 JA |
104 | struct proc_status { |
105 | pid_t pid; | |
106 | int status; /* Exit status of PID or 128 + fatal signal number */ | |
bb70624e | 107 | int flags; |
726f6388 JA |
108 | }; |
109 | ||
bb70624e JA |
110 | /* Values for proc_status.flags */ |
111 | #define PROC_RUNNING 0x01 | |
112 | #define PROC_NOTIFIED 0x02 | |
113 | #define PROC_ASYNC 0x04 | |
b80f6443 | 114 | #define PROC_SIGNALED 0x10 |
bb70624e | 115 | |
bb70624e JA |
116 | /* Return values from find_status_by_pid */ |
117 | #define PROC_BAD -1 | |
726f6388 JA |
118 | #define PROC_STILL_ALIVE -2 |
119 | ||
f73dda09 JA |
120 | static struct proc_status *pid_list = (struct proc_status *)NULL; |
121 | static int pid_list_size; | |
122 | static int wait_sigint_received; | |
123 | ||
7117c2d2 JA |
124 | static long child_max = -1L; |
125 | ||
f73dda09 JA |
126 | static void alloc_pid_list __P((void)); |
127 | static int find_proc_slot __P((void)); | |
128 | static int find_index_by_pid __P((pid_t)); | |
129 | static int find_status_by_pid __P((pid_t)); | |
130 | static int process_exit_status __P((WAIT)); | |
b80f6443 JA |
131 | static int find_termsig_by_pid __P((pid_t)); |
132 | static int get_termsig __P((WAIT)); | |
f73dda09 JA |
133 | static void set_pid_status __P((pid_t, WAIT)); |
134 | static void set_pid_flags __P((pid_t, int)); | |
135 | static void unset_pid_flags __P((pid_t, int)); | |
b80f6443 | 136 | static int get_pid_flags __P((pid_t)); |
f73dda09 JA |
137 | static void add_pid __P((pid_t, int)); |
138 | static void mark_dead_jobs_as_notified __P((int)); | |
139 | ||
7117c2d2 | 140 | static sighandler wait_sigint_handler __P((int)); |
b80f6443 | 141 | static char *j_strsignal __P((int)); |
f73dda09 JA |
142 | |
143 | #if defined (HAVE_WAITPID) | |
144 | static void reap_zombie_children __P((void)); | |
145 | #endif | |
146 | ||
b80f6443 JA |
147 | #if !defined (HAVE_SIGINTERRUPT) && defined (HAVE_POSIX_SIGNALS) |
148 | static int siginterrupt __P((int, int)); | |
149 | #endif | |
150 | ||
f73dda09 JA |
151 | static void restore_sigint_handler __P((void)); |
152 | ||
726f6388 JA |
153 | /* Allocate new, or grow existing PID_LIST. */ |
154 | static void | |
155 | alloc_pid_list () | |
156 | { | |
157 | register int i; | |
158 | int old = pid_list_size; | |
159 | ||
160 | pid_list_size += 10; | |
f73dda09 | 161 | pid_list = (struct proc_status *)xrealloc (pid_list, pid_list_size * sizeof (struct proc_status)); |
726f6388 JA |
162 | |
163 | /* None of the newly allocated slots have process id's yet. */ | |
164 | for (i = old; i < pid_list_size; i++) | |
ccc6cda3 | 165 | pid_list[i].pid = NO_PID; |
726f6388 JA |
166 | } |
167 | ||
168 | /* Return the offset within the PID_LIST array of an empty slot. This can | |
169 | create new slots if all of the existing slots are taken. */ | |
170 | static int | |
171 | find_proc_slot () | |
172 | { | |
173 | register int i; | |
174 | ||
175 | for (i = 0; i < pid_list_size; i++) | |
176 | if (pid_list[i].pid == NO_PID) | |
177 | return (i); | |
178 | ||
179 | if (i == pid_list_size) | |
180 | alloc_pid_list (); | |
181 | ||
182 | return (i); | |
183 | } | |
184 | ||
185 | /* Return the offset within the PID_LIST array of a slot containing PID, | |
186 | or the value NO_PID if the pid wasn't found. */ | |
187 | static int | |
188 | find_index_by_pid (pid) | |
189 | pid_t pid; | |
190 | { | |
191 | register int i; | |
192 | ||
193 | for (i = 0; i < pid_list_size; i++) | |
194 | if (pid_list[i].pid == pid) | |
195 | return (i); | |
196 | ||
197 | return (NO_PID); | |
198 | } | |
199 | ||
200 | /* Return the status of PID as looked up in the PID_LIST array. A | |
201 | return value of PROC_BAD indicates that PID wasn't found. */ | |
202 | static int | |
203 | find_status_by_pid (pid) | |
204 | pid_t pid; | |
205 | { | |
206 | int i; | |
207 | ||
208 | i = find_index_by_pid (pid); | |
209 | if (i == NO_PID) | |
210 | return (PROC_BAD); | |
bb70624e JA |
211 | if (pid_list[i].flags & PROC_RUNNING) |
212 | return (PROC_STILL_ALIVE); | |
726f6388 JA |
213 | return (pid_list[i].status); |
214 | } | |
215 | ||
bb70624e JA |
216 | static int |
217 | process_exit_status (status) | |
218 | WAIT status; | |
219 | { | |
220 | if (WIFSIGNALED (status)) | |
221 | return (128 + WTERMSIG (status)); | |
222 | else | |
223 | return (WEXITSTATUS (status)); | |
224 | } | |
225 | ||
b80f6443 JA |
226 | /* Return the status of PID as looked up in the PID_LIST array. A |
227 | return value of PROC_BAD indicates that PID wasn't found. */ | |
228 | static int | |
229 | find_termsig_by_pid (pid) | |
230 | pid_t pid; | |
231 | { | |
232 | int i; | |
233 | ||
234 | i = find_index_by_pid (pid); | |
235 | if (i == NO_PID) | |
236 | return (0); | |
237 | if (pid_list[i].flags & PROC_RUNNING) | |
238 | return (0); | |
3185942a | 239 | return (get_termsig ((WAIT)pid_list[i].status)); |
b80f6443 JA |
240 | } |
241 | ||
242 | /* Set LAST_COMMAND_EXIT_SIGNAL depending on STATUS. If STATUS is -1, look | |
243 | up PID in the pid array and set LAST_COMMAND_EXIT_SIGNAL appropriately | |
244 | depending on its flags and exit status. */ | |
245 | static int | |
246 | get_termsig (status) | |
247 | WAIT status; | |
248 | { | |
249 | if (WIFSTOPPED (status) == 0 && WIFSIGNALED (status)) | |
250 | return (WTERMSIG (status)); | |
251 | else | |
252 | return (0); | |
253 | } | |
254 | ||
726f6388 JA |
255 | /* Give PID the status value STATUS in the PID_LIST array. */ |
256 | static void | |
257 | set_pid_status (pid, status) | |
258 | pid_t pid; | |
259 | WAIT status; | |
260 | { | |
261 | int slot; | |
262 | ||
17345e5a JA |
263 | #if defined (COPROCESS_SUPPORT) |
264 | coproc_pidchk (pid, status); | |
265 | #endif | |
266 | ||
726f6388 JA |
267 | slot = find_index_by_pid (pid); |
268 | if (slot == NO_PID) | |
269 | return; | |
270 | ||
bb70624e JA |
271 | pid_list[slot].status = process_exit_status (status); |
272 | pid_list[slot].flags &= ~PROC_RUNNING; | |
b80f6443 JA |
273 | if (WIFSIGNALED (status)) |
274 | pid_list[slot].flags |= PROC_SIGNALED; | |
bb70624e JA |
275 | /* If it's not a background process, mark it as notified so it gets |
276 | cleaned up. */ | |
277 | if ((pid_list[slot].flags & PROC_ASYNC) == 0) | |
278 | pid_list[slot].flags |= PROC_NOTIFIED; | |
279 | } | |
280 | ||
281 | /* Give PID the flags FLAGS in the PID_LIST array. */ | |
282 | static void | |
283 | set_pid_flags (pid, flags) | |
284 | pid_t pid; | |
285 | int flags; | |
286 | { | |
287 | int slot; | |
288 | ||
289 | slot = find_index_by_pid (pid); | |
290 | if (slot == NO_PID) | |
291 | return; | |
292 | ||
293 | pid_list[slot].flags |= flags; | |
294 | } | |
295 | ||
296 | /* Unset FLAGS for PID in the pid list */ | |
297 | static void | |
298 | unset_pid_flags (pid, flags) | |
299 | pid_t pid; | |
300 | int flags; | |
301 | { | |
302 | int slot; | |
303 | ||
304 | slot = find_index_by_pid (pid); | |
305 | if (slot == NO_PID) | |
306 | return; | |
307 | ||
308 | pid_list[slot].flags &= ~flags; | |
726f6388 JA |
309 | } |
310 | ||
b80f6443 JA |
311 | /* Return the flags corresponding to PID in the PID_LIST array. */ |
312 | static int | |
313 | get_pid_flags (pid) | |
314 | pid_t pid; | |
315 | { | |
316 | int slot; | |
317 | ||
318 | slot = find_index_by_pid (pid); | |
319 | if (slot == NO_PID) | |
320 | return 0; | |
321 | ||
322 | return (pid_list[slot].flags); | |
323 | } | |
324 | ||
726f6388 | 325 | static void |
bb70624e | 326 | add_pid (pid, async) |
726f6388 | 327 | pid_t pid; |
bb70624e | 328 | int async; |
726f6388 JA |
329 | { |
330 | int slot; | |
331 | ||
332 | slot = find_proc_slot (); | |
bb70624e | 333 | |
726f6388 | 334 | pid_list[slot].pid = pid; |
bb70624e JA |
335 | pid_list[slot].status = -1; |
336 | pid_list[slot].flags = PROC_RUNNING; | |
337 | if (async) | |
338 | pid_list[slot].flags |= PROC_ASYNC; | |
339 | } | |
340 | ||
341 | static void | |
342 | mark_dead_jobs_as_notified (force) | |
343 | int force; | |
344 | { | |
345 | register int i, ndead; | |
346 | ||
347 | /* first, count the number of non-running async jobs if FORCE == 0 */ | |
348 | for (i = ndead = 0; force == 0 && i < pid_list_size; i++) | |
349 | { | |
350 | if (pid_list[i].pid == NO_PID) | |
351 | continue; | |
352 | if (((pid_list[i].flags & PROC_RUNNING) == 0) && | |
353 | (pid_list[i].flags & PROC_ASYNC)) | |
28ef6c31 | 354 | ndead++; |
bb70624e JA |
355 | } |
356 | ||
7117c2d2 JA |
357 | if (child_max < 0) |
358 | child_max = getmaxchild (); | |
359 | if (child_max < 0) | |
360 | child_max = DEFAULT_CHILD_MAX; | |
361 | ||
362 | if (force == 0 && ndead <= child_max) | |
bb70624e JA |
363 | return; |
364 | ||
365 | /* If FORCE == 0, we just mark as many non-running async jobs as notified | |
366 | to bring us under the CHILD_MAX limit. */ | |
367 | for (i = 0; i < pid_list_size; i++) | |
368 | { | |
369 | if (pid_list[i].pid == NO_PID) | |
370 | continue; | |
371 | if (((pid_list[i].flags & PROC_RUNNING) == 0) && | |
372 | pid_list[i].pid != last_asynchronous_pid) | |
373 | { | |
374 | pid_list[i].flags |= PROC_NOTIFIED; | |
7117c2d2 | 375 | if (force == 0 && (pid_list[i].flags & PROC_ASYNC) && --ndead <= child_max) |
bb70624e JA |
376 | break; |
377 | } | |
378 | } | |
726f6388 JA |
379 | } |
380 | ||
bb70624e | 381 | /* Remove all dead, notified jobs from the pid_list. */ |
726f6388 JA |
382 | int |
383 | cleanup_dead_jobs () | |
384 | { | |
385 | register int i; | |
386 | ||
ccc6cda3 | 387 | #if defined (HAVE_WAITPID) |
726f6388 JA |
388 | reap_zombie_children (); |
389 | #endif | |
390 | ||
391 | for (i = 0; i < pid_list_size; i++) | |
bb70624e JA |
392 | { |
393 | if ((pid_list[i].flags & PROC_RUNNING) == 0 && | |
394 | (pid_list[i].flags & PROC_NOTIFIED)) | |
395 | pid_list[i].pid = NO_PID; | |
396 | } | |
397 | ||
17345e5a JA |
398 | #if defined (COPROCESS_SUPPORT) |
399 | coproc_reap (); | |
400 | #endif | |
401 | ||
bb70624e JA |
402 | return 0; |
403 | } | |
404 | ||
405 | void | |
406 | reap_dead_jobs () | |
407 | { | |
408 | mark_dead_jobs_as_notified (0); | |
409 | cleanup_dead_jobs (); | |
726f6388 JA |
410 | } |
411 | ||
412 | /* Initialize the job control mechanism, and set up the tty stuff. */ | |
d166f048 JA |
413 | initialize_job_control (force) |
414 | int force; | |
726f6388 | 415 | { |
d166f048 JA |
416 | shell_tty = fileno (stderr); |
417 | ||
418 | if (interactive) | |
419 | get_tty_state (); | |
726f6388 JA |
420 | } |
421 | ||
726f6388 JA |
422 | /* Setup this shell to handle C-C, etc. */ |
423 | void | |
424 | initialize_job_signals () | |
425 | { | |
426 | set_signal_handler (SIGINT, sigint_sighandler); | |
726f6388 JA |
427 | |
428 | /* If this is a login shell we don't wish to be disturbed by | |
429 | stop signals. */ | |
430 | if (login_shell) | |
ccc6cda3 | 431 | ignore_tty_job_signals (); |
726f6388 JA |
432 | } |
433 | ||
ccc6cda3 | 434 | #if defined (HAVE_WAITPID) |
726f6388 JA |
435 | /* Collect the status of all zombie children so that their system |
436 | resources can be deallocated. */ | |
437 | static void | |
438 | reap_zombie_children () | |
439 | { | |
b80f6443 | 440 | # if defined (WNOHANG) |
726f6388 JA |
441 | pid_t pid; |
442 | WAIT status; | |
443 | ||
0628567a | 444 | CHECK_TERMSIG; |
ac50fbac | 445 | CHECK_WAIT_INTR; |
726f6388 JA |
446 | while ((pid = waitpid (-1, (int *)&status, WNOHANG)) > 0) |
447 | set_pid_status (pid, status); | |
b80f6443 | 448 | # endif /* WNOHANG */ |
0628567a | 449 | CHECK_TERMSIG; |
ac50fbac | 450 | CHECK_WAIT_INTR; |
726f6388 | 451 | } |
b80f6443 JA |
452 | #endif /* WAITPID */ |
453 | ||
454 | #if !defined (HAVE_SIGINTERRUPT) && defined (HAVE_POSIX_SIGNALS) | |
ac50fbac CR |
455 | |
456 | #if !defined (SA_RESTART) | |
457 | # define SA_RESTART 0 | |
458 | #endif | |
459 | ||
b80f6443 JA |
460 | static int |
461 | siginterrupt (sig, flag) | |
462 | int sig, flag; | |
463 | { | |
464 | struct sigaction act; | |
465 | ||
466 | sigaction (sig, (struct sigaction *)NULL, &act); | |
467 | ||
468 | if (flag) | |
469 | act.sa_flags &= ~SA_RESTART; | |
470 | else | |
471 | act.sa_flags |= SA_RESTART; | |
472 | ||
473 | return (sigaction (sig, &act, (struct sigaction *)NULL)); | |
474 | } | |
475 | #endif /* !HAVE_SIGINTERRUPT && HAVE_POSIX_SIGNALS */ | |
726f6388 JA |
476 | |
477 | /* Fork, handling errors. Returns the pid of the newly made child, or 0. | |
478 | COMMAND is just for remembering the name of the command; we don't do | |
479 | anything else with it. ASYNC_P says what to do with the tty. If | |
480 | non-zero, then don't give it away. */ | |
481 | pid_t | |
482 | make_child (command, async_p) | |
483 | char *command; | |
484 | int async_p; | |
485 | { | |
486 | pid_t pid; | |
3185942a | 487 | int forksleep; |
726f6388 JA |
488 | |
489 | /* Discard saved memory. */ | |
ccc6cda3 | 490 | if (command) |
726f6388 JA |
491 | free (command); |
492 | ||
493 | start_pipeline (); | |
494 | ||
495 | #if defined (BUFFERED_INPUT) | |
496 | /* If default_buffered_input is active, we are reading a script. If | |
497 | the command is asynchronous, we have already duplicated /dev/null | |
498 | as fd 0, but have not changed the buffered stream corresponding to | |
499 | the old fd 0. We don't want to sync the stream in this case. */ | |
cce855bc | 500 | if (default_buffered_input != -1 && (!async_p || default_buffered_input > 0)) |
726f6388 JA |
501 | sync_buffered_stream (default_buffered_input); |
502 | #endif /* BUFFERED_INPUT */ | |
503 | ||
ac50fbac CR |
504 | /* XXX - block SIGTERM here and unblock in child after fork resets the |
505 | set of pending signals? */ | |
506 | RESET_SIGTERM; | |
507 | ||
3185942a JA |
508 | /* Create the child, handle severe errors. Retry on EAGAIN. */ |
509 | forksleep = 1; | |
510 | while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX) | |
726f6388 | 511 | { |
3185942a | 512 | sys_error ("fork: retry"); |
ac50fbac CR |
513 | RESET_SIGTERM; |
514 | ||
ccc6cda3 | 515 | #if defined (HAVE_WAITPID) |
726f6388 JA |
516 | /* Posix systems with a non-blocking waitpid () system call available |
517 | get another chance after zombies are reaped. */ | |
3185942a JA |
518 | reap_zombie_children (); |
519 | if (forksleep > 1 && sleep (forksleep) != 0) | |
520 | break; | |
521 | #else | |
522 | if (sleep (forksleep) != 0) | |
523 | break; | |
ccc6cda3 | 524 | #endif /* HAVE_WAITPID */ |
3185942a JA |
525 | forksleep <<= 1; |
526 | } | |
726f6388 | 527 | |
ac50fbac CR |
528 | if (pid != 0) |
529 | RESET_SIGTERM; | |
530 | ||
3185942a JA |
531 | if (pid < 0) |
532 | { | |
ccc6cda3 | 533 | sys_error ("fork"); |
ac50fbac | 534 | last_command_exit_value = EX_NOEXEC; |
726f6388 JA |
535 | throw_to_top_level (); |
536 | } | |
ccc6cda3 | 537 | |
726f6388 JA |
538 | if (pid == 0) |
539 | { | |
540 | #if defined (BUFFERED_INPUT) | |
cce855bc | 541 | unset_bash_input (0); |
726f6388 JA |
542 | #endif /* BUFFERED_INPUT */ |
543 | ||
ccc6cda3 | 544 | #if defined (HAVE_POSIX_SIGNALS) |
726f6388 JA |
545 | /* Restore top-level signal mask. */ |
546 | sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL); | |
547 | #endif | |
548 | ||
3185942a | 549 | #if 0 |
726f6388 JA |
550 | /* Ignore INT and QUIT in asynchronous children. */ |
551 | if (async_p) | |
ccc6cda3 | 552 | last_asynchronous_pid = getpid (); |
3185942a | 553 | #endif |
726f6388 | 554 | |
ccc6cda3 | 555 | default_tty_job_signals (); |
726f6388 JA |
556 | } |
557 | else | |
558 | { | |
559 | /* In the parent. */ | |
560 | ||
561 | last_made_pid = pid; | |
562 | ||
563 | if (async_p) | |
564 | last_asynchronous_pid = pid; | |
565 | ||
bb70624e | 566 | add_pid (pid, async_p); |
726f6388 JA |
567 | } |
568 | return (pid); | |
569 | } | |
570 | ||
ccc6cda3 JA |
571 | void |
572 | ignore_tty_job_signals () | |
573 | { | |
574 | #if defined (SIGTSTP) | |
575 | set_signal_handler (SIGTSTP, SIG_IGN); | |
576 | set_signal_handler (SIGTTIN, SIG_IGN); | |
577 | set_signal_handler (SIGTTOU, SIG_IGN); | |
578 | #endif | |
579 | } | |
580 | ||
581 | void | |
582 | default_tty_job_signals () | |
583 | { | |
584 | #if defined (SIGTSTP) | |
585 | set_signal_handler (SIGTSTP, SIG_DFL); | |
586 | set_signal_handler (SIGTTIN, SIG_DFL); | |
587 | set_signal_handler (SIGTTOU, SIG_DFL); | |
588 | #endif | |
589 | } | |
590 | ||
bb70624e JA |
591 | /* Wait for a single pid (PID) and return its exit status. Called by |
592 | the wait builtin. */ | |
f73dda09 | 593 | int |
726f6388 JA |
594 | wait_for_single_pid (pid) |
595 | pid_t pid; | |
596 | { | |
597 | pid_t got_pid; | |
598 | WAIT status; | |
b80f6443 | 599 | int pstatus, flags; |
726f6388 JA |
600 | |
601 | pstatus = find_status_by_pid (pid); | |
602 | ||
603 | if (pstatus == PROC_BAD) | |
ccc6cda3 | 604 | { |
b80f6443 | 605 | internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid); |
ccc6cda3 JA |
606 | return (127); |
607 | } | |
726f6388 JA |
608 | |
609 | if (pstatus != PROC_STILL_ALIVE) | |
b80f6443 JA |
610 | { |
611 | if (pstatus > 128) | |
612 | last_command_exit_signal = find_termsig_by_pid (pid); | |
613 | return (pstatus); | |
614 | } | |
726f6388 JA |
615 | |
616 | siginterrupt (SIGINT, 1); | |
617 | while ((got_pid = WAITPID (pid, &status, 0)) != pid) | |
618 | { | |
0628567a | 619 | CHECK_TERMSIG; |
ac50fbac | 620 | CHECK_WAIT_INTR; |
726f6388 JA |
621 | if (got_pid < 0) |
622 | { | |
623 | if (errno != EINTR && errno != ECHILD) | |
624 | { | |
625 | siginterrupt (SIGINT, 0); | |
ccc6cda3 | 626 | sys_error ("wait"); |
726f6388 JA |
627 | } |
628 | break; | |
629 | } | |
630 | else if (got_pid > 0) | |
28ef6c31 | 631 | set_pid_status (got_pid, status); |
726f6388 JA |
632 | } |
633 | ||
7117c2d2 JA |
634 | if (got_pid > 0) |
635 | { | |
636 | set_pid_status (got_pid, status); | |
637 | set_pid_flags (got_pid, PROC_NOTIFIED); | |
638 | } | |
bb70624e | 639 | |
726f6388 JA |
640 | siginterrupt (SIGINT, 0); |
641 | QUIT; | |
642 | ||
7117c2d2 | 643 | return (got_pid > 0 ? process_exit_status (status) : -1); |
726f6388 JA |
644 | } |
645 | ||
bb70624e JA |
646 | /* Wait for all of the shell's children to exit. Called by the `wait' |
647 | builtin. */ | |
726f6388 JA |
648 | void |
649 | wait_for_background_pids () | |
650 | { | |
651 | pid_t got_pid; | |
652 | WAIT status; | |
653 | ||
654 | /* If we aren't using job control, we let the kernel take care of the | |
ccc6cda3 | 655 | bookkeeping for us. wait () will return -1 and set errno to ECHILD |
726f6388 JA |
656 | when there are no more unwaited-for child processes on both |
657 | 4.2 BSD-based and System V-based systems. */ | |
658 | ||
659 | siginterrupt (SIGINT, 1); | |
660 | ||
661 | /* Wait for ECHILD */ | |
662 | while ((got_pid = WAITPID (-1, &status, 0)) != -1) | |
663 | set_pid_status (got_pid, status); | |
664 | ||
665 | if (errno != EINTR && errno != ECHILD) | |
666 | { | |
667 | siginterrupt (SIGINT, 0); | |
ccc6cda3 | 668 | sys_error("wait"); |
726f6388 JA |
669 | } |
670 | ||
671 | siginterrupt (SIGINT, 0); | |
672 | QUIT; | |
bb70624e JA |
673 | |
674 | mark_dead_jobs_as_notified (1); | |
675 | cleanup_dead_jobs (); | |
676 | } | |
677 | ||
678 | /* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */ | |
679 | #define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids | |
680 | static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER; | |
681 | ||
682 | static void | |
683 | restore_sigint_handler () | |
684 | { | |
685 | if (old_sigint_handler != INVALID_SIGNAL_HANDLER) | |
686 | { | |
687 | set_signal_handler (SIGINT, old_sigint_handler); | |
688 | old_sigint_handler = INVALID_SIGNAL_HANDLER; | |
689 | } | |
726f6388 JA |
690 | } |
691 | ||
692 | /* Handle SIGINT while we are waiting for children in a script to exit. | |
693 | All interrupts are effectively ignored by the shell, but allowed to | |
694 | kill a running job. */ | |
695 | static sighandler | |
696 | wait_sigint_handler (sig) | |
697 | int sig; | |
698 | { | |
bb70624e JA |
699 | SigHandler *sigint_handler; |
700 | ||
701 | /* If we got a SIGINT while in `wait', and SIGINT is trapped, do | |
702 | what POSIX.2 says (see builtins/wait.def for more info). */ | |
703 | if (this_shell_builtin && this_shell_builtin == wait_builtin && | |
704 | signal_is_trapped (SIGINT) && | |
705 | ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler)) | |
706 | { | |
ac50fbac | 707 | last_command_exit_value = 128+SIGINT; |
bb70624e JA |
708 | restore_sigint_handler (); |
709 | interrupt_immediately = 0; | |
710 | trap_handler (SIGINT); /* set pending_traps[SIGINT] */ | |
7117c2d2 | 711 | wait_signal_received = SIGINT; |
ac50fbac | 712 | SIGRETURN (0); |
bb70624e JA |
713 | } |
714 | ||
28ef6c31 JA |
715 | if (interrupt_immediately) |
716 | { | |
717 | last_command_exit_value = EXECUTION_FAILURE; | |
718 | restore_sigint_handler (); | |
719 | ADDINTERRUPT; | |
720 | QUIT; | |
721 | } | |
726f6388 | 722 | |
bb70624e JA |
723 | wait_sigint_received = 1; |
724 | ||
ccc6cda3 | 725 | SIGRETURN (0); |
726f6388 JA |
726 | } |
727 | ||
b80f6443 JA |
728 | static char * |
729 | j_strsignal (s) | |
730 | int s; | |
731 | { | |
732 | static char retcode_name_buffer[64] = { '\0' }; | |
733 | char *x; | |
734 | ||
735 | x = strsignal (s); | |
736 | if (x == 0) | |
737 | { | |
738 | x = retcode_name_buffer; | |
739 | sprintf (x, "Signal %d", s); | |
740 | } | |
741 | return x; | |
742 | } | |
743 | ||
726f6388 JA |
744 | /* Wait for pid (one of our children) to terminate. This is called only |
745 | by the execution code in execute_cmd.c. */ | |
746 | int | |
747 | wait_for (pid) | |
748 | pid_t pid; | |
749 | { | |
750 | int return_val, pstatus; | |
751 | pid_t got_pid; | |
752 | WAIT status; | |
726f6388 JA |
753 | |
754 | pstatus = find_status_by_pid (pid); | |
755 | ||
756 | if (pstatus == PROC_BAD) | |
757 | return (0); | |
758 | ||
759 | if (pstatus != PROC_STILL_ALIVE) | |
b80f6443 JA |
760 | { |
761 | if (pstatus > 128) | |
762 | last_command_exit_signal = find_termsig_by_pid (pid); | |
763 | return (pstatus); | |
764 | } | |
726f6388 JA |
765 | |
766 | /* If we are running a script, ignore SIGINT while we're waiting for | |
767 | a child to exit. The loop below does some of this, but not all. */ | |
bb70624e JA |
768 | wait_sigint_received = 0; |
769 | if (interactive_shell == 0) | |
726f6388 JA |
770 | old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler); |
771 | ||
772 | while ((got_pid = WAITPID (-1, &status, 0)) != pid) /* XXX was pid now -1 */ | |
773 | { | |
0628567a | 774 | CHECK_TERMSIG; |
ac50fbac | 775 | CHECK_WAIT_INTR; |
726f6388 JA |
776 | if (got_pid < 0 && errno == ECHILD) |
777 | { | |
778 | #if !defined (_POSIX_VERSION) | |
779 | status.w_termsig = status.w_retcode = 0; | |
780 | #else | |
781 | status = 0; | |
782 | #endif /* _POSIX_VERSION */ | |
783 | break; | |
784 | } | |
785 | else if (got_pid < 0 && errno != EINTR) | |
f73dda09 | 786 | programming_error ("wait_for(%ld): %s", (long)pid, strerror(errno)); |
726f6388 JA |
787 | else if (got_pid > 0) |
788 | set_pid_status (got_pid, status); | |
789 | } | |
790 | ||
7117c2d2 JA |
791 | if (got_pid > 0) |
792 | set_pid_status (got_pid, status); | |
726f6388 | 793 | |
ccc6cda3 | 794 | #if defined (HAVE_WAITPID) |
726f6388 JA |
795 | if (got_pid >= 0) |
796 | reap_zombie_children (); | |
ccc6cda3 | 797 | #endif /* HAVE_WAITPID */ |
726f6388 | 798 | |
ac50fbac CR |
799 | CHECK_TERMSIG; |
800 | CHECK_WAIT_INTR; | |
801 | ||
ccc6cda3 | 802 | if (interactive_shell == 0) |
726f6388 | 803 | { |
bb70624e JA |
804 | SigHandler *temp_handler; |
805 | ||
806 | temp_handler = old_sigint_handler; | |
807 | restore_sigint_handler (); | |
808 | ||
726f6388 JA |
809 | /* If the job exited because of SIGINT, make sure the shell acts as if |
810 | it had received one also. */ | |
811 | if (WIFSIGNALED (status) && (WTERMSIG (status) == SIGINT)) | |
812 | { | |
bb70624e | 813 | |
726f6388 | 814 | if (maybe_call_trap_handler (SIGINT) == 0) |
bb70624e JA |
815 | { |
816 | if (temp_handler == SIG_DFL) | |
0628567a | 817 | termsig_handler (SIGINT); |
bb70624e JA |
818 | else if (temp_handler != INVALID_SIGNAL_HANDLER && temp_handler != SIG_IGN) |
819 | (*temp_handler) (SIGINT); | |
820 | } | |
726f6388 JA |
821 | } |
822 | } | |
ccc6cda3 | 823 | |
726f6388 JA |
824 | /* Default return value. */ |
825 | /* ``a full 8 bits of status is returned'' */ | |
bb70624e | 826 | return_val = process_exit_status (status); |
b80f6443 | 827 | last_command_exit_signal = get_termsig (status); |
ccc6cda3 | 828 | |
ac50fbac CR |
829 | #if defined (DONT_REPORT_SIGPIPE) && defined (DONT_REPORT_SIGTERM) |
830 | # define REPORTSIG(x) ((x) != SIGINT && (x) != SIGPIPE && (x) != SIGTERM) | |
831 | #elif !defined (DONT_REPORT_SIGPIPE) && !defined (DONT_REPORT_SIGTERM) | |
832 | # define REPORTSIG(x) ((x) != SIGINT) | |
833 | #elif defined (DONT_REPORT_SIGPIPE) | |
834 | # define REPORTSIG(x) ((x) != SIGINT && (x) != SIGPIPE) | |
d166f048 | 835 | #else |
ac50fbac | 836 | # define REPORTSIG(x) ((x) != SIGINT && (x) != SIGTERM) |
d166f048 | 837 | #endif |
ac50fbac CR |
838 | |
839 | if ((WIFSTOPPED (status) == 0) && WIFSIGNALED (status) && REPORTSIG(WTERMSIG (status))) | |
726f6388 | 840 | { |
b80f6443 | 841 | fprintf (stderr, "%s", j_strsignal (WTERMSIG (status))); |
726f6388 | 842 | if (WIFCORED (status)) |
3185942a | 843 | fprintf (stderr, _(" (core dumped)")); |
726f6388 JA |
844 | fprintf (stderr, "\n"); |
845 | } | |
846 | ||
ccc6cda3 | 847 | if (interactive_shell && subshell_environment == 0) |
726f6388 JA |
848 | { |
849 | if (WIFSIGNALED (status) || WIFSTOPPED (status)) | |
850 | set_tty_state (); | |
851 | else | |
852 | get_tty_state (); | |
853 | } | |
ac50fbac CR |
854 | else if (interactive_shell == 0 && subshell_environment == 0 && check_window_size) |
855 | get_new_window_size (0, (int *)0, (int *)0); | |
726f6388 JA |
856 | |
857 | return (return_val); | |
858 | } | |
859 | ||
95732b49 JA |
860 | /* Send PID SIGNAL. Returns -1 on failure, 0 on success. If GROUP is non-zero, |
861 | or PID is less than -1, then kill the process group associated with PID. */ | |
726f6388 JA |
862 | int |
863 | kill_pid (pid, signal, group) | |
864 | pid_t pid; | |
865 | int signal, group; | |
866 | { | |
867 | int result; | |
868 | ||
95732b49 JA |
869 | if (pid < -1) |
870 | { | |
871 | pid = -pid; | |
872 | group = 1; | |
873 | } | |
bb70624e | 874 | result = group ? killpg (pid, signal) : kill (pid, signal); |
726f6388 JA |
875 | return (result); |
876 | } | |
877 | ||
bb70624e | 878 | static TTYSTRUCT shell_tty_info; |
ccc6cda3 | 879 | static int got_tty_state; |
726f6388 JA |
880 | |
881 | /* Fill the contents of shell_tty_info with the current tty info. */ | |
882 | get_tty_state () | |
883 | { | |
ccc6cda3 JA |
884 | int tty; |
885 | ||
d166f048 | 886 | tty = input_tty (); |
726f6388 JA |
887 | if (tty != -1) |
888 | { | |
bb70624e | 889 | ttgetattr (tty, &shell_tty_info); |
726f6388 | 890 | got_tty_state = 1; |
ccc6cda3 | 891 | if (check_window_size) |
95732b49 | 892 | get_new_window_size (0, (int *)0, (int *)0); |
726f6388 JA |
893 | } |
894 | } | |
895 | ||
896 | /* Make the current tty use the state in shell_tty_info. */ | |
b72432fd | 897 | int |
726f6388 JA |
898 | set_tty_state () |
899 | { | |
ccc6cda3 JA |
900 | int tty; |
901 | ||
d166f048 | 902 | tty = input_tty (); |
726f6388 JA |
903 | if (tty != -1) |
904 | { | |
ccc6cda3 | 905 | if (got_tty_state == 0) |
b72432fd | 906 | return 0; |
bb70624e | 907 | ttsetattr (tty, &shell_tty_info); |
726f6388 | 908 | } |
b72432fd | 909 | return 0; |
726f6388 JA |
910 | } |
911 | ||
912 | /* Give the terminal to PGRP. */ | |
28ef6c31 | 913 | give_terminal_to (pgrp, force) |
726f6388 | 914 | pid_t pgrp; |
28ef6c31 | 915 | int force; |
726f6388 JA |
916 | { |
917 | } | |
918 | ||
919 | /* Stop a pipeline. */ | |
f73dda09 | 920 | int |
726f6388 JA |
921 | stop_pipeline (async, ignore) |
922 | int async; | |
923 | COMMAND *ignore; | |
924 | { | |
925 | already_making_children = 0; | |
f73dda09 | 926 | return 0; |
726f6388 JA |
927 | } |
928 | ||
929 | void | |
930 | start_pipeline () | |
931 | { | |
932 | already_making_children = 1; | |
933 | } | |
934 | ||
f73dda09 JA |
935 | void |
936 | stop_making_children () | |
937 | { | |
938 | already_making_children = 0; | |
939 | } | |
940 | ||
d166f048 JA |
941 | int |
942 | get_job_by_pid (pid, block) | |
943 | pid_t pid; | |
944 | int block; | |
945 | { | |
946 | int i; | |
947 | ||
948 | i = find_index_by_pid (pid); | |
949 | return ((i == NO_PID) ? PROC_BAD : i); | |
950 | } | |
951 | ||
726f6388 JA |
952 | /* Print descriptive information about the job with leader pid PID. */ |
953 | void | |
954 | describe_pid (pid) | |
955 | pid_t pid; | |
956 | { | |
f73dda09 | 957 | fprintf (stderr, "%ld\n", (long) pid); |
726f6388 | 958 | } |
ccc6cda3 | 959 | |
495aee44 CR |
960 | void |
961 | freeze_jobs_list () | |
962 | { | |
963 | } | |
964 | ||
ccc6cda3 JA |
965 | void |
966 | unfreeze_jobs_list () | |
967 | { | |
968 | } | |
bb70624e JA |
969 | |
970 | int | |
971 | count_all_jobs () | |
972 | { | |
973 | return 0; | |
974 | } |