GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Nicht blockierender Get-Charakter

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

verwenden
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.)


Linux
  1. Alter der gegebenen Datei abrufen?

  2. Wie liest man eine Variable aus einer Datei?

  3. Dateiberechtigungen unter Linux – Lesen/Schreiben/Ausführen

  4. Holen Sie sich die neueste Datei in einem Verzeichnis unter Linux

  5. Holen Sie sich das letzte Änderungsdatum der Datei in Linux

So lesen Sie Dateien Zeile für Zeile in Bash

So lesen Sie eine Datei Zeile für Zeile in Bash

Datei in Array einlesen?

Wie erhalte ich den vollständigen Pfad einer Datei?

Warum wird select unter Linux verwendet

Holen Sie sich MP3-Länge in Linux / FreeBSD