From f4b417c62a4f272c4cf9a074d0f7a3a97201f9db Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 17 Apr 2012 11:23:35 +0200 Subject: Update to upstream bash 4.2 This upgrades bash to from 4.1-rc to 4.2-release. See CWRU/changelog for changes. Change-Id: I926269c300cf44fa25964b5b375a148fcf11c4b7 --- jobs.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 14 deletions(-) (limited to 'jobs.c') diff --git a/jobs.c b/jobs.c index df13ad9..d63c5dd 100644 --- a/jobs.c +++ b/jobs.c @@ -3,7 +3,7 @@ /* This file works with both POSIX and BSD systems. It implements job control. */ -/* Copyright (C) 1989-2009 Free Software Foundation, Inc. +/* Copyright (C) 1989-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -77,6 +77,10 @@ extern int errno; #endif /* !errno */ +#if !defined (HAVE_KILLPG) +extern int killpg __P((pid_t, int)); +#endif + #define DEFAULT_CHILD_MAX 32 #if !defined (DEBUG) #define MAX_JOBS_IN_ARRAY 4096 /* production */ @@ -246,8 +250,6 @@ static int find_job __P((pid_t, int, PROCESS **)); static int print_job __P((JOB *, int, int, int)); static int process_exit_status __P((WAIT)); static int process_exit_signal __P((WAIT)); -static int job_exit_status __P((int)); -static int job_exit_signal __P((int)); static int set_job_status_and_cleanup __P((int)); static WAIT job_signal_status __P((int)); @@ -645,7 +647,7 @@ stop_pipeline (async, deferred) stop_making_children (); UNBLOCK_CHILD (oset); - return (js.j_current); + return (newjob ? i : js.j_current); } /* Functions to manage the list of exited background pids whose status has @@ -1134,6 +1136,33 @@ add_process (name, pid) } } +/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last + process in jobs[JID]->pipe. Used by the lastpipe code. */ +void +append_process (name, pid, status, jid) + char *name; + pid_t pid; + int status; + int jid; +{ + PROCESS *t, *p; + + t = (PROCESS *)xmalloc (sizeof (PROCESS)); + t->next = (PROCESS *)NULL; + t->pid = pid; + /* set process exit status using offset discovered by configure */ + t->status = (status & 0xff) << WEXITSTATUS_OFFSET; + t->running = PS_DONE; + t->command = name; + + js.c_reaped++; /* XXX */ + + for (p = jobs[jid]->pipe; p->next != jobs[jid]->pipe; p = p->next) + ; + p->next = t; + t->next = jobs[jid]->pipe; +} + #if 0 /* Take the last job and make it the first job. Must be called with SIGCHLD blocked. */ @@ -1708,10 +1737,10 @@ make_child (command, async_p) /* Create the child, handle severe errors. Retry on EAGAIN. */ while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX) { -#if 0 /* for bash-4.2 */ + /* bash-4.2 */ /* If we can't create any children, try to reap some dead ones. */ waitchld (-1, 0); -#endif + sys_error ("fork: retry"); if (sleep (forksleep) != 0) break; @@ -2125,7 +2154,7 @@ wait_for_single_pid (pid) return r; } -/* Wait for all of the backgrounds of this shell to finish. */ +/* Wait for all of the background processes started by this shell to finish. */ void wait_for_background_pids () { @@ -2306,14 +2335,14 @@ raw_job_exit_status (job) /* Return the exit status of job JOB. This is the exit status of the last (rightmost) process in the job's pipeline, modified if the job was killed by a signal or stopped. */ -static int +int job_exit_status (job) int job; { return (process_exit_status (raw_job_exit_status (job))); } -static int +int job_exit_signal (job) int job; { @@ -2347,7 +2376,6 @@ wait_for (pid) WAIT s; register PROCESS *child; sigset_t set, oset; - register PROCESS *p; /* In the case that this code is interrupted, and we longjmp () out of it, we are relying on the code in throw_to_top_level () to restore the @@ -2549,11 +2577,13 @@ if (job == NO_JOB) } } } - else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received) + else if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PIPE)) && wait_sigint_received) { /* If waiting for a job in a subshell started to do command - substitution, simulate getting and being killed by the SIGINT to - pass the status back to our parent. */ + substitution or to run a pipeline element that consists of + something like a while loop or a for loop, simulate getting + and being killed by the SIGINT to pass the status back to our + parent. */ s = job_signal_status (job); if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0) @@ -4114,7 +4144,13 @@ itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", j } /* Here to allow other parts of the shell (like the trap stuff) to - unfreeze the jobs list. */ + freeze and unfreeze the jobs list. */ +void +freeze_jobs_list () +{ + jobs_list_frozen = 1; +} + void unfreeze_jobs_list () { -- cgit v1.1