X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=4.0 required=5.0 tests=AWL,BAYES_00,BOTNET,DKIM_SIGNED,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,T_DKIM_INVALID,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org MIME-Version: 1.0 In-Reply-To: References: <00e101cd1f09$83405310$89c0f930$@motionview3d.com> From: Date: Wed, 25 Apr 2012 15:19:26 +0100 Message-ID: Subject: Re: 1.7.10->1.7.13 : output from .NET programs does not get through pipeline to a visual c++ program To: cygwin AT cygwin DOT com Content-Type: text/plain; charset=ISO-8859-1 Reply-To: cygwin AT alanhowells DOT e4ward DOT com X-e4ward-RCPT: cygwin-cygwin DOT com-cygwin-alanhowells DOT e4ward DOT com-120725-b79e-5 AT reply DOT e4ward DOT com Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com > Please don't http://cygwin.com/acronyms/#TOFU My apologies I know my test code wasn't robust, I just wanted to get something going to prove any issues. Anyway, I still have the issue when using std::cin. Let me start again and give you some programs and show you what is happening. I have 4 programs, consoleout1 (a C# program calling PInvoke methods which replicates Console.Out.WriteLine at its minimum), consoleout2 (a c++ program calling the same Win32 methods as consoleout1), readin1 (a c++ program that uses std::cin to read from the console) and readin2 (a c++ program uses Win32 to read from the console). Here are the results $ ./consoleout1.exe hello world | ./readin1.exe $ ./consoleout1.exe hello world | ./readin1.exe $ ./consoleout1.exe hello world | ./readin2.exe hello world $ ./consoleout2.exe hello world | ./readin1.exe $ ./consoleout2.exe hello world | ./readin1.exe hello world $ ./consoleout2.exe hello world | ./readin2.exe hello world $ There are two issues, 1. When consoleout1 pipes to readin1, readin1 never receives output from consoleout1. 2. When consoleout2 pipes to readin1, the first time the readin1 does not recieve the output from consoleout2. This makes me think that std::cin has issues but this definitely worked on 1.7.9 and below. Also, it is frustrating to partially replicate it in C++. These all work in the MS command prompt (cmd). Here are the basic programs: >>> begin consoleout1.cs compiled with "csc /optimize /target:exe /out:./consoleout1.exe /unsafe consoleout1.cs" namespace consoleout { using System; using System.Linq; using System.Runtime.InteropServices; internal static class Program { [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetStdHandle(int nStdHandle); [DllImport("kernel32.dll", SetLastError = true)] internal unsafe static extern int WriteFile(IntPtr handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero); private unsafe static void Main(string[] args) { IntPtr hFile = GetStdHandle(-11); byte b = 65; int num; WriteFile(hFile, &b, 0, out num, IntPtr.Zero); foreach (string arg in args) { string newValue = arg + "\r\n"; // This works only for ASCII but will do for our example. byte[] bytes = newValue.Select(c => (byte)c).ToArray(); int result = 0; fixed (byte* ptr = bytes) { WriteFile(hFile, ptr, bytes.Length, out result, IntPtr.Zero); } } } } } <<< end consoleout1.cs >>> begin consoleout2.cxx compiled with "cl /EHs consoleout2.cxx /link" #include #include 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. char c = 65; BOOL writeOK = WriteFile(h, &c, 0, &written, NULL); assert(writeOK); for (int i = 1; i < argc; ++i) { DWORD toWrite = strlen(argv[i]); WriteFile(h, argv[i], toWrite, &written, NULL); WriteFile(h, "\r\n", 2, &written, NULL); } return EXIT_SUCCESS; } <<< end consoleout2.cxx >>> begin readin1.cxx compiled with "cl /EHs readin1.cxx /link" #include #include int main(int argc, char* argv[]) { static_cast(argc); static_cast(argv); std::string buf; buf.reserve(1024); while (std::getline(std::cin, buf, '\n')) { std::cout << buf << '\n'; } return EXIT_SUCCESS; } <<< end readin1.cxx >>> begin readin2.cxx compiled with "cl /EHs readin2.cxx /link" #include int main(int argc, char* argv[]) { static_cast(argc); static_cast(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; } <<< end readin2.cxx -- 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