From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18917 invoked by alias); 24 Dec 2011 09:33:19 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 30054 Received: (qmail 8368 invoked from network); 24 Dec 2011 09:33:15 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <111224013252.ZM22819@torch.brasslantern.com> Date: Sat, 24 Dec 2011 01:32:52 -0800 In-reply-to: <87hb0rueem.fsf@ft.bewatermyfriend.org> Comments: In reply to Frank Terbeck "Re: $pipestatus broken?" (Dec 23, 11:11pm) References: <87borgzkap.fsf@ft.bewatermyfriend.org> <877h24zj69.fsf@ft.bewatermyfriend.org> <111210065833.ZM6198@torch.brasslantern.com> <877h1nwojx.fsf@ft.bewatermyfriend.org> <111223133128.ZM17298@torch.brasslantern.com> <87hb0rueem.fsf@ft.bewatermyfriend.org> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: $pipestatus broken? MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Dec 23, 11:11pm, Frank Terbeck wrote: } } ...unless, of course, the loop just needs to be there to delay the RHS, } for the exit/reap to happen as you suggested. Hmm, this is getting a bit hairy. In the simple case { echo foo | read -E }, there is a single job table entry for "read" which is the group leader for the pipeline. In the loop case { echo foo | repeat 1; read -E } there is a job table entry for the loop which is the group leader, but a new entry is created for "read -E". execpline() remembers the previous thisjob as the local "pj" and restores thisjob = pj at line 1619, but by that time it is too late -- waitjobs() has set thisjob = -1 for just long enough for zhandler() to call update_job(), which fails to update the pipestats because thisjob = -1 tells it there is no current job. The following seems to fix it, by telling waitjobs() what the previous job number was so it can be reset immediately. There may still be a race condition that requires fiddling with signal blocks to make sure thisjob is correct at the time the zhandler() catches the signal, but if so this should at least allow the block/unblock to be localized. Index: Src/exec.c =================================================================== --- Src/exec.c 20 Dec 2011 17:13:38 -0000 1.43 +++ Src/exec.c 24 Dec 2011 09:22:57 -0000 @@ -1516,7 +1516,7 @@ } if (!(jn->stat & STAT_LOCKED)) { updated = hasprocs(thisjob); - waitjobs(); + waitjobs(pj); child_block(); } else updated = 0; @@ -3339,7 +3339,7 @@ close(i); closem(FDT_UNUSED); if (thisjob != -1) - waitjobs(); + waitjobs(-1); _exit(lastval); } fixfds(save); Index: Src/jobs.c =================================================================== --- Src/jobs.c 20 Dec 2011 17:13:38 -0000 1.31 +++ Src/jobs.c 24 Dec 2011 09:23:34 -0000 @@ -1363,7 +1363,7 @@ /**/ void -waitjobs(void) +waitjobs(int prevjob) { Job jn = jobtab + thisjob; DPUTS(thisjob == -1, "No valid job in waitjobs."); @@ -1375,7 +1375,7 @@ pipestats[0] = lastval; numpipestats = 1; } - thisjob = -1; + thisjob = prevjob; } /* clear job table when entering subshells */ @@ -2072,7 +2072,7 @@ * when we've just been told to wait for another * job (and done it)? */ - waitjobs(); + waitjobs(-1); retval = lastval2; } else if (ofunc == BIN_DISOWN) deletejob(jobtab + job, 1);