Bug 180178 - shells/zsh: hangs upon '>(command)' redirections
Summary: shells/zsh: hangs upon '>(command)' redirections
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Baptiste Daroussin
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-01 20:30 UTC by danielsh
Modified: 2014-06-22 22:56 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description danielsh 2013-07-01 20:30:00 UTC
zsh hangs when commands involving '>(command)' are involved:

[[[
% ssh loki.apache.org 'zsh -fc "echo >(wc -l)"' 
/tmp/zshJHGd5f

]]]

It responds to ^C and ^Z but not to ^D or ^\.

Using ':' or 'true' inside the parentheses yields the same behaviour.

Fix: 

The problem does not appear on either OpenBSD or Linux:

% ssh openbsdbox 'zsh -fc "echo >(true)"' 
/dev/fd/12
% ssh linuxbox 'zsh -fc "echo >(true)"'             
/proc/self/fd/12
How-To-Repeat: zsh -fc "echo >(:)"

OR

zsh -fc ">(:)"
Comment 1 Edwin Groothuis freebsd_committer 2013-07-01 20:30:09 UTC
Responsible Changed
From-To: freebsd-ports-bugs->bapt

Over to maintainer (via the GNATS Auto Assign Tool)
Comment 2 Jilles Tjoelker freebsd_committer 2014-04-05 13:56:55 UTC
In FreeBSD PR ports/180178, you wrote:
> zsh hangs when commands involving '>(command)' are involved:

> [[[
> % ssh loki.apache.org 'zsh -fc "echo >(wc -l)"'
> /tmp/zshJHGd5f
> ]]]

> It responds to ^C and ^Z but not to ^D or ^\.

> Using ':' or 'true' inside the parentheses yields the same behaviour.

A construct like >(CMD) is called process substitution and expands to a
pathname that, when opened, writes to the standard input of CMD. In zsh
(but not bash), the shell also waits for CMD to terminate when the outer
command is done.

The similar <(CMD) expands to a pathname that reads from the standard
output of CMD; the shell does not wait for CMD to terminate.

Depending on whether the full /dev/fd was available when zsh was
compiled (look for zsh_cv_sys_path_dev_fd in configure.ac), zsh uses
either /dev/fd or a fifo to generate the pathname. There is a special
case for redirecting to or from a process substitution which uses an
unnamed pipe.

If zsh uses a fifo, the child process will block until the generated
pathname is opened. If the pathname is never opened, such as when you
echo it, the child process blocks indefinitely. It might be possible to
fix this in zsh by opening the fifo with O_NONBLOCK before deleting it.

If zsh uses /dev/fd, such as when the port is compiled using poudriere,
process substitution does not work unless the full /dev/fd (fdescfs) is
mounted (by default, only /dev/fd/0, /dev/fd/1 and /dev/fd/2 are
available which is not good enough).

-- 
Jilles Tjoelker