2008-11-13 9 views
5

Es scheint, als ob die folgenden Aufrufe tun, was Sie erwarten würden (Schließen Sie den Stream und keine weitere Eingabe zulassen - alles, was auf Eingabe auf dem Stream wartet Fehler zurück), aber ist es garantiert korrekt über alle Compiler/Plattformen?Ist close/fclose auf stdin garantiert korrekt?

close(fileno(stdin)); 
fclose(stdin); 
+1

können Sie einfach schließen (Stdin), wird es close() auf der Datei behandeln. –

Antwort

3

Nichts ist garantiert korrekt über jedes mögliche Betriebssystem. Der Aufruf von fclose (stdin) funktioniert jedoch auf allen POSIX-kompatiblen Betriebssystemen sowie auf Windows-Betriebssystemen. Sie sollten also praktisch alles, was derzeit verwendet wird, verwenden.

Wie von der vorherigen Antwort sowie mein Kommentar angegeben, gibt es keine Notwendigkeit, auf das Dateihandle zu schließen. fclose() schließt alles richtig für dich ab.

14

Schließen Sie nicht auf Fileno (FILE *). FILE ist ein Pufferobjekt. Wenn man sich seine Implementierung ansieht und sich in seinen Zustand einmischt, trägt dies alle Vorbehalte und Gefahren mit sich, die bei einem ähnlichen Fehlverhalten auf einem anderen Softwaremodul auftreten würden.

Tun Sie es nicht.

AGH. Ernst. Böse.

+5

In der Tat, die close() vor der fclose() wird garantiert, dass fclose() fehlschlagen, wenn irgendwelche ausstehenden Daten zu flush sind. (In einem allgemeineren Fall, wo der andere Code zwischen dem close() und fclose() sein könnte, könnte fclose() einfach in die falsche Datei schreiben!) –

+0

Dies ... beantwortet die Frage technisch nicht . –

+0

Das tut: Das Verhalten des OP-Codes wäre undefiniert. Es ist unwahrscheinlich, dass seine Implementierung von fclose erkennen würde, dass die fd geschlossen wurde. Wenn er zwischen den Aufrufen zum Schließen und Schließen noch andere Dinge vor sich hat, dann gibt es eine andere unangenehme Möglichkeit: Nachdem er gerade einen Dateideskriptor geschlossen hat, ist der nächste Aufruf von open() in der Praxis wahrscheinlich, diesen Dateideskriptor wiederzuverwenden. Was würde passieren, wenn Sie den zugrundeliegenden Deskriptor kurz aufrufen, einen anderen Deskriptor mit demselben Index öffnen, der dann fclose heißt? Das letzte open() wäre zumindest schlecht. – Sniggerfardimungus

17

fclose(stdin) verursacht jede weitere Verwendung von stdin (implizit oder explizit) undefinierten Verhalten aufzurufen, die ein sehr schlechte Sache ist. Es "blockiert die Eingabe nicht".

close(fileno(stdin)) bewirkt, dass alle weiteren Versuche, am Eingang von stdin, nachdem der aktuelle Puffer aufgebraucht ist, mit EBADF zum Scheitern verurteilt, aber nur, bis Sie eine andere Datei zu öffnen, wobei in diesem Fall die Datei fd geworden # 0 und schlechte Dinge passieren.

int fd = open("/dev/null", O_WRONLY); 
dup2(fd, 0); 
close(fd); 

mit ein paar zusätzlichen Fehlerprüfungen:

könnte ein robuster Ansatz. Dadurch wird sichergestellt, dass alle Lesevorgänge (nachdem der aktuelle Puffer leer ist) zu Fehlern führen. Wenn Sie nur möchten, dass sie zu EOF führen, kein Fehler, verwenden Sie O_RDONLY anstelle von O_WRONLY.