(Apologies - I also posted this in the Windows SDK sub-forum, however I think this sub-forum is more appropriate)
Hi there, I am writing a small utility console application that spawns two other console applications. These applications are actually chess engines, using the UCI protocol (a simple text protocol designed to allow the GUI and engine elements to be separated and the engines to be interchanged).
Anyway I am having problems successfully reading the output from the spawned processes. My main thread does something like this (following the sample code here http://support.microsoft.com/kb/190351):
1) Create two anonymous pipes for each of the engines.
2) Duplicate the engine stdout pipe to be its stderr pipe.
3) Use SetHandleInformation set to my side of the pipes as being uninheritable (have also tried use DuplicateHandle to do this - it makes no difference).
4) Create the process in a new console, using the new in/out/err handles.
5) Create an I/O thread to manage the I/O between my program and the engines. This uses simple I/O queue objects to communicate from and to the engine. It employs thread locking (critical section), and event notification (auto-reset event object) .
6) Perform comms to the engines via the I/O queues.
Now the I/O thread uses WaitForMultipleObjects to listen for the output pipes from the engines to become signalled and also for the event objects on each of the 'to engine' I/O queues to become signalled (i.e. there is something to send to the engines).
The problem I am having is that using a ReadFile on the pipes from the engines often causes a block, which I understand and it seems the correct solution to this is to use PeekNamedPipe to see how many characters are available. Once you know this you can then use ReadFile to read the correct number of characters. However when I use PeekNamedPipe, the lpTotalBytesAvail is always returned as 0 and I/O thread spends all its time being told a pipe has data and being unable to find any data to read. I have tried various combinatons of parameters to PeekNamedPipe, but it makes no difference.