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