From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14316 invoked by alias); 13 Aug 2017 18:49:45 -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: 41538 Received: (qmail 4848 invoked by uid 1010); 13 Aug 2017 18:49:45 -0000 X-Qmail-Scanner-Diagnostics: from know-smtprelay-omc-9.server.virginmedia.net 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(80.0.253.73):SA:0(-2.8/5.0):. Processed in 0.851735 secs); 13 Aug 2017 18:49:45 -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=-2.8 required=5.0 tests=RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: p.w.stephenson@ntlworld.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | X-Originating-IP: [86.21.219.59] X-Authenticated-User: p.w.stephenson@ntlworld.com X-Spam: 0 X-Authority: v=2.1 cv=aJkN0uJm c=1 sm=1 tr=0 a=utowdAHh8RITBM/6U1BPxA==:117 a=utowdAHh8RITBM/6U1BPxA==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=x7bEGLp0ZPQA:10 a=pGLkceISAAAA:8 a=Kp_KwRXVUMslTirrju4A:9 a=CjuIK1q_8ugA:10 a=6kGIvZw6iX1k4Y-7sg4_:22 Date: Sun, 13 Aug 2017 19:49:39 +0100 From: Peter Stephenson To: Zsh hackers list Subject: Re: fd used for saving redirected fds leaked to child processes Message-ID: <20170813194939.7a96bc4b@ntlworld.com> In-Reply-To: <20170813161207.GA6530@chaz.gmail.com> References: <20170813161207.GA6530@chaz.gmail.com> X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ntlworld.com; s=meg.feb2017; t=1502650179; bh=E9sBBqFTljYQfnAPlUu+wruXL4xpOxjEPvKB0PlqTSk=; h=Date:From:To:Subject:In-Reply-To:References; b=qI6bcj5u5/aBclIgmBrJbopBbbFcMaqQuDuwoPw2L9GEOpWNjL4voHXyPmYPYDHI7 Y5l0ChQ/6LrbuXWwWONR+WlYU1T1Q434oVFz/jqFRIBk3BO1kE2UhjCdpRlTn6rITb rH2PeSv3YTbb6ysKuR4pP6QSs9++oiD/wR7SU1PXmbzFAdSU1DwUpZa7lOuTmJVKKQ 0Tbx4nV3pc2eJzUWHR0fIDBRZMgnwpx4wcvPSdzLGpFRLNr/2i6h9pAhVT0WyAdKfr dAohL5NdkkywY/iS11jqqmUu/eEY03wdUxOWhfasHNgc+MpHZv3NHwOMvcXHQzAGi8 1oyCkgEtKExBw== On Sun, 13 Aug 2017 17:12:07 +0100 Stephane Chazelas wrote: > In: > > mkfifo fifo > zsh -c '{ echo GO > fifo & echo $!; } > pid; echo done' | cat > > "cat" hangs until some process open the fifo in read mode, even > though that "echo GO > fifo" command was run in background and > "done" is output straight away. > > What we see is the child zsh process opening the "fifo" having > a fd open on the pipe to cat: > > zsh 28400 chazelas 12w FIFO 0,10 0t0 125690 pipe 28399,cat,0r > > I think that fd was the one that was dupped from stdout by its > parent to /save/ stdout before doing the > pid redirection (so > it can be used to restore stdout after the command group > returns). That explanation makes sense, in which case I think this fix should be good enough. pws diff --git a/Src/exec.c b/Src/exec.c index f339dd6..61ae5e8 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -947,6 +947,14 @@ hashcmd(char *arg0, char **pp) int forklevel; +/* FDs saved for possible restoring, not needed in a subshell + * where we will never need to restore them. Hence if we enter + * a subshell these will simply be closed unconditionally. + * + * A value >= 10 indicates a valid saved fd. + */ +static int saved_fds[10]; + /* Arguments to entersubsh() */ enum { /* Subshell is to be run asynchronously (else synchronously) */ @@ -972,7 +980,7 @@ enum { static void entersubsh(int flags) { - int sig, monitor, job_control_ok; + int i, sig, monitor, job_control_ok; if (!(flags & ESUB_KEEPTRAP)) for (sig = 0; sig < SIGCOUNT; sig++) @@ -1083,6 +1091,12 @@ entersubsh(int flags) opts[MONITOR] = 0; opts[USEZLE] = 0; zleactive = 0; + for (i = 0; i != 10; i++) { + if (saved_fds[i] >= 10) { + close(saved_fds[i]); + saved_fds[i] = 0; + } + } if (flags & ESUB_PGRP) clearjobtab(monitor); get_usage(); @@ -2318,6 +2332,7 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag, return; } save[fd1] = fdN; + saved_fds[fd1] = fdN; } } } @@ -4249,9 +4264,12 @@ fixfds(int *save) int old_errno = errno; int i; - for (i = 0; i != 10; i++) + for (i = 0; i != 10; i++) { if (save[i] != -2) redup(save[i], i); + if (save[i] >= 10) + saved_fds[i] = 0; + } errno = old_errno; }