Please don't http://cygwin.com/acronyms/#TOFU Thank you.
On Apr 24 13:37, cyg...@alanhowells.e4ward.com wrote: > Thank you very much James for the helpful comments and pointer to your > sample program. > > I have some more information and I tried to minimise .NET and so wrote > the program in C++, compiled with "cl /EHs consoleout.cxx /link" > > >>> begin consoleout.cxx > #include <windows.h> > > int > main(int argc, char* argv[]) > { > DWORD written; > > // Get standard output file handle > HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); > > // Do a null write. This is what .net does. > WriteFile(h, "", 0, &written, NULL); > > for (int i = 1; i < argc; ++i) { > DWORD toWrite = strlen(argv[i]); > WriteFile(h, argv[i], toWrite, &written, NULL); > WriteFile(h, "\n", 1, &written, NULL); > } > > return EXIT_SUCCESS; > } > <<< end consoleout.cxx > > The strange thing here is that I get the issue on the first time (but > not the second or third): > $ ./consoleout hello world | ./readin > $ ./consoleout hello world | ./readin > hello > world > $ ./consoleout hello world | ./readin > hello > world > $ This problem has nothing to do with Cygwin, as far as I can see. What happens is that the shell creates the pipe for you and then starts two native Child processes, consoleout and readin, which use the existing pipe without any interference from Cygwin. So you have to look into the testcases itself to find the cause for the problem. And here we go: > >>> begin readin.cxx > #include <windows.h> > > int > main(int argc, char* argv[]) > { > static_cast<void>(argc); > static_cast<void>(argv); > > HANDLE hi = GetStdHandle(STD_INPUT_HANDLE); > HANDLE ho = GetStdHandle(STD_OUTPUT_HANDLE); > > char buf[1024]; > DWORD read, written; > ReadFile(hi, buf, 1024, &read, NULL); > WriteFile(ho, buf, read, &written, NULL); > > return EXIT_SUCCESS; > } > >>> end readin.cxx So, while your writer *writes* a 0 bytes block, your reader doesn't *expect* a 0 bytes block, even though that's exactly what this case is about. Even worse, your readin testcase doesn't expect short reads at all. Consider the processes are scheduled interlaced: WriteFile (""); ReadFile(); WriteFile ("hello"); ReadFile(); WriteFile ("\n"); ReadFile(); WriteFile ("world"); ReadFile(); WriteFile ("\n"); ReadFile(); If you change your application accordingly, it will work as expected: #include <windows.h> int main(int argc, char* argv[]) { static_cast<void>(argc); static_cast<void>(argv); HANDLE hi = GetStdHandle(STD_INPUT_HANDLE); HANDLE ho = GetStdHandle(STD_OUTPUT_HANDLE); char buf[1024]; DWORD read, written; BOOL ret; do { ret = ReadFile(hi, buf, 1024, &read, NULL); if (ret && read > 0) WriteFile(ho, buf, read, &written, NULL); } while (ret); return EXIT_SUCCESS; } Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- 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