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: 1.7.10->1.7.13 : output from .NET programs does not get through pipeline to a visual c++ program


> -----Original Message-----
> Sent: Tuesday, April 24, 2012 12:38
> Subject: Re: 1.7.10->1.7.13 : output from .NET programs does not get
through
> pipeline to a visual c++ program
> 
> >>> 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

What Corinna said... your problem is that you don't have a loop.  The reason
your program sometimes works and sometimes not is that sometimes the
execution of readin is delayed long enough such that you get all the data
buffered in the STD_INPUT_HANDLE pipe, and your program seems to work.
Other times, all you might get is only the null write, or only the "hello"
but not the "world".  That's because your consoleout program hasn't actually
written all its data yet - so ReadFile is only going to send you what it
knows and has buffered - it figures a partial response is better than
waiting (important for a network protocol or other device where the next
bytes could be a long time before they arrive, if ever!).  It's just random
luck, subject to the whims of the operating system scheduler.

In general, one must remember that when reading from a stream or file, the
read may be incomplete - not all data may yet be received, so the function
just returns what is buffered.  It is necessary to loop until either
end-of-file is reached, or a special terminating character or sequence is
reached, depending on the file format, network protocol, etc. (e.g. a
newline).  In your case, you'd loop until end-of-file is reached, which is
just what the built-in utilities like cat, grep, etc. do.

Sometimes, depending on the stream class / file API being used, you have to
write in a loop too - for example, WriteFile returns a parameter indicating
how many bytes were actually written; you would need to loop until all bytes
have actually been written.  It's possible that the underlying device just
isn't ready to handle all the data you are providing, so it will only bite
off an appropriately-sized chunk from what you provided.  (Other APIs, such
as .NET's Stream class, will block until all bytes have been written.)

I mention these things because I see too much code where programmers assume
just a single read or write covers what they need and it happens to work on
their computer - never mind that it would break on 5% of customer
computers/networks!  (Cleaning up things like that is not an enjoyable use
of time...)

James


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


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