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