This is the mail archive of the
mailing list for the Cygwin project.
Re: Socket inheritance with fork/dup2/exec
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
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:
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
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.
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html