close(2) System Calls Manual close(2) BEZEICHNUNG close - Dateideskriptor schliessen BIBLIOTHEK Standard-C-Bibliothek (libc, -lc) UBERSICHT #include int close(int dd); BESCHREIBUNG close() schliesst einen Dateideskriptor, so dass dieser nicht mehr zu einer Datei gehort und wieder verwendet werden kann. Alle zum Prozess gehorenden Datensatz-Sperren (siehe fcntl(2)) der mit dem Deskriptor verbundenen Datei werden aufgehoben. Die Aufhebung der Sperren erfolgt unabhangig von dem Deskriptor, mit dem die Sperre eingerichtet wurde. Dies hat einige ungluckliche Konsequenzen und Sie sollten besonders vorsichtig beim Einsatz von empfohlenen Datensatzsperren sein. In fcntl(2) werden die Risiken und Konsequenzen diskutiert sowie die (wahrscheinlich zu bevorzugenden) Deskriptorensperren fur offene Dateien. Wenn dd der letzte Deskriptor der zugehorigen offenen Datei ist (siehe open(2)), werden die zugehorigen Ressourcen freigegeben. War der Datei-Deskriptor der letzte Verweis auf eine Datei, die mittels unlink(2) entfernt wurde, wird die Datei geloscht. RUCKGABEWERT Nach erfolgreicher Ausfuhrung gibt close() 0 zuruck. Bei Fehlern wird -1 zuruckgegeben und errno gesetzt, um den Fehler anzuzeigen. FEHLER EBADF dd ist kein gultiger Deskriptor fur eine geoffnete Datei. EINTR Der Aufruf von close() wurde von einem Signal unterbrochen (siehe signal(7)). EIO Es ist ein E/A-Fehler (engl. I/O) aufgetreten. ENOSPC EDQUOT Auf NFS werden diese Fehler normalerweise nicht beim ersten Schreibversuch, der den verfugbaren Speicherplatz uberschreitet, berichtet, sondern stattdessen an nachfolgende write(2), fsync(2) oder close(2). Siehe ANMERKUNGEN fur eine Diskussion, warum close() nach einem Fehler nicht erneut versucht werden sollte. STANDARDS POSIX.1-2008. GESCHICHTE POSIX.1-2001, SVr4, 4.3BSD. ANMERKUNGEN Ein erfolgreiches >>close<< garantiert nicht, dass die Daten erfolgreich auf der Festplatte gespeichert wurden, weil der Kernel den Pufferzwischenspeicher verwendet, um verzogert zu schreiben. Typischerweise leeren Dateisysteme ihre Puffer beim Schliessen einer Datei nicht. Wenn Sie sicher sein mussen, dass die Daten physisch auf der darunterliegenen Platte gespeichert sind, verwenden Sie fsync(2). (Hierbei kommt es auf die Hardware Ihrer Festplatte an.) Der Dateideskriptor close-on-exec kann dazu verwandt werden, sicherzustellen, dass ein Dateideskriptor automatisch bei einem erfolgreichen execve(2) geschlossen wird; siehe fcntl(2) fur Details. Multithreaded-Prozesse und close() Wahrscheinlich ist es unklug, Dateideskriptoren zu schliessen, die moglicherweise noch durch Systemaufrufe in anderen Threads desselben Prozesses belegt sein konnen. Da Dateideskriptoren wiederverwendet werden konnen, kann dies zu undurchsichtigen >>Race Conditions<< mit unbeabsichtigten Nebenwirkungen fuhren. Betrachten Sie des Weiteren folgendes Szenario, bei dem zwei Threads Aktionen auf den gleichen Dateideskriptor ausfuhren: (1) Ein Thread blockiert auf einem E/A-Systemaufruf auf dem Dateideskriptor. Beispielsweise versucht er in eine Pipe zu schreiben (write(2)), die bereits voll ist, oder versucht aus einem Datenstrom-Socket zu lesen (read(2)), der derzeit uber keine Daten verfugt. (2) Ein anderer Thread schliesst den Dateideskriptor. Das Verhalten in dieser Situation unterscheidet sich zwischen Systemen. Auf einigen Systemen kehrt der blockierte Systemaufruf sofort mit einem Fehler zuruck, wenn der Dateideskriptor geschlossen wird. Unter Linux (und moglicherweise einigen anderen Systemen) ist das Verhalten anders: Der blockierende E/A-Systemaufruf halt eine Referenz auf die zugrundeliegende offene Dateideskription und diese Referenz halt die Deskription offen, bis der E/A-Systemaufruf abschliesst. (Siehe open(2) fur eine Diskussion von offenen Dateideskriptionen). Daher kann sich der blockierende Systemaufruf in dem ersten Thread nach einem close() in dem zweiten Thread erfolgreich beenden. Umgang mit von close() zuruckgelieferten Fehlern Ein sorgfaltiger Programmierer pruft den Ruckgabewert von close(), da es durchaus moglich ist, dass Fehler bei einer fruheren write(2)-Operation erst bei dem abschliessenden close()-Zugriff, bei dem die offenen Dateideskriptoren freigegeben werden, gemeldet werden. Wird der Ruckgabewert beim Schliessen einer Datei nicht gepruft, kann dies zu unbemerktem Datenverlust fuhren. Dies kann vor allem mit NFS und Plattenkontingenten beobachtet werden. Beachten Sie allerdings, dass ein zuruckgelieferter Fehler nur fur diagnostische Zwecke (d.h. einer Warnung an die Anwendung, dass E/A noch in Verarbeitung ist, oder dass es fehlgeschlagene E/A gegeben haben konnte) oder fur abhelfende Zwecke (z.B. dem erneuten Schreiben der Datei oder dem Erstellen einer Sicherungskopie) verwandt werden sollte. Es ist falsch, nach einer Ruckgabe eines Fehlers close() erneut zu versuchen, da es dazu fuhren konnte, dass ein wiederverwandter Dateideskriptor von einem anderen Thread geschlossen werden konnte. Dies kann auftreten, da der Linux-Kernel Dateideskriptoren immer fruh in der Close-Aktion fur die Wiederbenutzung freigibt und die Schritte, die einen Fehler liefern konnen, wie das Rausschreiben von Daten zu dem Dateisystem oder Gerat, erst spater in der Close-Aktion vorkommen. Viele andere Implementierunngen schliessen den Dateideskriptor ahnlich (ausser im Falle von EBADF, der bedeutet, dass der Dateideskriptor ungultig war), selbst falls sie im folgenden einen Fehler bei der Ruckkehr von close() berichten. POSIX.1 sagt derzeit zu diesem Punkt nichts aus, aber es gibt Uberlegungen, dieses Verhalten in der nachsten grossen Veroffentlichung dieses Standards zu verpflichten. Ein sorgfaltiger Programmierer, der uber E/A-Fehler Bescheid wissen mochte, kann close() einen Aufruf von fsync(2) vorschalten. Der Fehler EINTR ist etwas speziell. Bezuglich des Fehlers EINTR sagt POSIX.1-2008: Falls close() von einem Signal unterbrochen wird, das gefangen werden soll, muss es -1 zuruckliefern, wobei errno auf EINTR gesetzt werden soll und der Zustand von fildes nicht festgelegt ist. Dies erlaubt das Verhalten, das auf Linux und vielen anderen Implementierungen auftritt, bei dem, wie auch bei anderen von close() berichteten Fehlern, garantiert wird, dass der Dateideskriptor geschlossen ist. Es erlaubt allerdings auch eine andere Moglichkeit: dass die Implementierung einen Fehler EINTR zuruckliefert und den Dateideskriptor offen halt. (Laut seiner Beschreibung ist dies fur close() unter HP-UX der Fall.) Der Aufrufende muss dann erneut close() verwenden, um den Dateideskriptor zu schliessen und Lecks bei Dateideskriptoren zu vermeiden. Diese Divergenz in Implementierungsverhalten stellt eine schwierige Hurde fur portable Anwendungen dar, da unter vielen Implementierungen close() nicht nach einem Fehler EINTR erneut aufgerufen werden darf, und bei mindestens einer close() erneut aufgerufen werden muss. Es gibt Uberlegungen, dieses Puzzle fur die nachste Hauptveroffentlichung des Standards POSIX.1 zu losen. SIEHE AUCH close_range(2), fcntl(2), fsync(2), open(2), shutdown(2), unlink(2), fclose(3) UBERSETZUNG Die deutsche Ubersetzung dieser Handbuchseite wurde von Ralf Demmer , Martin Eberhard Schauer , Mario Blattermann und Helge Kreutzmann erstellt. Diese Ubersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezuglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG ubernommen. Wenn Sie Fehler in der Ubersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an die Mailingliste der Ubersetzer . Linux man-pages 6.06 31. Oktober 2023 close(2)