On 3/24/10 3:30 PM, Tomáš Trnka wrote:
> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: linux-gnu
> Compiler: gcc
> Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -
> DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -
> DCONF_VENDOR='unknown' -DLOCALEDIR='/home/trnka/opt/share/locale' -
> DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -g -
> O2
> uname output: Linux a324-2 2.6.24.2 #1 SMP Wed Feb 20 12:36:17 CET 2008 
> x86_64 
> GNU/Linux
> Machine Type: x86_64-unknown-linux-gnu
> 
> Bash Version: 4.1
> Patch Level: 2
> Release Status: release
> 
> Description:
> I've started using coprocesses heavily and I've found a nasty problem related 
> (but not limited) to them: After the coprocess finishes its job, the 
> resultant 
> SIGCHLD is not properly blocked by bash signal processing logic and 
> interferes 
> with script I/O. In my case, I've been using something like:
> 
> read var1 var2 < <( a | long | pipeline | here)
> echo "var1=$var1"
> echo "var2=$var2"
> 
> Sometimes, the SIGCHLD arrived just when one of the echos were doing output 
> and the result was:
> echo: write error: Interrupted system call
> As this is a bit of a race, it occurs only when the stars are right, i.e. 
> during normal usage the probability of the SIGCHLD hitting exactly the echo 
> is 
> quite low. However, as soon as anything causes the I/O to take significantly 
> longer, the bug appears. I've been hitting quite often (30%?) when running 
> the 
> script over SSH.

I think there's an easier way to do this.  Try the attached patch and
see what you get.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU    c...@case.edu    http://cnswww.cns.cwru.edu/~chet/
*** ../bash-4.1-patched/sig.c   Fri Aug 14 16:31:52 2009
--- sig.c       Fri Mar 26 22:34:11 2010
***************
*** 655,660 ****
--- 655,663 ----
      act.sa_flags |= SA_INTERRUPT;     /* XXX */
    else
      act.sa_flags |= SA_RESTART;               /* XXX */
+ #else
+   if (sig == SIGCHLD)
+     act.sa_flags |= SA_RESTART;
  #endif
    sigemptyset (&act.sa_mask);
    sigemptyset (&oact.sa_mask);

Reply via email to