]> git.ipfire.org Git - thirdparty/bash.git/blame - nojobs.c
Bash-4.2 direxpand with patch 27
[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
3185942a 6/* Copyright (C) 1987-2009 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
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(). */
97int check_window_size;
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
b80f6443 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));
b80f6443
JA
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));
b80f6443 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));
b80f6443 138static char *j_strsignal __P((int));
f73dda09
JA
139
140#if defined (HAVE_WAITPID)
141static void reap_zombie_children __P((void));
142#endif
143
b80f6443
JA
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
b80f6443
JA
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);
3185942a 236 return (get_termsig ((WAIT)pid_list[i].status));
b80f6443
JA
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
17345e5a
JA
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;
b80f6443
JA
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
b80f6443
JA
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
17345e5a
JA
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{
b80f6443 437# if defined (WNOHANG)
726f6388
JA
438 pid_t pid;
439 WAIT status;
440
0628567a 441 CHECK_TERMSIG;
726f6388
JA
442 while ((pid = waitpid (-1, (int *)&status, WNOHANG)) > 0)
443 set_pid_status (pid, status);
b80f6443 444# endif /* WNOHANG */
0628567a 445 CHECK_TERMSIG;
726f6388 446}
b80f6443
JA
447#endif /* WAITPID */
448
449#if !defined (HAVE_SIGINTERRUPT) && defined (HAVE_POSIX_SIGNALS)
450static int
451siginterrupt (sig, flag)
452 int sig, flag;
453{
454 struct sigaction act;
455
456 sigaction (sig, (struct sigaction *)NULL, &act);
457
458 if (flag)
459 act.sa_flags &= ~SA_RESTART;
460 else
461 act.sa_flags |= SA_RESTART;
462
463 return (sigaction (sig, &act, (struct sigaction *)NULL));
464}
465#endif /* !HAVE_SIGINTERRUPT && HAVE_POSIX_SIGNALS */
726f6388
JA
466
467/* Fork, handling errors. Returns the pid of the newly made child, or 0.
468 COMMAND is just for remembering the name of the command; we don't do
469 anything else with it. ASYNC_P says what to do with the tty. If
470 non-zero, then don't give it away. */
471pid_t
472make_child (command, async_p)
473 char *command;
474 int async_p;
475{
476 pid_t pid;
3185942a 477 int forksleep;
726f6388
JA
478
479 /* Discard saved memory. */
ccc6cda3 480 if (command)
726f6388
JA
481 free (command);
482
483 start_pipeline ();
484
485#if defined (BUFFERED_INPUT)
486 /* If default_buffered_input is active, we are reading a script. If
487 the command is asynchronous, we have already duplicated /dev/null
488 as fd 0, but have not changed the buffered stream corresponding to
489 the old fd 0. We don't want to sync the stream in this case. */
cce855bc 490 if (default_buffered_input != -1 && (!async_p || default_buffered_input > 0))
726f6388
JA
491 sync_buffered_stream (default_buffered_input);
492#endif /* BUFFERED_INPUT */
493
3185942a
JA
494 /* Create the child, handle severe errors. Retry on EAGAIN. */
495 forksleep = 1;
496 while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
726f6388 497 {
3185942a 498 sys_error ("fork: retry");
ccc6cda3 499#if defined (HAVE_WAITPID)
726f6388
JA
500 /* Posix systems with a non-blocking waitpid () system call available
501 get another chance after zombies are reaped. */
3185942a
JA
502 reap_zombie_children ();
503 if (forksleep > 1 && sleep (forksleep) != 0)
504 break;
505#else
506 if (sleep (forksleep) != 0)
507 break;
ccc6cda3 508#endif /* HAVE_WAITPID */
3185942a
JA
509 forksleep <<= 1;
510 }
726f6388 511
3185942a
JA
512 if (pid < 0)
513 {
ccc6cda3 514 sys_error ("fork");
726f6388
JA
515 throw_to_top_level ();
516 }
ccc6cda3 517
726f6388
JA
518 if (pid == 0)
519 {
520#if defined (BUFFERED_INPUT)
cce855bc 521 unset_bash_input (0);
726f6388
JA
522#endif /* BUFFERED_INPUT */
523
ccc6cda3 524#if defined (HAVE_POSIX_SIGNALS)
726f6388
JA
525 /* Restore top-level signal mask. */
526 sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
527#endif
528
3185942a 529#if 0
726f6388
JA
530 /* Ignore INT and QUIT in asynchronous children. */
531 if (async_p)
ccc6cda3 532 last_asynchronous_pid = getpid ();
3185942a 533#endif
726f6388 534
ccc6cda3 535 default_tty_job_signals ();
726f6388
JA
536 }
537 else
538 {
539 /* In the parent. */
540
541 last_made_pid = pid;
542
543 if (async_p)
544 last_asynchronous_pid = pid;
545
bb70624e 546 add_pid (pid, async_p);
726f6388
JA
547 }
548 return (pid);
549}
550
ccc6cda3
JA
551void
552ignore_tty_job_signals ()
553{
554#if defined (SIGTSTP)
555 set_signal_handler (SIGTSTP, SIG_IGN);
556 set_signal_handler (SIGTTIN, SIG_IGN);
557 set_signal_handler (SIGTTOU, SIG_IGN);
558#endif
559}
560
561void
562default_tty_job_signals ()
563{
564#if defined (SIGTSTP)
565 set_signal_handler (SIGTSTP, SIG_DFL);
566 set_signal_handler (SIGTTIN, SIG_DFL);
567 set_signal_handler (SIGTTOU, SIG_DFL);
568#endif
569}
570
bb70624e
JA
571/* Wait for a single pid (PID) and return its exit status. Called by
572 the wait builtin. */
f73dda09 573int
726f6388
JA
574wait_for_single_pid (pid)
575 pid_t pid;
576{
577 pid_t got_pid;
578 WAIT status;
b80f6443 579 int pstatus, flags;
726f6388
JA
580
581 pstatus = find_status_by_pid (pid);
582
583 if (pstatus == PROC_BAD)
ccc6cda3 584 {
b80f6443 585 internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
ccc6cda3
JA
586 return (127);
587 }
726f6388
JA
588
589 if (pstatus != PROC_STILL_ALIVE)
b80f6443
JA
590 {
591 if (pstatus > 128)
592 last_command_exit_signal = find_termsig_by_pid (pid);
593 return (pstatus);
594 }
726f6388
JA
595
596 siginterrupt (SIGINT, 1);
597 while ((got_pid = WAITPID (pid, &status, 0)) != pid)
598 {
0628567a 599 CHECK_TERMSIG;
726f6388
JA
600 if (got_pid < 0)
601 {
602 if (errno != EINTR && errno != ECHILD)
603 {
604 siginterrupt (SIGINT, 0);
ccc6cda3 605 sys_error ("wait");
726f6388
JA
606 }
607 break;
608 }
609 else if (got_pid > 0)
28ef6c31 610 set_pid_status (got_pid, status);
726f6388
JA
611 }
612
7117c2d2
JA
613 if (got_pid > 0)
614 {
615 set_pid_status (got_pid, status);
616 set_pid_flags (got_pid, PROC_NOTIFIED);
617 }
bb70624e 618
726f6388
JA
619 siginterrupt (SIGINT, 0);
620 QUIT;
621
7117c2d2 622 return (got_pid > 0 ? process_exit_status (status) : -1);
726f6388
JA
623}
624
bb70624e
JA
625/* Wait for all of the shell's children to exit. Called by the `wait'
626 builtin. */
726f6388
JA
627void
628wait_for_background_pids ()
629{
630 pid_t got_pid;
631 WAIT status;
632
633 /* If we aren't using job control, we let the kernel take care of the
ccc6cda3 634 bookkeeping for us. wait () will return -1 and set errno to ECHILD
726f6388
JA
635 when there are no more unwaited-for child processes on both
636 4.2 BSD-based and System V-based systems. */
637
638 siginterrupt (SIGINT, 1);
639
640 /* Wait for ECHILD */
641 while ((got_pid = WAITPID (-1, &status, 0)) != -1)
642 set_pid_status (got_pid, status);
643
644 if (errno != EINTR && errno != ECHILD)
645 {
646 siginterrupt (SIGINT, 0);
ccc6cda3 647 sys_error("wait");
726f6388
JA
648 }
649
650 siginterrupt (SIGINT, 0);
651 QUIT;
bb70624e
JA
652
653 mark_dead_jobs_as_notified (1);
654 cleanup_dead_jobs ();
655}
656
657/* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */
658#define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids
659static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER;
660
661static void
662restore_sigint_handler ()
663{
664 if (old_sigint_handler != INVALID_SIGNAL_HANDLER)
665 {
666 set_signal_handler (SIGINT, old_sigint_handler);
667 old_sigint_handler = INVALID_SIGNAL_HANDLER;
668 }
726f6388
JA
669}
670
671/* Handle SIGINT while we are waiting for children in a script to exit.
672 All interrupts are effectively ignored by the shell, but allowed to
673 kill a running job. */
674static sighandler
675wait_sigint_handler (sig)
676 int sig;
677{
bb70624e
JA
678 SigHandler *sigint_handler;
679
680 /* If we got a SIGINT while in `wait', and SIGINT is trapped, do
681 what POSIX.2 says (see builtins/wait.def for more info). */
682 if (this_shell_builtin && this_shell_builtin == wait_builtin &&
683 signal_is_trapped (SIGINT) &&
684 ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler))
685 {
686 last_command_exit_value = EXECUTION_FAILURE;
687 restore_sigint_handler ();
688 interrupt_immediately = 0;
689 trap_handler (SIGINT); /* set pending_traps[SIGINT] */
7117c2d2 690 wait_signal_received = SIGINT;
bb70624e
JA
691 longjmp (wait_intr_buf, 1);
692 }
693
28ef6c31
JA
694 if (interrupt_immediately)
695 {
696 last_command_exit_value = EXECUTION_FAILURE;
697 restore_sigint_handler ();
698 ADDINTERRUPT;
699 QUIT;
700 }
726f6388 701
bb70624e
JA
702 wait_sigint_received = 1;
703
ccc6cda3 704 SIGRETURN (0);
726f6388
JA
705}
706
b80f6443
JA
707static char *
708j_strsignal (s)
709 int s;
710{
711 static char retcode_name_buffer[64] = { '\0' };
712 char *x;
713
714 x = strsignal (s);
715 if (x == 0)
716 {
717 x = retcode_name_buffer;
718 sprintf (x, "Signal %d", s);
719 }
720 return x;
721}
722
726f6388
JA
723/* Wait for pid (one of our children) to terminate. This is called only
724 by the execution code in execute_cmd.c. */
725int
726wait_for (pid)
727 pid_t pid;
728{
729 int return_val, pstatus;
730 pid_t got_pid;
731 WAIT status;
726f6388
JA
732
733 pstatus = find_status_by_pid (pid);
734
735 if (pstatus == PROC_BAD)
736 return (0);
737
738 if (pstatus != PROC_STILL_ALIVE)
b80f6443
JA
739 {
740 if (pstatus > 128)
741 last_command_exit_signal = find_termsig_by_pid (pid);
742 return (pstatus);
743 }
726f6388
JA
744
745 /* If we are running a script, ignore SIGINT while we're waiting for
746 a child to exit. The loop below does some of this, but not all. */
bb70624e
JA
747 wait_sigint_received = 0;
748 if (interactive_shell == 0)
726f6388
JA
749 old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
750
751 while ((got_pid = WAITPID (-1, &status, 0)) != pid) /* XXX was pid now -1 */
752 {
0628567a 753 CHECK_TERMSIG;
726f6388
JA
754 if (got_pid < 0 && errno == ECHILD)
755 {
756#if !defined (_POSIX_VERSION)
757 status.w_termsig = status.w_retcode = 0;
758#else
759 status = 0;
760#endif /* _POSIX_VERSION */
761 break;
762 }
763 else if (got_pid < 0 && errno != EINTR)
f73dda09 764 programming_error ("wait_for(%ld): %s", (long)pid, strerror(errno));
726f6388
JA
765 else if (got_pid > 0)
766 set_pid_status (got_pid, status);
767 }
768
7117c2d2
JA
769 if (got_pid > 0)
770 set_pid_status (got_pid, status);
726f6388 771
ccc6cda3 772#if defined (HAVE_WAITPID)
726f6388
JA
773 if (got_pid >= 0)
774 reap_zombie_children ();
ccc6cda3 775#endif /* HAVE_WAITPID */
726f6388 776
ccc6cda3 777 if (interactive_shell == 0)
726f6388 778 {
bb70624e
JA
779 SigHandler *temp_handler;
780
781 temp_handler = old_sigint_handler;
782 restore_sigint_handler ();
783
726f6388
JA
784 /* If the job exited because of SIGINT, make sure the shell acts as if
785 it had received one also. */
786 if (WIFSIGNALED (status) && (WTERMSIG (status) == SIGINT))
787 {
bb70624e 788
726f6388 789 if (maybe_call_trap_handler (SIGINT) == 0)
bb70624e
JA
790 {
791 if (temp_handler == SIG_DFL)
0628567a 792 termsig_handler (SIGINT);
bb70624e
JA
793 else if (temp_handler != INVALID_SIGNAL_HANDLER && temp_handler != SIG_IGN)
794 (*temp_handler) (SIGINT);
795 }
726f6388
JA
796 }
797 }
ccc6cda3 798
726f6388
JA
799 /* Default return value. */
800 /* ``a full 8 bits of status is returned'' */
bb70624e 801 return_val = process_exit_status (status);
b80f6443 802 last_command_exit_signal = get_termsig (status);
ccc6cda3 803
d166f048
JA
804#if !defined (DONT_REPORT_SIGPIPE)
805 if ((WIFSTOPPED (status) == 0) && WIFSIGNALED (status) &&
806 (WTERMSIG (status) != SIGINT))
807#else
808 if ((WIFSTOPPED (status) == 0) && WIFSIGNALED (status) &&
809 (WTERMSIG (status) != SIGINT) && (WTERMSIG (status) != SIGPIPE))
810#endif
726f6388 811 {
b80f6443 812 fprintf (stderr, "%s", j_strsignal (WTERMSIG (status)));
726f6388 813 if (WIFCORED (status))
3185942a 814 fprintf (stderr, _(" (core dumped)"));
726f6388
JA
815 fprintf (stderr, "\n");
816 }
817
ccc6cda3 818 if (interactive_shell && subshell_environment == 0)
726f6388
JA
819 {
820 if (WIFSIGNALED (status) || WIFSTOPPED (status))
821 set_tty_state ();
822 else
823 get_tty_state ();
824 }
825
826 return (return_val);
827}
828
95732b49
JA
829/* Send PID SIGNAL. Returns -1 on failure, 0 on success. If GROUP is non-zero,
830 or PID is less than -1, then kill the process group associated with PID. */
726f6388
JA
831int
832kill_pid (pid, signal, group)
833 pid_t pid;
834 int signal, group;
835{
836 int result;
837
95732b49
JA
838 if (pid < -1)
839 {
840 pid = -pid;
841 group = 1;
842 }
bb70624e 843 result = group ? killpg (pid, signal) : kill (pid, signal);
726f6388
JA
844 return (result);
845}
846
bb70624e 847static TTYSTRUCT shell_tty_info;
ccc6cda3 848static int got_tty_state;
726f6388
JA
849
850/* Fill the contents of shell_tty_info with the current tty info. */
851get_tty_state ()
852{
ccc6cda3
JA
853 int tty;
854
d166f048 855 tty = input_tty ();
726f6388
JA
856 if (tty != -1)
857 {
bb70624e 858 ttgetattr (tty, &shell_tty_info);
726f6388 859 got_tty_state = 1;
ccc6cda3 860 if (check_window_size)
95732b49 861 get_new_window_size (0, (int *)0, (int *)0);
726f6388
JA
862 }
863}
864
865/* Make the current tty use the state in shell_tty_info. */
b72432fd 866int
726f6388
JA
867set_tty_state ()
868{
ccc6cda3
JA
869 int tty;
870
d166f048 871 tty = input_tty ();
726f6388
JA
872 if (tty != -1)
873 {
ccc6cda3 874 if (got_tty_state == 0)
b72432fd 875 return 0;
bb70624e 876 ttsetattr (tty, &shell_tty_info);
726f6388 877 }
b72432fd 878 return 0;
726f6388
JA
879}
880
881/* Give the terminal to PGRP. */
28ef6c31 882give_terminal_to (pgrp, force)
726f6388 883 pid_t pgrp;
28ef6c31 884 int force;
726f6388
JA
885{
886}
887
888/* Stop a pipeline. */
f73dda09 889int
726f6388
JA
890stop_pipeline (async, ignore)
891 int async;
892 COMMAND *ignore;
893{
894 already_making_children = 0;
f73dda09 895 return 0;
726f6388
JA
896}
897
898void
899start_pipeline ()
900{
901 already_making_children = 1;
902}
903
f73dda09
JA
904void
905stop_making_children ()
906{
907 already_making_children = 0;
908}
909
d166f048
JA
910int
911get_job_by_pid (pid, block)
912 pid_t pid;
913 int block;
914{
915 int i;
916
917 i = find_index_by_pid (pid);
918 return ((i == NO_PID) ? PROC_BAD : i);
919}
920
726f6388
JA
921/* Print descriptive information about the job with leader pid PID. */
922void
923describe_pid (pid)
924 pid_t pid;
925{
f73dda09 926 fprintf (stderr, "%ld\n", (long) pid);
726f6388 927}
ccc6cda3 928
495aee44
CR
929void
930freeze_jobs_list ()
931{
932}
933
ccc6cda3
JA
934void
935unfreeze_jobs_list ()
936{
937}
bb70624e
JA
938
939int
940count_all_jobs ()
941{
942 return 0;
943}