views:

903

answers:

2

I have a Windows C program that gets its data through a redirected stdin pipe, sort of like this:

./some-data-generator | ./myprogram

The problem is that I need to be able to read from stdin in a non-blocking manner. The reason for this is that (1) the input is a data stream and there is no EOF and (2) the program needs to be able to abort its stdin-reading thread at any time. fread blocks when there's no data, so this makes it very difficult.

In Unix this is no problem, as you can set the blocking mode of a file descriptor with fcntl and O_NONBLOCK. However, fcntl doesn't exist on windows.

I tried using SetNamedPipeHandleState:

    DWORD mode= PIPE_READMODE_BYTE|PIPE_NOWAIT;
    BOOL ok= SetNamedPipeHandleState(GetStdHandle(STD_INPUT_HANDLE), &mode, NULL, NULL);
    DWORD err= GetLastError();

but this fails with ERROR_ACCESS_DENIED (0x5).

I'm not sure what else to do. Is this actually impossible (!) or is it just highly obfuscated? The resources on the net are rather sparse for this particular issue.

+1  A: 

You could use async I/O to read from the handle, such as the ReadFileEx() WIN32 call. Use CancelIo() to terminate reading in the absence of input.

See MSDN at http://msdn.microsoft.com/en-us/library/aa365468(VS.85).aspx

Conal
+2  A: 

The order apprach, check there is input ready to read:

  • For console mode, you can use GetNumberOfConsoleInputEvents().
  • For pipe redirection, you can use PeekNamedPipe()
kcwu
PeekNamedPipe was what I was looking for... This allows you to then call ReadFile so that it doesn't block.
paleozogt