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