7 Bug-Reported-by: Ingo Molnar <mingo@elte.hu>
8 Bug-Reference-ID: <20071205202901.GA25202@elte.hu>
9 Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2007-12/msg00014.html
13 Bash incorrectly puts the second and subsequent children spawned by a
14 shell forked to run a command substitution in the wrong process group.
18 *** ../bash-3.2-patched/subst.c 2007-12-13 22:31:21.000000000 -0500
19 --- bash-3.2/subst.c 2008-01-17 22:48:15.000000000 -0500
23 #if defined (JOB_CONTROL)
24 set_sigchld_handler ();
25 stop_making_children ();
26 ! pipeline_pgrp = old_pipeline_pgrp;
28 stop_making_children ();
31 #if defined (JOB_CONTROL)
32 set_sigchld_handler ();
33 stop_making_children ();
35 ! pipeline_pgrp = old_pipeline_pgrp;
37 stop_making_children ();
38 *** ../bash-3.2-patched/jobs.c 2007-08-25 13:46:59.000000000 -0400
39 --- bash-3.2/jobs.c 2007-12-08 16:47:43.000000000 -0500
43 static int set_job_status_and_cleanup __P((int));
45 + static WAIT job_signal_status __P((int));
46 static WAIT raw_job_exit_status __P((int));
54 + job_signal_status (job)
57 + register PROCESS *p;
60 + p = jobs[job]->pipe;
64 + if (WIFSIGNALED(s) || WIFSTOPPED(s))
68 + while (p != jobs[job]->pipe);
73 /* Return the exit status of the last process in the pipeline for job JOB.
74 This is the exit status of the entire job. */
77 received, only if one of the jobs run is killed via SIGINT. If
78 job control is not set, the job will be run in the same pgrp as
79 ! the shell, and the shell will see any signals the job gets. */
81 /* This is possibly a race condition -- should it go in stop_pipeline? */
82 wait_sigint_received = 0;
83 ! if (job_control == 0)
85 old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
87 received, only if one of the jobs run is killed via SIGINT. If
88 job control is not set, the job will be run in the same pgrp as
89 ! the shell, and the shell will see any signals the job gets. In
90 ! fact, we want this set every time the waiting shell and the waited-
91 ! for process are in the same process group, including command
94 /* This is possibly a race condition -- should it go in stop_pipeline? */
95 wait_sigint_received = 0;
96 ! if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
98 old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
101 the last process in the pipeline. If no process exits due to a
102 signal, S is left as the status of the last job in the pipeline. */
103 ! p = jobs[job]->pipe;
107 ! if (WIFSIGNALED(s) || WIFSTOPPED(s))
111 ! while (p != jobs[job]->pipe);
113 if (WIFSIGNALED (s) || WIFSTOPPED (s))
115 the last process in the pipeline. If no process exits due to a
116 signal, S is left as the status of the last job in the pipeline. */
117 ! s = job_signal_status (job);
119 if (WIFSIGNALED (s) || WIFSTOPPED (s))
125 + else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
127 + /* If waiting for a job in a subshell started to do command
128 + substitution, simulate getting and being killed by the SIGINT to
129 + pass the status back to our parent. */
130 + s = job_signal_status (job);
132 + if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
134 + UNBLOCK_CHILD (oset);
135 + restore_sigint_handler ();
136 + old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL);
137 + if (old_sigint_handler == SIG_IGN)
138 + restore_sigint_handler ();
140 + kill (getpid (), SIGINT);
144 /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
145 *** ../bash-3.2/patchlevel.h Thu Apr 13 08:31:04 2006
146 --- bash-3.2/patchlevel.h Mon Oct 16 14:22:54 2006
149 looks for to find the patch level (for the sccs version string). */
151 ! #define PATCHLEVEL 34
153 #endif /* _PATCHLEVEL_H_ */
155 looks for to find the patch level (for the sccs version string). */
157 ! #define PATCHLEVEL 35
159 #endif /* _PATCHLEVEL_H_ */