> I am calling a few different .NET Framework 4.0 command line tools from > Cygwin and have noted that .NET Framework 4.0 introduced a change that > causes an incompatibility between it and Cygwin. I have carefully examined > .NET Framework 4.0 source code and also checked things out with an API > monitor utility, and have arrived at a simple test case in straight Win32 C > code. > > <snip test case that calls WaitForSingleObject with unsupported pipe handle> > > Then run this from bash shell: > > ( sleep 3 ; echo test ) | ./ReaderCPP > > This issue will affect every .NET Framework 4.0 program that attempts to > read from standard input.
I narrowed down the problem. The stdin file handle inherited by the non-Cygwin program ReaderCPP is an overlapped file handle. I wrote a simple Win32 C test case that uses CreateNamedPipe & CreateFile like Cygwin does in fhandler_pipe::create in pipes.cc file. The test case opens both handles with FILE_FLAG_OVERLAPPED. It then calls CreateProcess to start WriterCPP (containing a Sleep & a WriteFile to stdout) and the existing ReaderCPP program. The pipe is used to connect WriterCPP's stdout to ReaderCPP's stdin. This causes ReaderCPP to hang, just like it was when called from Cygwin. If I remove the problematic WaitForMultipleObjectsEx call from ReaderCPP, then everything works normally. Alternatively, if I modify the program to NOT open pipes in overlapped mode, the WaitForMultipleObjectsEx is no longer a problem - pointing to the solution. I can send sample code if it would be helpful to anyone. As far as I'm aware, this practice of passing overlapped standard file handles to Win32 child processes is probably unique to Cygwin. The standard CMD.EXE doesn't do it, for example. One reason why this probably MUST be the case is given in the MSDN docs for ReadFile: "A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL." This is further confirmed in the remarks ("The lpOverlapped parameter must not be NULL"). Because probably every Win32 program in existence isn't normally using overlapped I/O with their standard file handles, this causes all of them to exhibit undefined behavior. The bottom line is that .NET Framework 4.0 programs will hang when they try to read from standard input unless Cygwin can give them pipe handles that were NOT opened with overlapped I/O. Also, any standard Win32 program will exhibit undefined behavior because most (all?) Win32 C runtime libraries do not use overlapped I/O with the standard file handles. This will require modifications to Cygwin. It seems that fhandler_pipe::create needs to NOT create overlapped pipes - at least in the case of pipes destined for standard Win32 programs' stdin. That might be easier said than done, however. On the other hand, a blanket change of removing FILE_FLAG_OVERLAPPED carries the risk of breaking existing code in Cygwin - I don't know how catastrophic such a change might be. Any ideas? If removing this flag causes breakage only in rare edge cases or results in non-POSIX behavior (or no breakage at all), perhaps this behavior can be customized via a flag in the CYGWIN environment variable. On the other hand, if removing the flag causes mass breakage, I am not sure what the solution should be. Best regards, James Johnston -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple