Wie überprüft man, ob stdin noch geöffnet ist, ohne zu blockieren?

8

Ich brauche mein Programm in reinem C geschrieben, um die Ausführung zu stoppen, wenn die stdin geschlossen ist.

Es gibt unbestimmte Arbeit im Programm Hauptzyklus, und es gibt keine Möglichkeit, dass ich blockierende Prüfungen (wie getc() ) dort verwenden kann (keine Daten sollen auf stdin ankommen - es bleibt nur für unbekannte Zeit geöffnet).

Ich beabsichtige, die beschriebene Funktionalität bei der Realisierung des in inetd, xinetd oder ihren Analoga gehosteten Netzwerk-Daemons zu verwenden - er sollte Daten auf stdout ausgeben, während die Verbindung geöffnet bleibt und die Arbeit beim Schließen korrekt beendet. Jetzt wird mein Programm von Hosting-Service getötet, wie es nach Beendigung der Verbindung nicht aufhören wird.

Ich frage mich, ob fctntl() mit O_NONBLOCK Flag, das auf den stdin-Deskriptor angewendet wird, mir erlaubt, read() function im nicht-blockierenden Modus zu verwenden? Soll ich irgendwie select() benutzen?

P.S. Die Daten werden nicht angenommen, könnten aber in stdin ankommen. Ein Weg des nicht blockierenden Auslesens wäre eine Antwort auf die Frage.

    
Basilevs 20.10.2009, 12:27
quelle

5 Antworten

6

select () macht genau das, was Sie wollen: signalisieren, dass eine Operation (in diesem Fall gelesen) auf einen Dateideskriptor (Datei, Socket, was auch immer) nicht blockiert wird.

%Vor%

Sie können nun vor der Verwendung einen Dateideskriptor überprüfen, um beispielsweise den Dateideskriptor zu leeren:

%Vor%

Verwenden Sie in Ihrem Fall fileno (stdin) , um den Dateideskriptor von stdin:

zu erhalten %Vor%     
digitalarbeiter 20.10.2009, 13:12
quelle
2
  

Ich frage mich, ob fcntl () mit dem O_NONBLOCK-Flag, das auf den stdin-Deskriptor angewendet wird, mir erlauben würde, die read () -Funktion im nicht-blockierenden Modus zu verwenden?

Das Ausführen von stdin mit O_NONBLOCK hat Vorteile gegenüber dem Auswählen. Select sagt, dass einige Daten vorhanden sind, aber nicht wie viel. Es gibt Zeiten, in denen Sie alle verfügbaren Daten abrufen, aber nicht blockieren möchten, unabhängig davon, wie viel in der Warteschlange enthalten ist. Running Select für jeden Charakter scheint wie viel beschäftigt Arbeit ... O_NONBLOCK hat nicht für mich gearbeitet. Es ist eine interne Flagge, die in den meisten Treibern nicht sichtbar ist.

Sieh dir ioctl (..., FIONBIO) an. Es scheint den Job erledigt zu haben.

    
fbp 05.07.2012 12:30
quelle
1

Ich bin mir nicht sicher, ob Sie O_NONBLOCK auf stdin setzen können, aber select() oder poll() wird den Job definitiv erledigen.

    
Michael Foukarakis 20.10.2009 12:43
quelle
0

Was stimmt nicht mit feof(stdin) ?

    
eduffy 20.10.2009 12:34
quelle
0

Ja, Sie können select (mit einem Zeitlimit von Null) verwenden. Sie müssen den Dateideskriptor jedoch nicht blockierend einstellen - wenn select Ihnen sagt, dass der Dateideskriptor lesbar ist, dann wird ein read definitiv nicht blockieren.

Also poll file descriptor 0 gelegentlich mit select , und wenn es lesbar ist, read it. Wenn read 0 zurückgibt, bedeutet das, dass es geschlossen wurde.

    
caf 20.10.2009 12:48
quelle

Tags und Links