Scroll to navigation

CLOSE(2) Linux Programmeurs Handleiding CLOSE(2)

NAAM

close - sluit een bestandsindicator

SAMENVATTING

#include <unistd.h>
int close(int bi);

BESCHRIJVING

close() sluit een bestandsindicator, zodat deze niet langer naar een bestand wijst en hergebruikt kan worden. Eventuele record sloten op het bestand (zie fcntl(2)) die het eigendom waren van het proces worden verwijderd (onafhankelijk van de bestandsindicator die gebruikt werd om het slot te verkrijgen).

Als bi de laatste dubbelganger van een bepaalde bestandsindicator is, worden de systeem-middelen die erbij horen vrijgemaakt; als de bestandsindicator de laatste verwijzing was naar een bestand dat verwijderd werd met unlink(2) dan wordt het bestand verwijderd.

EIND WAARDE

Bij succes geeft close() nul terug. Bij falen wordt -1 teruggegeven en wordt errno overeenkomstig gezet.

FOUTEN

EBADF
bi is geen geldige open bestandsindicator.
EINTR
De close() aanroep werd onderbroken door een signaal; zie signal(7).
EIO
Een Invoer/Uitvoer fout trad op.
ENOSPC, EDQUOT
Op NFS worden deze fouten normaliter gerapporteerd tegen de eerste schrijf actie die de beschikbare opslag ruimte overschrijdt, maar in plaats daarvan tegen een volgende write(2), fsync(2), of close().

Zie OPMERKINGEN voor een discussie over waarom close() niet opnieuw geprobeerd moet worden na een fout.

VOLDOET AAN

POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

OPMERKINGEN

Een succesvolle close() garandeert niet dat de gegevens succesvol zijn bewaard op de schijf doordat de kernel het schrijven ervan achterhoudt. Het is niet normaal voor een bestandssysteem om de buffers door te spoelen als het bestand wordt gesloten. Als u zeker moet zijn dat de gegevens fysiek bewaard zijn, gebruik dan fsync(2). (Het hangt nu verder van de schijf hardware af.)

De sluit-bij-uitvoeren bestandsindicator vlag kan worden gebruikt om er voor zorg te dragen dat een bestandsindicator automatisch wordt gesloten bij een succesvolle execve(2); zie fcntl(2) voor details.

Multithreaded processen en close()

Het is hoogstwaarschijnlijk niet slim om bestandsindicatoren te sluiten terwijl ze in gebruik kunnen zijn door systeem aanroepen in andere threads in hetzelfde proces. Omdat een bestandsindicator kan worden hergebruikt, zijn er obscure looptijd condities die tot onbedoelde neven effecten kunnen leiden.

Bovendien, overweeg het volgende scenario waar twee threads dezelfde operaties op dezelfde bestandsindicator uitvoeren:

1.
Een thread wordt geblokkeerd door een Invoer/Uitvoer systeem aanroep op de bestandsindicator. Bijvoorbeeld, hij probeert te write(2) naar een pijp die al vol is, of probeert te read(2) van een stream socket die op dit moment geen gegevens beschikbaar heeft.
2.
Een andere thread sluit de bestandsindicator.

Het gedrag in deze situatie varieert over systemen. Op sommige systemen, zal de blokkerende systeem aanroep onmiddellijk met een fout beëindigen zodra de bestandsindicator is gesloten

Op Linux (en mogelijk enkele andere systemen), is het gedrag anders: de blokkerende Invoer/Uitvoer systeem aanroep houdt een referentie naar de onderliggende bestandsindicator open, en deze referentie houdt de indicator open totdat de Invoer/Uitvoer systeem aanroep eindigt. (Zie open(2) voor een discussie over open bestandsindicatoren.) Dus kan de blokkerende systeem aanroep in de eerste thread succesvol eindigen na de close() in de tweede thread.

Omgaan met fout meldingen van close()

Een zorgvuldige programmeur controleert de uitvoer waarde van close(), omdat het mogelijk is dat fouten van een vorige write(2) operatie alleen worden gerapporteerd bij de finale close() die de open bestandsindicator vrij geeft. Het niet controleren van de uitvoer waarde bij het sluiten van een bestand kan leiden tot zwijgend verlies van gegevens. Dit kan speciaal optreden met NFS en met schijf quota.

Merk op, dat een fout uitvoer alleen gebruikt mag worden voor diagnose (m.a.w. een waarschuwing aan de applicatie dat er nog een Invoer/Uitvoer bezig kan zijn of dat er gefaalde Invoer/Uitvoer kan zijn) of gebruikt voor reparaties (b.v. het opnieuw schrijven van een bestand of het maken van een backup).

Opnieuw close() proberen na terug melding van een fout is verkeerd om te doen, omdat dat er voor kan zorgen dat een hergebruikte bestandsindicator van een andere thread kan worden gesloten. Dit kan optreden doordat de Linux kernel de bestandsindicator altijd vroeg tijdens de close operatie los laat, daarbij hem voor hergebruik beschikbaar maakt; de stappen die een fout kunnen geven, zoals doorspoelen van data naar het bestandssysteem of apparaat, treden alleen later tijdens de close operatie op.

Veel andere implementatie sluiten de bestandsindicator ook op deze manier (behalve in het geval van EBADF, aangezien dit betekent dat de bestandsindicator ongeldig was) zelfs als deze een vervolgens een fout rapporteren bij terugkeer van close(). POSIX.1 is momenteel stil op dit punt, maar er bestaan plannen om dit gedrag te eisen in een volgende belangrijke uitgave van de standaard.

Een zorgvuldige programmeur die Invoer/Uitvoer fouten wil weten mag de aanroep van close() vooraf laten gaan met een aanroep van fsync(2).

De EINTR fout is een speciaal geval. Betreffende de EINTR fout, zegt POSIX.1-2008:

Als close() werd onderbroken door een signaal dat ontvangen moet worden, dan moet het -1 teruggeven met errno gezet op EINTR en de status van fildes is niet gespecificeerd.

Dit staat het gedrag toe dat optreedt in Linux en veel andere implementaties waar, zoals bij andere fouten die kunnen worden gerapporteerd door close(), de bestandsindicator gegarandeerd wordt gesloten. Hoewel het ook een andere mogelijkheid opent: dat de implementatie een EINTR fout terug geeft en de bestandsindicator open houdt. (Volgens de documentatie doet de HP-UX close() implementatie dit.) De aanroeper dient nog een keer close() gebruiken om de bestandsindicator te sluiten, om lekken van bestandsindicatoren te voorkomen. Deze verschillen in implementatie gedrag betekenen een moeilijkheid voor overdraagbare applicaties, omdat in veel implementaties close() niet nogmaals hoeft te worden aangeroepen na een EINTR fout, en op zijn minst op een moet close() nog een keer aangeroepen worden. Er bestaan plannen om dit raadsel aan te pakken in een volgende belangrijke uitgave van de POSIX.1 standaard.

ZIE OOK

fcntl(2), fsync(2), open(2), shutdown(2), unlink(2), fclose(3)

COLOFON

Deze pagina is onderdeel van release 5.10 van het Linux man-pages-project. Een beschrijving van het project, informatie over het melden van bugs en de nieuwste versie van deze pagina zijn op https://www.kernel.org/doc/man-pages/ te vinden.

VERTALING

De Nederlandse vertaling van deze handleiding is geschreven door Jos Boersema <joshb@xs4all.nl>, Mario Blättermann <mario.blaettermann@gmail.com> en Luc Castermans <luc.castermans@gmail.com>

Deze vertaling is vrije documentatie; lees de GNU General Public License Version 3 of later over de Copyright-voorwaarden. Er is geen AANSPRAKELIJKHEID.

Indien U fouten in de vertaling van deze handleiding zou vinden, stuur een e-mail naar debian-l10n-dutch@lists.debian.org.

9 juni 2020 Linux