Socket inheritance with fork/dup2/exec

Lev Bishop lev.bishop@gmail.com
Fri Jun 22 02:36:00 GMT 2007


On 6/21/07, Brian Dessent wrote:
> Jim Powers wrote:
>
> > I am redirecting the stdout of a child process to a socket via the standard
> > fork/dup2/exec paradigm and then reading and displaying the output.
> >
> > This works fine if the exec'd child process is compiled using gcc under
> > cygwin. However, it fails with an "Invalid file handle" error when compiled
> > using VC8 under windows.
> >
> > I've included both the parent and child code below.
>
> I'm fairly sure this isn't supposed to work.  Unix domain sockets
> (AF_UNIX/AF_LOCAL) don't actually exist in any Windows API so Cygwin
> emulates them with an underlying AF_INET socket.  So when your MSVCRT
> program tries to WriteFile to a socket it fails, because you have to use
> the Winsock API for that.  In short, Windows is not unix, and handles
> aren't fds.

Actually, in windows API you can WriteFile() to a socket (as an
optional feature, but the default socket provider supports it). The
problem here is that cygwin opens the underlying socket in overlapped
mode, and the windows API requires treating overlapped handles
differently than non-overlapped. If you'll always be using the same
child, that you have full control over, then you can write the child
to use overlapped semantics. But if you want to be able to pass the
socket to an arbitrary child process then you're out of luck, because
the windows API provides no way for the child to discover that it
needs to use overlapped semantics,  forcing the child to attempt
non-overlapped semantics and fail.

I once wrote a patch to cygwin in an attempt to get around this. It
mostly worked, but windows API calls that were not documented to be
able to block (eg setsockopt()) started blocking on non-overlapped
sockets. Don't you just love the windows API? See:
http://cygwin.com/ml/cygwin-patches/2006-q2/msg00039.html

> You can probably make this work if you use pipe() instead of a
> socketpair() as that maps directly onto a Windows anonymous pipe, which
> is a file handle that can be written to.  You could also use a named
> pipe, which is the closest Windows has to a unix domain socket, but
> there is no corresponding POSIX api for that and so you'd be breaking
> abstraction as you'd have to deal with raw Win32 APIs in your POSIX
> parent app, which is ugly (and not how Cygwin was designed to work
> either.)

Actually, pipe() is implemented in cygwin using win32  named pipes,
not anonymous pipes, as I recall. But, you are right that using pipe()
should solve this particular problem.

Lev

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list