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