views:

30

answers:

1

My question is related to "Turn off buffering in pipe" albeit concerning Windows rather than Unix.

I'm writing a Make clone and to stop parallel processes from thrashing each others' console output I've redirected the output to pipes (as described in here) on which I can do any filtering I want. Unfortunately long-running processes now buffer up their output rather than sending it in real-time as they would on a console.

From peeking at the MSVCRT sources it seems the root cause is that GetFileType() is used to check whether the standard I/O handles are attached to a console, which then sets an internal flag and ends up disabling buffering.

Apparently a separate array of inheritable file handles and flags can also be passed on through the undocumented lpReserved2 member of the STARTUPINFO structured when creating the process. About the only working solution I've figured out is to use this list and just lie about the device type when setting the flags for stdout/stderr.

Now then... Is there any sane way of solving this problem?

+1  A: 

There is not. Yes, GetFileType() tells it that stdout is no longer a char device, _isatty() return false so the CRT switches the output stream to buffered mode. Important to get reasonable thoughput. Flushing output one character at a time is only acceptable when a human is looking at them.

You would have to relink the programs you are trying to redirect with a customized version of the CRT. I don't doubt that if that was possible, you wouldn't be messing with this in the first place. Patching GetFileType() is another un-sane solution.

Hans Passant
This is done not only to improve performance, but to conform with the standard(s). C99, §7.19.3/7: "...the standard input and standardoutput streams are fully buffered if and only if the stream can be determined not to refer to an interactive device."
Jerry Coffin