AW: 1.5.25-7 piping directed output to /dev/stdout will not work

Corinna Vinschen
Mon Feb 18 13:02:00 GMT 2008

On Feb 16 06:18, Eric Blake wrote:
> The symlink was correctly resolved, and discovered the pipe, but fell back
> to fhandler_base::dup to do the duplication.  At any rate, the open
> succeeded, but fd 3 is now tied to a symbolic name
> (/proc/3448/fd/pipe:[1504] stands for handle 0x5e0).  Then, in the dup2,
> handle 0x5e0 from fd 1 is closed before overlaying fd 3 onto fd 1.
> Finally, the write tries to access the pipe via fd 1, and sends a wakeup
> to the original handle 0x5e0, based on the symbolic name associated with
> fd 3 (now fd 1) - oops; that was the handle that dup already closed.

This might be a bug in the pipe handling, I'm not sure, but the name
associated with the file descriptor is certainly not the reason to access
the 5e0 handle.

> Here, the strace inherits an open handle to f, but does not know which
> file it came from, so it gives up with ENOENT rather than successfully
> creating fd 3.  But since strace is obviously able to dup open handles to
> unknown files, it would seem that open(/proc/self/fd/1) to an unknown file
> handle should work as well.

strace doesn't call dup.  Rather it just inherits the stdio file handles
to the child through the call to CreateProcess.  What you get is a fd 1
in foo which is connected to an unknown file.  Calling open("/dev/stdout")
results in a symlink expansion which points into nirvana.  The open call
fails before it even tries to call an fhandler's open method.

> Not /dev/stdout, per se, but /proc/<pid>/fd/n.  But since /proc is already
> a special device (via fhandler_proc), it seems like such special handling
> should already be happening.  Maybe it's just a matter of writing
> fhandler_proc::dup, or making fhandler_proc::open go through the dup
> machinery.

open ("/dev/stdout") goes through the entire symlink expansion first.
fhandler_process is not involved in the open() call, except in the
symlink expansion stage.  The final path is the path to the pipe. 
Consequentially the open is done by fhandler_pipe::open.  It already
knows when it's opening a pipe of the current process and it calls dup().

dup2 is implemented in the outer layer, dtable::dup2.  It has no
knowledge about the underlying types of file handlers and usually
doesn't need any.  If the target descriptor is opened, it closes it
after duplicating the source handle worked.  I don't see that any
special handling at this point would make any sense.


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Unsubscribe info:
Problem reports:

More information about the Cygwin mailing list