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