]> git.ipfire.org Git - thirdparty/bash.git/blame - nojobs.c
Bash-5.2 patch 26: fix typo when specifying readline's custom color prefix
[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
74091dd4 6/* Copyright (C) 1987-2022 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
15409324
CR
578 subshell_environment |= SUBSHELL_IGNTRAP;
579
ccc6cda3 580 default_tty_job_signals ();
726f6388
JA
581 }
582 else
583 {
584 /* In the parent. */
585
586 last_made_pid = pid;
587
588 if (async_p)
589 last_asynchronous_pid = pid;
590
bb70624e 591 add_pid (pid, async_p);
726f6388
JA
592 }
593 return (pid);
594}
595
ccc6cda3
JA
596void
597ignore_tty_job_signals ()
598{
599#if defined (SIGTSTP)
600 set_signal_handler (SIGTSTP, SIG_IGN);
601 set_signal_handler (SIGTTIN, SIG_IGN);
602 set_signal_handler (SIGTTOU, SIG_IGN);
603#endif
604}
605
606void
607default_tty_job_signals ()
608{
609#if defined (SIGTSTP)
a0c0a00f
CR
610 if (signal_is_trapped (SIGTSTP) == 0 && signal_is_hard_ignored (SIGTSTP))
611 set_signal_handler (SIGTSTP, SIG_IGN);
612 else
613 set_signal_handler (SIGTSTP, SIG_DFL);
614 if (signal_is_trapped (SIGTTIN) == 0 && signal_is_hard_ignored (SIGTTIN))
615 set_signal_handler (SIGTTIN, SIG_IGN);
616 else
617 set_signal_handler (SIGTTIN, SIG_DFL);
618 if (signal_is_trapped (SIGTTOU) == 0 && signal_is_hard_ignored (SIGTTOU))
619 set_signal_handler (SIGTTOU, SIG_IGN);
620 else
621 set_signal_handler (SIGTTOU, SIG_DFL);
622#endif
623}
624
625/* Called once in a parent process. */
626void
627get_original_tty_job_signals ()
628{
629 static int fetched = 0;
630
631 if (fetched == 0)
632 {
633#if defined (SIGTSTP)
634 if (interactive_shell)
635 {
636 set_original_signal (SIGTSTP, SIG_DFL);
637 set_original_signal (SIGTTIN, SIG_DFL);
638 set_original_signal (SIGTTOU, SIG_DFL);
639 }
640 else
641 {
642 get_original_signal (SIGTSTP);
643 get_original_signal (SIGTTIN);
644 get_original_signal (SIGTTOU);
645 }
ccc6cda3 646#endif
a0c0a00f
CR
647 fetched = 1;
648 }
ccc6cda3
JA
649}
650
bb70624e
JA
651/* Wait for a single pid (PID) and return its exit status. Called by
652 the wait builtin. */
f73dda09 653int
a0c0a00f 654wait_for_single_pid (pid, flags)
726f6388 655 pid_t pid;
a0c0a00f 656 int flags;
726f6388
JA
657{
658 pid_t got_pid;
659 WAIT status;
a0c0a00f 660 int pstatus;
726f6388
JA
661
662 pstatus = find_status_by_pid (pid);
663
664 if (pstatus == PROC_BAD)
ccc6cda3 665 {
b80f6443 666 internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
74091dd4 667 return (257);
ccc6cda3 668 }
726f6388
JA
669
670 if (pstatus != PROC_STILL_ALIVE)
b80f6443
JA
671 {
672 if (pstatus > 128)
673 last_command_exit_signal = find_termsig_by_pid (pid);
674 return (pstatus);
675 }
726f6388
JA
676
677 siginterrupt (SIGINT, 1);
678 while ((got_pid = WAITPID (pid, &status, 0)) != pid)
679 {
0628567a 680 CHECK_TERMSIG;
ac50fbac 681 CHECK_WAIT_INTR;
726f6388
JA
682 if (got_pid < 0)
683 {
684 if (errno != EINTR && errno != ECHILD)
685 {
686 siginterrupt (SIGINT, 0);
ccc6cda3 687 sys_error ("wait");
726f6388
JA
688 }
689 break;
690 }
691 else if (got_pid > 0)
28ef6c31 692 set_pid_status (got_pid, status);
726f6388
JA
693 }
694
7117c2d2
JA
695 if (got_pid > 0)
696 {
697 set_pid_status (got_pid, status);
698 set_pid_flags (got_pid, PROC_NOTIFIED);
699 }
bb70624e 700
726f6388
JA
701 siginterrupt (SIGINT, 0);
702 QUIT;
8868edaf 703 CHECK_WAIT_INTR;
726f6388 704
7117c2d2 705 return (got_pid > 0 ? process_exit_status (status) : -1);
726f6388
JA
706}
707
bb70624e
JA
708/* Wait for all of the shell's children to exit. Called by the `wait'
709 builtin. */
74091dd4 710int
8868edaf
CR
711wait_for_background_pids (ps)
712 struct procstat *ps;
726f6388
JA
713{
714 pid_t got_pid;
715 WAIT status;
74091dd4 716 int njobs;
726f6388
JA
717
718 /* If we aren't using job control, we let the kernel take care of the
ccc6cda3 719 bookkeeping for us. wait () will return -1 and set errno to ECHILD
726f6388
JA
720 when there are no more unwaited-for child processes on both
721 4.2 BSD-based and System V-based systems. */
722
74091dd4 723 njobs = 0;
726f6388
JA
724 siginterrupt (SIGINT, 1);
725
726 /* Wait for ECHILD */
8868edaf 727 waiting_for_child = 1;
726f6388 728 while ((got_pid = WAITPID (-1, &status, 0)) != -1)
8868edaf
CR
729 {
730 waiting_for_child = 0;
74091dd4 731 njobs++;
8868edaf
CR
732 set_pid_status (got_pid, status);
733 if (ps)
734 {
735 ps->pid = got_pid;
736 ps->status = process_exit_status (status);
737 }
738 waiting_for_child = 1;
739 CHECK_WAIT_INTR;
740 }
741 waiting_for_child = 0;
726f6388
JA
742
743 if (errno != EINTR && errno != ECHILD)
744 {
745 siginterrupt (SIGINT, 0);
ccc6cda3 746 sys_error("wait");
726f6388
JA
747 }
748
749 siginterrupt (SIGINT, 0);
750 QUIT;
8868edaf 751 CHECK_WAIT_INTR;
bb70624e
JA
752
753 mark_dead_jobs_as_notified (1);
754 cleanup_dead_jobs ();
74091dd4
CR
755
756 return njobs;
bb70624e
JA
757}
758
a0c0a00f
CR
759void
760wait_sigint_cleanup ()
761{
762}
763
bb70624e
JA
764/* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */
765#define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids
766static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER;
767
768static void
769restore_sigint_handler ()
770{
771 if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
772 {
773 set_signal_handler (SIGINT, old_sigint_handler);
774 old_sigint_handler = INVALID_SIGNAL_HANDLER;
775 }
726f6388
JA
776}
777
778/* Handle SIGINT while we are waiting for children in a script to exit.
779 All interrupts are effectively ignored by the shell, but allowed to
780 kill a running job. */
781static sighandler
782wait_sigint_handler (sig)
783 int sig;
784{
bb70624e
JA
785 SigHandler *sigint_handler;
786
787 /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
788 what POSIX.2 says (see builtins/wait.def for more info). */
789 if (this_shell_builtin && this_shell_builtin == wait_builtin &&
790 signal_is_trapped (SIGINT) &&
791 ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler))
792 {
ac50fbac 793 last_command_exit_value = 128+SIGINT;
bb70624e 794 restore_sigint_handler ();
bb70624e 795 trap_handler (SIGINT); /* set pending_traps[SIGINT] */
7117c2d2 796 wait_signal_received = SIGINT;
ac50fbac 797 SIGRETURN (0);
bb70624e
JA
798 }
799
bb70624e
JA
800 wait_sigint_received = 1;
801
ccc6cda3 802 SIGRETURN (0);
726f6388
JA
803}
804
b80f6443
JA
805static char *
806j_strsignal (s)
807 int s;
808{
809 static char retcode_name_buffer[64] = { '\0' };
810 char *x;
811
812 x = strsignal (s);
813 if (x == 0)
814 {
815 x = retcode_name_buffer;
816 sprintf (x, "Signal %d", s);
817 }
818 return x;
819}
820
726f6388
JA
821/* Wait for pid (one of our children) to terminate. This is called only
822 by the execution code in execute_cmd.c. */
823int
8868edaf 824wait_for (pid, flags)
726f6388 825 pid_t pid;
8868edaf 826 int flags;
726f6388
JA
827{
828 int return_val, pstatus;
829 pid_t got_pid;
830 WAIT status;
726f6388
JA
831
832 pstatus = find_status_by_pid (pid);
833
834 if (pstatus == PROC_BAD)
835 return (0);
836
837 if (pstatus != PROC_STILL_ALIVE)
b80f6443
JA
838 {
839 if (pstatus > 128)
840 last_command_exit_signal = find_termsig_by_pid (pid);
841 return (pstatus);
842 }
726f6388
JA
843
844 /* If we are running a script, ignore SIGINT while we're waiting for
845 a child to exit. The loop below does some of this, but not all. */
bb70624e
JA
846 wait_sigint_received = 0;
847 if (interactive_shell == 0)
726f6388
JA
848 old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
849
8868edaf
CR
850 waiting_for_child = 1;
851 CHECK_WAIT_INTR;
726f6388
JA
852 while ((got_pid = WAITPID (-1, &status, 0)) != pid) /* XXX was pid now -1 */
853 {
8868edaf 854 waiting_for_child = 0;
0628567a 855 CHECK_TERMSIG;
ac50fbac 856 CHECK_WAIT_INTR;
726f6388
JA
857 if (got_pid < 0 && errno == ECHILD)
858 {
859#if !defined (_POSIX_VERSION)
860 status.w_termsig = status.w_retcode = 0;
861#else
862 status = 0;
863#endif /* _POSIX_VERSION */
864 break;
865 }
866 else if (got_pid < 0 && errno != EINTR)
f73dda09 867 programming_error ("wait_for(%ld): %s", (long)pid, strerror(errno));
726f6388
JA
868 else if (got_pid > 0)
869 set_pid_status (got_pid, status);
8868edaf 870 waiting_for_child = 1;
726f6388 871 }
8868edaf 872 waiting_for_child = 0;
726f6388 873
7117c2d2
JA
874 if (got_pid > 0)
875 set_pid_status (got_pid, status);
726f6388 876
ccc6cda3 877#if defined (HAVE_WAITPID)
726f6388
JA
878 if (got_pid >= 0)
879 reap_zombie_children ();
ccc6cda3 880#endif /* HAVE_WAITPID */
726f6388 881
ac50fbac
CR
882 CHECK_TERMSIG;
883 CHECK_WAIT_INTR;
884
ccc6cda3 885 if (interactive_shell == 0)
726f6388 886 {
bb70624e
JA
887 SigHandler *temp_handler;
888
889 temp_handler = old_sigint_handler;
890 restore_sigint_handler ();
891
726f6388
JA
892 /* If the job exited because of SIGINT, make sure the shell acts as if
893 it had received one also. */
894 if (WIFSIGNALED (status) && (WTERMSIG (status) == SIGINT))
895 {
bb70624e 896
726f6388 897 if (maybe_call_trap_handler (SIGINT) == 0)
bb70624e
JA
898 {
899 if (temp_handler == SIG_DFL)
0628567a 900 termsig_handler (SIGINT);
bb70624e
JA
901 else if (temp_handler != INVALID_SIGNAL_HANDLER && temp_handler != SIG_IGN)
902 (*temp_handler) (SIGINT);
903 }
726f6388
JA
904 }
905 }
ccc6cda3 906
726f6388
JA
907 /* Default return value. */
908 /* ``a full 8 bits of status is returned'' */
bb70624e 909 return_val = process_exit_status (status);
b80f6443 910 last_command_exit_signal = get_termsig (status);
ccc6cda3 911
ac50fbac
CR
912#if defined (DONT_REPORT_SIGPIPE) && defined (DONT_REPORT_SIGTERM)
913# define REPORTSIG(x) ((x) != SIGINT && (x) != SIGPIPE && (x) != SIGTERM)
914#elif !defined (DONT_REPORT_SIGPIPE) && !defined (DONT_REPORT_SIGTERM)
915# define REPORTSIG(x) ((x) != SIGINT)
916#elif defined (DONT_REPORT_SIGPIPE)
917# define REPORTSIG(x) ((x) != SIGINT && (x) != SIGPIPE)
d166f048 918#else
ac50fbac 919# define REPORTSIG(x) ((x) != SIGINT && (x) != SIGTERM)
d166f048 920#endif
ac50fbac
CR
921
922 if ((WIFSTOPPED (status) == 0) && WIFSIGNALED (status) && REPORTSIG(WTERMSIG (status)))
726f6388 923 {
b80f6443 924 fprintf (stderr, "%s", j_strsignal (WTERMSIG (status)));
726f6388 925 if (WIFCORED (status))
3185942a 926 fprintf (stderr, _(" (core dumped)"));
726f6388
JA
927 fprintf (stderr, "\n");
928 }
929
ccc6cda3 930 if (interactive_shell && subshell_environment == 0)
726f6388
JA
931 {
932 if (WIFSIGNALED (status) || WIFSTOPPED (status))
933 set_tty_state ();
934 else
935 get_tty_state ();
936 }
ac50fbac
CR
937 else if (interactive_shell == 0 && subshell_environment == 0 && check_window_size)
938 get_new_window_size (0, (int *)0, (int *)0);
726f6388
JA
939
940 return (return_val);
941}
942
95732b49
JA
943/* Send PID SIGNAL. Returns -1 on failure, 0 on success. If GROUP is non-zero,
944 or PID is less than -1, then kill the process group associated with PID. */
726f6388
JA
945int
946kill_pid (pid, signal, group)
947 pid_t pid;
948 int signal, group;
949{
950 int result;
951
95732b49
JA
952 if (pid < -1)
953 {
954 pid = -pid;
955 group = 1;
956 }
bb70624e 957 result = group ? killpg (pid, signal) : kill (pid, signal);
726f6388
JA
958 return (result);
959}
960
bb70624e 961static TTYSTRUCT shell_tty_info;
ccc6cda3 962static int got_tty_state;
726f6388
JA
963
964/* Fill the contents of shell_tty_info with the current tty info. */
a0c0a00f 965int
726f6388
JA
966get_tty_state ()
967{
ccc6cda3
JA
968 int tty;
969
d166f048 970 tty = input_tty ();
726f6388
JA
971 if (tty != -1)
972 {
bb70624e 973 ttgetattr (tty, &shell_tty_info);
726f6388 974 got_tty_state = 1;
ccc6cda3 975 if (check_window_size)
95732b49 976 get_new_window_size (0, (int *)0, (int *)0);
726f6388 977 }
a0c0a00f 978 return 0;
726f6388
JA
979}
980
981/* Make the current tty use the state in shell_tty_info. */
b72432fd 982int
726f6388
JA
983set_tty_state ()
984{
ccc6cda3
JA
985 int tty;
986
d166f048 987 tty = input_tty ();
726f6388
JA
988 if (tty != -1)
989 {
ccc6cda3 990 if (got_tty_state == 0)
b72432fd 991 return 0;
bb70624e 992 ttsetattr (tty, &shell_tty_info);
726f6388 993 }
b72432fd 994 return 0;
726f6388
JA
995}
996
997/* Give the terminal to PGRP. */
a0c0a00f 998int
28ef6c31 999give_terminal_to (pgrp, force)
726f6388 1000 pid_t pgrp;
28ef6c31 1001 int force;
726f6388 1002{
a0c0a00f 1003 return 0;
726f6388
JA
1004}
1005
1006/* Stop a pipeline. */
f73dda09 1007int
726f6388
JA
1008stop_pipeline (async, ignore)
1009 int async;
1010 COMMAND *ignore;
1011{
1012 already_making_children = 0;
f73dda09 1013 return 0;
726f6388
JA
1014}
1015
1016void
1017start_pipeline ()
1018{
1019 already_making_children = 1;
1020}
1021
f73dda09
JA
1022void
1023stop_making_children ()
1024{
1025 already_making_children = 0;
1026}
1027
a0c0a00f
CR
1028/* The name is kind of a misnomer, but it's what the job control code uses. */
1029void
1030without_job_control ()
1031{
1032 stop_making_children ();
1033 last_made_pid = NO_PID; /* XXX */
1034}
1035
d166f048 1036int
8868edaf 1037get_job_by_pid (pid, block, ignore)
d166f048
JA
1038 pid_t pid;
1039 int block;
8868edaf 1040 PROCESS **ignore;
d166f048
JA
1041{
1042 int i;
1043
1044 i = find_index_by_pid (pid);
1045 return ((i == NO_PID) ? PROC_BAD : i);
1046}
1047
726f6388
JA
1048/* Print descriptive information about the job with leader pid PID. */
1049void
1050describe_pid (pid)
1051 pid_t pid;
1052{
f73dda09 1053 fprintf (stderr, "%ld\n", (long) pid);
726f6388 1054}
ccc6cda3 1055
a0c0a00f 1056int
495aee44
CR
1057freeze_jobs_list ()
1058{
a0c0a00f 1059 return 0;
495aee44
CR
1060}
1061
ccc6cda3
JA
1062void
1063unfreeze_jobs_list ()
1064{
1065}
bb70624e 1066
d233b485
CR
1067void
1068set_jobs_list_frozen (s)
1069 int s;
1070{
1071}
1072
bb70624e
JA
1073int
1074count_all_jobs ()
1075{
1076 return 0;
1077}