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