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