From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20204 invoked by alias); 16 Sep 2016 18:37:53 -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: 39364 Received: (qmail 8601 invoked from network); 16 Sep 2016 18:37:53 -0000 X-Qmail-Scanner-Diagnostics: from mail-pa0-f41.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(209.85.220.41):SA:0(0.0/5.0):. Processed in 0.649487 secs); 16 Sep 2016 18:37:53 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.1 X-Envelope-From: schaefer@brasslantern.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: none (ns1.primenet.com.au: domain at brasslantern.com does not designate permitted sender hosts) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:in-reply-to:comments:references:to:subject :mime-version; bh=ACmmmp+YNysCibDOwxKNeqXvZujrp+lCFT830/GyIFg=; b=skGEKF7JLHlGErLJ5BiJpebS04HDZNK1AwK23zASgDHxRE9nyPgsxOJWt4gxx0uMJZ PVJ5NaI2p8u9hWx9Nv3FSfVLoU9iVerkNcyeNSvSeKW3j93EPtRGiQo3ZscljK6O5F6/ Qri1vPyYiA3l+W3xHG6JcdgPjkYDv1jeFLzT28iYBfahhH9jb61npWy10WNmjIg6PXbk tpjN3RSK7RUQKz9/7CLVE39SI20UDJCTWAiTjQjo7GjD+Iks908MPgQq1p2k/ehYeufC o3ADo0haHJyHrcGNHtYp98+zr/LqTtq/EMck8vOicqleJ5lSUiYCueyYIkzLVwD2eFw2 pGwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:to:subject:mime-version; bh=ACmmmp+YNysCibDOwxKNeqXvZujrp+lCFT830/GyIFg=; b=CXXemLln7IdTzHUBXBBdm33gFF0LF5aAkEJKDmMFLANnW6ZaLH4GSOyGDYIlyAFGWn BQsY9HOiR9/vlS7DCu9M9gVijEfFY01ZRVcATh5/UW+fdQxqXMyrQ3arVn+k7RbbJHjE Mgmii2IoYN7hHwWc7mXbZ9sKSxaxbZQs2lHR/nnvmkZX8K7UR2PRmlTFa/EZg7ITLO/N FanVaWbsh8AqFhk6CvYNbbBTGXM2erdEsdv22tZzU/qyrH23WiV3VS6JFYu7l5iYpUiO EmcqS7LvPR8RycAhTslYqY7VhedjcfKTCG0T0Q8PUJGRtwR3goaQe+a9VqE4LkxzztAJ 6uqQ== X-Gm-Message-State: AE9vXwPBvVTgdlEh4jx420URlGbUJafHENo1xGklFikbeJBQqTeUMbROcb5CN9ozKddGhg== X-Received: by 10.66.19.197 with SMTP id h5mr5311031pae.142.1474051066414; Fri, 16 Sep 2016 11:37:46 -0700 (PDT) From: Bart Schaefer Message-Id: <160916113801.ZM11473@torch.brasslantern.com> Date: Fri, 16 Sep 2016 11:38:01 -0700 In-Reply-To: <20160916133302.1f447ca0@pwslap01u.europe.root.pri> Comments: In reply to Peter Stephenson "Another bug when suspending pipelines" (Sep 16, 1:33pm) References: <20160916133302.1f447ca0@pwslap01u.europe.root.pri> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: "Zsh Hackers' List" Subject: Re: Another bug when suspending pipelines MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Sep 16, 1:33pm, Peter Stephenson wrote: } Subject: Another bug when suspending pipelines } } To check my code for the other pipeline suspending problem, I came up } with a command designed to check different cases, in particular where } the left of the pipeline was still running: } } (sleep 5; print foo) | { sleep 5; read bar; print $bar; } } } Suspending this sometimes doesn't work: the ^Z is delayed and gets } relayed to the parent shell. In this construct, the "read" is going to be running in the current zsh; that is: % (sleep 5; print foo) | { sleep 5; read bar; print GOT: $bar; } should print "GOT: foo" even after ^Z/fg, whereas % (sleep 5; print foo) | { sleep 5; read bar }; print GOT: $bar should print "GOT: foo" if it runs un-interrupted, but should print nothing if ^Z/fg. Therefore the current (parent) shell is required to handle the TSTP in this case. } I have no handle on what aspect of this is problematic, but I don't } see anything about the shell code above that suggests this is a } particularly hairy case. Let's tweak this slightly to be (sleep 6; print foo) | { sleep 7; read bar; print $bar } just for clarity in the following description. I believe what should be happening is: * The "sleep 7" is initially the tty group leader, because it is the foreground job in the parent shell. "sleep 6" and its subshell parent will not be in this process group because they were started before "sleep 7" existed; instead they are in the process group of the original parent. * If the keyboard signal is generated during "sleep 7", sleep gets a SIGTSTP, is stopped, and the parent shell is notified by SIGCHLD. The parent reads the wait() status and finds that the foregroup job has stopped. * The parent responds by stopping all the other jobs in the current pipeline. It forks the brace expression into a new process and stops that one as well (or maybe that one stops itself, I don't recall the exact sequence of events here). * The parent reclaims the tty leadership and returns to the prompt. You can see this happen by adding "print $sysparams[pid]" on both sides of the "sleep 7"; you will get a different PID before and after the ^Z/fg. So now we have two different process groups: The "sleep 7" all by itself, and the parent shell, whose group includes two more jobs, the subshell and the rest of the brace expression. The parent has to manage all three of these jobs, because it can't hand off the already-forked "sleep 7" to the newly-forked brace job. It has to arrange that the brace job can be sent a SIGCONT on "fg" but not actually do anything until the "sleep 7" has finished; I believe that's handled by the "synch" pipes and hidden reads; in any case, it works. On "fg" the parent: * makes "sleep 7" the tty group leader again * sends SIGCONT everywhere * and waits for "sleep 7" to exit. If I'm correct about the synch pipe, the tail of the brace expression is blocked waiting to read that. When "sleep 7" finally exits, the parent: * makes the tail of the brace expression into a process group which becomes the tty leader, and * writes a byte on the synch pipe to wake it up. And now we're finally back to the same state we'd have started in if the brace expression had instead been a subshell, and the parent may proceed with simply waiting for children. "Particularly hairy"? When the forked brace expression stops, the parent is going to be notified about that again, possibly by SIGCHLD. If it mis-handles that, it could be the source of your observed "the ^Z is delayed" and consequently cause an incorrect second pass through "stopping all other jobs in the current pipeline". But I can't reproduce the double-stop to confirm that.