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);