160 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 			     BASH PATCH REPORT
 | |
| 			     =================
 | |
| 
 | |
| Bash-Release: 3.2
 | |
| Patch-ID: bash32-035
 | |
| 
 | |
| Bug-Reported-by:	Ingo Molnar <mingo@elte.hu>
 | |
| Bug-Reference-ID:	<20071205202901.GA25202@elte.hu>
 | |
| Bug-Reference-URL:	http://lists.gnu.org/archive/html/bug-bash/2007-12/msg00014.html
 | |
| 
 | |
| Bug-Description:
 | |
| 
 | |
| Bash incorrectly puts the second and subsequent children spawned by a
 | |
| shell forked to run a command substitution in the wrong process group.
 | |
| 
 | |
| Patch:
 | |
| 
 | |
| *** ../bash-3.2-patched/subst.c	2007-12-13 22:31:21.000000000 -0500
 | |
| --- subst.c	2008-01-17 22:48:15.000000000 -0500
 | |
| ***************
 | |
| *** 4621,4627 ****
 | |
|   
 | |
|   #if defined (JOB_CONTROL)
 | |
|     set_sigchld_handler ();
 | |
|     stop_making_children ();
 | |
| !   pipeline_pgrp = old_pipeline_pgrp;
 | |
|   #else
 | |
|     stop_making_children ();
 | |
| --- 4721,4728 ----
 | |
|   
 | |
|   #if defined (JOB_CONTROL)
 | |
|     set_sigchld_handler ();
 | |
|     stop_making_children ();
 | |
| !   if (pid != 0)
 | |
| !     pipeline_pgrp = old_pipeline_pgrp;
 | |
|   #else
 | |
|     stop_making_children ();
 | |
| *** ../bash-3.2-patched/jobs.c	2007-08-25 13:46:59.000000000 -0400
 | |
| --- jobs.c	2007-12-08 16:47:43.000000000 -0500
 | |
| ***************
 | |
| *** 251,254 ****
 | |
| --- 251,255 ----
 | |
|   static int set_job_status_and_cleanup __P((int));
 | |
|   
 | |
| + static WAIT job_signal_status __P((int));
 | |
|   static WAIT raw_job_exit_status __P((int));
 | |
|   
 | |
| ***************
 | |
| *** 2220,2223 ****
 | |
| --- 2238,2261 ----
 | |
|   }
 | |
|   
 | |
| + static WAIT
 | |
| + job_signal_status (job)
 | |
| +      int job;
 | |
| + {
 | |
| +   register PROCESS *p;
 | |
| +   WAIT s;
 | |
| + 
 | |
| +   p = jobs[job]->pipe;
 | |
| +   do
 | |
| +     {
 | |
| +       s = p->status;
 | |
| +       if (WIFSIGNALED(s) || WIFSTOPPED(s))
 | |
| + 	break;
 | |
| +       p = p->next;
 | |
| +     }
 | |
| +   while (p != jobs[job]->pipe);
 | |
| + 
 | |
| +   return s;
 | |
| + }
 | |
| +   
 | |
|   /* Return the exit status of the last process in the pipeline for job JOB.
 | |
|      This is the exit status of the entire job. */
 | |
| ***************
 | |
| *** 2302,2310 ****
 | |
|        received, only if one of the jobs run is killed via SIGINT.  If
 | |
|        job control is not set, the job will be run in the same pgrp as
 | |
| !      the shell, and the shell will see any signals the job gets. */
 | |
|   
 | |
|     /* This is possibly a race condition -- should it go in stop_pipeline? */
 | |
|     wait_sigint_received = 0;
 | |
| !   if (job_control == 0)
 | |
|       {
 | |
|         old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
 | |
| --- 2343,2354 ----
 | |
|        received, only if one of the jobs run is killed via SIGINT.  If
 | |
|        job control is not set, the job will be run in the same pgrp as
 | |
| !      the shell, and the shell will see any signals the job gets.  In
 | |
| !      fact, we want this set every time the waiting shell and the waited-
 | |
| !      for process are in the same process group, including command
 | |
| !      substitution. */
 | |
|   
 | |
|     /* This is possibly a race condition -- should it go in stop_pipeline? */
 | |
|     wait_sigint_received = 0;
 | |
| !   if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
 | |
|       {
 | |
|         old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
 | |
| ***************
 | |
| *** 2452,2464 ****
 | |
|   	     the last process in the pipeline.  If no process exits due to a
 | |
|   	     signal, S is left as the status of the last job in the pipeline. */
 | |
| ! 	  p = jobs[job]->pipe;
 | |
| ! 	  do
 | |
| ! 	    {
 | |
| ! 	      s = p->status;
 | |
| ! 	      if (WIFSIGNALED(s) || WIFSTOPPED(s))
 | |
| ! 		break;
 | |
| ! 	      p = p->next;
 | |
| ! 	    }
 | |
| ! 	  while (p != jobs[job]->pipe);
 | |
|   
 | |
|   	  if (WIFSIGNALED (s) || WIFSTOPPED (s))
 | |
| --- 2496,2500 ----
 | |
|   	     the last process in the pipeline.  If no process exits due to a
 | |
|   	     signal, S is left as the status of the last job in the pipeline. */
 | |
| ! 	  s = job_signal_status (job);
 | |
|   
 | |
|   	  if (WIFSIGNALED (s) || WIFSTOPPED (s))
 | |
| ***************
 | |
| *** 2494,2497 ****
 | |
| --- 2530,2551 ----
 | |
|   	    }
 | |
|   	}
 | |
| +       else if ((subshell_environment & SUBSHELL_COMSUB) && 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. */
 | |
| + 	  s = job_signal_status (job);
 | |
| + 	
 | |
| + 	  if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
 | |
| + 	    {
 | |
| + 	      UNBLOCK_CHILD (oset);
 | |
| + 	      restore_sigint_handler ();
 | |
| + 	      old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
 | |
| + 	      if (old_sigint_handler == SIG_IGN)
 | |
| + 		restore_sigint_handler ();
 | |
| + 	      else
 | |
| + 		kill (getpid (), SIGINT);
 | |
| + 	    }
 | |
| + 	}
 | |
|   
 | |
|         /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
 | |
| *** ../bash-3.2/patchlevel.h	Thu Apr 13 08:31:04 2006
 | |
| --- patchlevel.h	Mon Oct 16 14:22:54 2006
 | |
| ***************
 | |
| *** 26,30 ****
 | |
|      looks for to find the patch level (for the sccs version string). */
 | |
|   
 | |
| ! #define PATCHLEVEL 34
 | |
|   
 | |
|   #endif /* _PATCHLEVEL_H_ */
 | |
| --- 26,30 ----
 | |
|      looks for to find the patch level (for the sccs version string). */
 | |
|   
 | |
| ! #define PATCHLEVEL 35
 | |
|   
 | |
|   #endif /* _PATCHLEVEL_H_ */
 |