2009-05-15 7 views
6

J'ai un programme Windows C qui obtient ses données à travers un redirigée tube stdin, un peu comme ceci:dans Windows, comment avoir stdin non-bloquant qui est un tuyau redirigé?

./some-data-generator | ./myprogram 

Le problème est que je dois être capable de lire à partir stdin d'une manière non bloquante. La raison en est que (1) l'entrée est un flux de données et qu'il n'y a pas de EOF et (2) le programme doit être capable d'abandonner son fil d'exécution stdin à tout moment. fread blocs lorsqu'il n'y a pas de données, ce qui rend très difficile.

Dans Unix, cela ne pose aucun problème, car vous pouvez définir le mode de blocage d'un descripteur de fichier avec fcntl et O_NONBLOCK. Cependant, fcntl n'existe pas sur Windows.

J'ai essayé d'utiliser SetNamedPipeHandleState:

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

mais échoue avec ERROR_ACCESS_DENIED (0x5).

Je ne sais pas quoi faire d'autre. Est-ce réellement impossible (!) Ou est-ce simplement très obscurci? Les ressources sur le net sont plutôt rares pour ce problème particulier.

Répondre

3

L'ordre apprach, vérifier qu'il est entré prêt à lire:

  • Pour le mode console, vous pouvez utiliser GetNumberOfConsoleInputEvents().
  • Pour la redirection de conduite, vous pouvez utiliser PeekNamedPipe()
+0

PeekNamedPipe était ce que je cherchais ... Cela vous permet d'appeler ReadFile pour qu'il ne bloque pas. – paleozogt

1

Vous pouvez utiliser des E/S asynchrones pour lire à partir du descripteur, tel que l'appel ReadFileEx() WIN32. Utilisez CancelIo() pour terminer la lecture en l'absence d'entrée.

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

+1

Cela ne fonctionnera pas si la poignée est à un tuyau anonyme - comme il sera dans l'exemple donner à la question. Les E/S superposées (asynchrones) ne sont pas possibles avec les conduites anonymes. –

Questions connexes