]> git.pld-linux.org Git - packages/bash.git/blob - bash32-035
- up to 3.2.39
[packages/bash.git] / bash32-035
1                              BASH PATCH REPORT
2                              =================
3
4 Bash-Release: 3.2
5 Patch-ID: bash32-035
6
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
10
11 Bug-Description:
12
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.
15
16 Patch:
17
18 *** ../bash-3.2-patched/subst.c 2007-12-13 22:31:21.000000000 -0500
19 --- subst.c     2008-01-17 22:48:15.000000000 -0500
20 ***************
21 *** 4621,4627 ****
22   
23   #if defined (JOB_CONTROL)
24     set_sigchld_handler ();
25     stop_making_children ();
26 !   pipeline_pgrp = old_pipeline_pgrp;
27   #else
28     stop_making_children ();
29 --- 4721,4728 ----
30   
31   #if defined (JOB_CONTROL)
32     set_sigchld_handler ();
33     stop_making_children ();
34 !   if (pid != 0)
35 !     pipeline_pgrp = old_pipeline_pgrp;
36   #else
37     stop_making_children ();
38 *** ../bash-3.2-patched/jobs.c  2007-08-25 13:46:59.000000000 -0400
39 --- jobs.c      2007-12-08 16:47:43.000000000 -0500
40 ***************
41 *** 251,254 ****
42 --- 251,255 ----
43   static int set_job_status_and_cleanup __P((int));
44   
45 + static WAIT job_signal_status __P((int));
46   static WAIT raw_job_exit_status __P((int));
47   
48 ***************
49 *** 2220,2223 ****
50 --- 2238,2261 ----
51   }
52   
53 + static WAIT
54 + job_signal_status (job)
55 +      int job;
56 + {
57 +   register PROCESS *p;
58 +   WAIT s;
59
60 +   p = jobs[job]->pipe;
61 +   do
62 +     {
63 +       s = p->status;
64 +       if (WIFSIGNALED(s) || WIFSTOPPED(s))
65 +       break;
66 +       p = p->next;
67 +     }
68 +   while (p != jobs[job]->pipe);
69
70 +   return s;
71 + }
72 +   
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. */
75 ***************
76 *** 2302,2310 ****
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. */
80   
81     /* This is possibly a race condition -- should it go in stop_pipeline? */
82     wait_sigint_received = 0;
83 !   if (job_control == 0)
84       {
85         old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
86 --- 2343,2354 ----
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
92 !      substitution. */
93   
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))
97       {
98         old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
99 ***************
100 *** 2452,2464 ****
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;
104 !         do
105 !           {
106 !             s = p->status;
107 !             if (WIFSIGNALED(s) || WIFSTOPPED(s))
108 !               break;
109 !             p = p->next;
110 !           }
111 !         while (p != jobs[job]->pipe);
112   
113           if (WIFSIGNALED (s) || WIFSTOPPED (s))
114 --- 2496,2500 ----
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);
118   
119           if (WIFSIGNALED (s) || WIFSTOPPED (s))
120 ***************
121 *** 2494,2497 ****
122 --- 2530,2551 ----
123             }
124         }
125 +       else if ((subshell_environment & SUBSHELL_COMSUB) && wait_sigint_received)
126 +       {
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);
131 +       
132 +         if (WIFSIGNALED (s) && WTERMSIG (s) == SIGINT && signal_is_trapped (SIGINT) == 0)
133 +           {
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 ();
139 +             else
140 +               kill (getpid (), SIGINT);
141 +           }
142 +       }
143   
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 --- patchlevel.h        Mon Oct 16 14:22:54 2006
147 ***************
148 *** 26,30 ****
149      looks for to find the patch level (for the sccs version string). */
150   
151 ! #define PATCHLEVEL 34
152   
153   #endif /* _PATCHLEVEL_H_ */
154 --- 26,30 ----
155      looks for to find the patch level (for the sccs version string). */
156   
157 ! #define PATCHLEVEL 35
158   
159   #endif /* _PATCHLEVEL_H_ */
This page took 0.037185 seconds and 3 git commands to generate.