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