Sie führen IO falsch aus, das POSIX-Handbuch und alle anderen zugehörigen Dokumentationen sagen ausdrücklich, dass IO niemals auf FILE *
durchgeführt werden soll s und Dateideskriptoren. Sie haben diese Regel sehr eklatant gebrochen. Diese Regel gilt wegen FILE *
s Verwenden Sie Pufferung und dies bedeutet, dass nach einem Aufruf von fgets
für read
bleibt nichts übrig weil fgets
zu bekommen bereits alle anstehenden Daten in einen Puffer eingelesen, der im FILE *
gehalten wird Struktur.
Da es also keine Möglichkeit gibt zu prüfen, ob eine ISO-C-IO-Methode blockiert, müssen wir nur Dateideskriptoren verwenden.
Da wir wissen, dass STDIN_FILENO
nur die Zahl 0 ist, können wir
fcntl (0, F_SETFL, O_NONBLOCK);
dadurch werden alle read
s auf Dateideskriptor 0 in den nicht blockierenden Modus, wenn Sie einen anderen Dateideskriptor verwenden möchten, damit Sie 0 in Ruhe lassen können, dann verwenden Sie einfach dup
um es zu duplizieren.
Auf diese Weise können Sie sich von poll
fernhalten komplettieren und ngetc
implementieren als
ssize_t
ngetc (char *c)
{
return read (0, c, 1);
}
oder noch besser ein Makro
#define ngetc(c) (read (0, (c), 1))
So erhalten Sie eine einfache Implementierung für das, was Sie suchen.
Bearbeiten: Wenn Sie sich immer noch Sorgen darüber machen, dass das Terminal die Eingabe puffert, können Sie jederzeit die Einstellungen des Terminals ändern, siehe So deaktivieren Sie die Zeilenpufferung der Eingabe in xterm vom Programm aus? Weitere Informationen dazu finden Sie hier.
Bearbeiten: Der Grund, warum man fgetc
nicht verwenden konnte statt read
hat denselben Grund wie die Verwendung von fgets
wird nicht funktionieren. Wenn einer der FILE *
IO-Funktionen ausgeführt werden, liest es alle Daten aus dem zugehörigen Dateideskriptor. Aber sobald das passiert, poll
wird niemals zurückkehren, weil es auf einen Dateideskriptor wartet, der immer leer ist, und dasselbe passiert mit read
. Daher schlage ich vor, dass Sie dem Rat der Dokumentation folgen und niemals Streams mischen (E/A mit fgets
, fgetc
, usw.) und Dateideskriptoren (E/A mit read
, write
usw.)