This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]