I have a long-running console-based application Sender that sends simple text to STDOUT using non-buffered output such as cout << \"Message\" << flush(). I want
I think you have a typo:
CreatePipe(&handles[h_Child_StdOut_Read], &handles[h_Child_StdOut_Write], &sa, 0);
SetHandleInformation(handles[h_Child_StdOut_Read], HANDLE_FLAG_INHERIT, 0);
CreatePipe(&handles[h_Child_StdIn_Read], &handles[h_Child_StdIn_Write], &sa, 0);
SetHandleInformation(handles[h_Child_StdIn_Read], HANDLE_FLAG_INHERIT, 0);
change the last one to
SetHandleInformation(handles[h_Child_StdIn_Write], HANDLE_FLAG_INHERIT, 0);
that's also what they do at the MSDN example.
Besides the error pointed out by @DyP, you are assuming that CreatePipe
opened the handle in overlapped mode. Your assumption is incorrect. Microsoft documents it:
Asynchronous (overlapped) read and write operations are not supported by anonymous pipes. This means that you cannot use the ReadFileEx and WriteFileEx functions with anonymous pipes. In addition, the lpOverlapped parameter of ReadFile and WriteFile is ignored when these functions are used with anonymous pipes.
(Indeed, if you look inside kernel32.dll
, on Windows XP for example, CreatePipe
does not set the lower bit on the seventh parameter to NtCreateNamedPipeFile
; that bit is set when CreateNamedPipe
is called with FILE_FLAG_OVERLAPPED
.)
Look for Dave Hart's MyCreatePipeEx implementation; it can be used as a drop-in replacement for CreatePipe
when overlapped I/O is needed. Simply change PipeSerialNumber++
to InterlockedIncrement(&PipeSerialNumber)
to avoid race conditions in MT code.