Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: bug with eval, proc-subst and pipes

On Mon, 15 Jul 2013 10:06:24 -0700
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> On Jul 15,  2:35pm, Stephane Chazelas wrote:
> } Subject: bug with eval, proc-subst and pipes
> }
> } NOK$ eval 'paste <(echo 1) <(echo 2) <(echo 3) <(echo 4)' | cat
> } paste: /proc/self/fd/13: No such file or directory
> It's a race condition of some kind.  I can reproduce reliably with
> % (){ sleep 5; paste "$@" } <(echo 1)
> even without an "eval".

That's not a race; it looks like it because it relies on a command
running before the one that's using the command substitution, but in
fact the bug in this case is completely deterministic.  It may therefore
be a different problem from Stephane's.

The shell executes the () { ... }; it creates fd 11 (in this case, the
first beyond 10 which is SHTTY).  It marks it in the global fdtable
array as FDT_PROC_SUBST.

Now it starts executing inside the anonymous function.  It starts processing the
sleep and gets to the chunk in execcmd() where it handles the fork.  At
line 2864 of exec.c, as it's in the function that's calling sleep, it
closes all the file descriptors of type FDT_PROC_SUBST that it thinks
are private to the sleep.  Unfortunately as fdtable is global it has no
way of knowing that actually fd 11 is associated with the current
function, not the sleep, so it closes it anyway.  So when it gets to the
paste fd 11 is already closed.

I suppose a smarter way of marking such file descriptors is needed,
perhaps one associated with the appropriate job in the same way as
auxiliary processes are remembered.  Good luck avoiding leaks...

Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/

Messages sorted by: Reverse Date, Date, Thread, Author