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 [email protected] 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);