2009-05-15 13 views
6

Bir çeşit böyle bir yönlendirildi stdin borudan verilerini alır Windows C program var:, yeniden yönlendirilmiş bir boru olan engelleyici olmayan stdin nasıl?

./some-data-generator | ./myprogram 

Sorun engellenmeyen bir şekilde stdin okumak gerekiyor olmasıdır. Bunun nedeni, (1) girişin bir veri akışı olmasıdır ve EOF yoktur ve (2) programın herhangi bir zamanda stdin -reading iş parçacığını iptal edebilmesi gerekir. Hiçbir veri olmadığı zaman fread bloklar, bu çok zor hale getirir.

Unix'te, bir dosya tanımlayıcısının engelleme modunu fcntl ve O_NONBLOCK ile ayarlayabildiğinizden, bu hiç sorun değil. Ancak, Windows'ta fcntl bulunmuyor.

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

ama bu ERROR_ACCESS_DENIED (0x5) başarısız:

Ben SetNamedPipeHandleState kullanarak çalıştı.

Başka ne yapacağımı bilmiyorum. Bu aslında imkansız mı (!) Yoksa sadece yüksek gizlenmiş mi? Net üzerindeki kaynaklar bu konu için oldukça seyrek.

cevap

3

sipariş apprach de, okumaya hazır girişi var kontrol edin:

  • konsol modu için, GetNumberOfConsoleInputEvents kullanabilirsiniz(). Boru yönlendirme için
  • , sen PeekNamedPipe kullanabilirsiniz() tanıtıcı anonim borusuna ise çalışmaz
+0

PeekNamedPipe, aradığım şeydi ... Bu, ReadFile öğesini çağırmanıza izin vermez, böylece engellenmez. – paleozogt

1

ReadFileEx() WIN32 çağrısı gibi tanıtıcıdan okumak için eşzamansız I/O kullanabilirsiniz. Giriş yokken okumayı sonlandırmak için CancelIo() öğesini kullanın.

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

+1

- bu örnekte söz konusu vermek olacaktır olarak. Anonim borularla çakışan (async) I/O mümkün değildir. –