2009-05-15 14 views
6

que tienen un programa de Windows C, que obtiene sus datos a través de un stdin tubería redirigida, algo así como esto:en windows, ¿cómo tener stdin sin bloqueo que es una tubería redirigida?

./some-data-generator | ./myprogram 

El problema es que tengo que ser capaz de leer de stdin en una forma no bloqueante. La razón de esto es que (1) la entrada es una secuencia de datos y no hay EOF y (2) el programa necesita poder abortar su subproceso stdin -reading en cualquier momento. fread bloques cuando no hay datos, por lo que esto lo hace muy difícil.

En Unix esto no es un problema, ya que puede establecer el modo de bloqueo de un descriptor de archivo con fcntl y O_NONBLOCK. Sin embargo, fcntl no existe en Windows.

He intentado utilizar SetNamedPipeHandleState:

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

pero esta falla con ERROR_ACCESS_DENIED (0x5).

No estoy seguro de qué más hacer. ¿Es esto realmente imposible (!) O solo está muy ofuscado? Los recursos en la red son bastante escasos para este problema en particular.

Respuesta

3

El apprach de compra, visita hay una entrada listo para leer:

  • Para el modo de consola, puede utilizar GetNumberOfConsoleInputEvents().
  • para la redirección de la tubería, se puede utilizar PeekNamedPipe()
+0

PeekNamedPipe era lo que estaba buscando ... Esto le permite llamar a ReadFile para que no se bloquee. – paleozogt

1

Puede usar la E/S asíncrona para leer desde el identificador, como la llamada de ReadFileEx() WIN32. Use CancelIo() para terminar la lectura en ausencia de entrada.

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

+1

que no funciona si el mango es un tubo en el anonimato - ya que será en el ejemplo de dar en la pregunta. La E/S superpuesta (asíncrona) no es posible con tuberías anónimas. –

Cuestiones relacionadas