NOM
close - Fermer un descripteur de fichier
SYNOPSIS
#include <unistd.h>
int close(int fd);
DESCRIPTION
close() ferme le descripteur fd, de manière à ce qu’il ne référence plus aucun fichier, et puisse être réutilisé. Tous les verrouillages (consultez fcntl(2)) sur le fichier qui lui était associé, appartenant au processus, sont supprimés (quel que soit le descripteur qui fut utilisé pour obtenir le verrouillage).
Si fd est le dernier descripteur de fichier qui se réfère à une description de fichier ouvert sous-jacente (consultez open(2)), les ressources associées à la description de fichier ouvert sont libérées. Si le descripteur était la dernière référence sur un fichier supprimé avec unlink(2), le fichier est effectivement effacé.
VALEUR RENVOYÉE
Si elle réussit, la fonction close() renvoie zéro. En cas d’erreur, elle renvoie -1 et remplit errno avec le code d’erreur.
ERREURS
EBADF |
Le descripteur de fichier fd est invalide. | ||
EINTR |
L’appel système close() a été interrompu par un signal ; consultez signal(7). | ||
EIO |
Une erreur d’entrée-sortie s’est produite. |
ENOSPC, EDQUOT
Sur NFS, ces erreurs ne sont en principe pas signalées lors de la première écriture qui dépasse l’espace de stockage disponible, mais lors d’un write(2), fsync(2) ou close() consécutif.
Voir les NOTES pour un point sur la raison pour laquelle close() ne devrait pas réessayer après une erreur.
CONFORMITÉ
POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.
NOTES
Une fermeture sans erreur ne garantit pas que les données ont été vraiment écrites sur le disque, car le noyau repousse les écritures le plus tard possible. Il n’est pas fréquent qu’un système de fichiers vide les tampons dès la fermeture d’un flux. Si vous désirez vous assurer que les informations sont en sûreté sur le disque, utilisez fsync(2) (mais des considérations matérielles entrent en jeu à ce moment).
L’attribut de descripteur de fichier close-on-exec peut être utilisé pour s’assurer qu’un descripteur de fichier est fermé automatiquement en cas de succès de execve(2) ; voir fcntl(2) pour des détails.
Multithreaded
processes and close()
Il est probablement imprudent de fermer des descripteurs de
fichier alors qu’ils peuvent peut-être
être utilisés par des appels système
dans d’autres threads du même processus.
Puisqu’un descripteur de fichier peut être
réutilisé, il y a des conditions de
concurrence obscures qui peuvent provoquer des effets de
bord non désirés.
Furthermore, consider the following scenario where two threads are performing operations on the same file descriptor:
1. |
One thread is blocked in an I/O system call on the file descriptor. For example, it is trying to write(2) to a pipe that is already full, or trying to read(2) from a stream socket which currently has no available data. | ||
2. |
Another thread closes the file descriptor. |
The behavior in this situation varies across systems. On some systems, when the file descriptor is closed, the blocking system call returns immediately with an error.
On Linux (and possibly some other systems), the behavior is different. the blocking I/O system call holds a reference to the underlying open file description, and this reference keeps the description open until the I/O system call completes. (See open(2) for a discussion of open file descriptions.) Thus, the blocking system call in the first thread may successfully complete after the close() in the second thread.
Gérer
les erreurs renvoyées par close()
Un programmeur prudent vérifiera le code de retour de
close(), car il est possible qu’une erreur
correspondant à un appel write(2)
antérieur ne soit rapportée que lors du
close() final. Ne pas vérifier le code de
retour lorsqu’un fichier est fermé peut
conduire à une perte silencieuse de
données. Cela est principalement vrai dans le cas de
systèmes de fichiers NFS, ou avec l’utilisation
des quotas de disques.
Remarquez cependant que la valeur de retour ne devrait être utilisée que pour les diagnostics (à savoir pour prévenir une application qu’il peut rester des E/S en attente ou échouées) ou de correction (comme pour écrire un fichier une ou plusieurs fois ou pour créer une sauvegarde).
Réessayer close() après un renvoi d’échec n’est pas la bonne manière de faire, car il peut en résulter que le descripteur d’un fichier qui serait réutilisé à partir d’un autre thread se ferme. Cela est possible car le noyau Linux abandonne toujours tôt le descripteur de fichier lors d’une opération de fermeture, ce qui le libère pour être réutilisé ; les étapes de renvoi d’erreur telles que l’effacement des données sur le système de fichiers ou le périphérique arrivent plus tard dans l’opération de fermeture.
De même, beaucoup d’autres implémentations ferment toujours le descripteur de fichier (sauf en cas de EBADF, qui signifie que le descripteur de fichier n’était pas valable), même si elles signalent ensuite une erreur renvoyée par close(). POSIX.1 ne dit rien aujourd’hui sur ce point mais ce comportement sera rendu obligatoire dans la prochaine version majeure du standard.
Un programmeur prudent qui veut savoir les erreurs E/S doit faire précéder close() d’un appel fsync(2).
The EINTR error is a somewhat special case. Regarding the EINTR error, POSIX.1-2008 says:
Si close() est interrompu par un signal qui doit être récupéré, il renverra -1 et positionnera errno sur EINTR et l’état de fildes ne sera pas spécifié.
Cela autorise un comportement qui arrive sur Linux et beaucoup d’autres implémentations, où, comme pour beaucoup d’erreurs pouvant être signalées par close(), le descripteur de fichier se fermera assurément. Néanmoins, cela permet aussi une autre possibilité : l’implémentation renvoie une erreur EINTR et laisse le descripteur de fichier ouvert (selon sa documentation, le close() de HP-UX fait cela). L’appelant doit donc utiliser une fois de plus close() pour fermer le descripteur de fichier, afin d’éviter des fuites du descripteur de fichier. Cette divergence de comportements dans l’implémentation apporte un obstacle difficile à la portabilité des applications car sur beaucoup d’implémentations, close() ne doit pas être rappelé après une erreur EINTR, tandis que sur au moins une d’elles, close() doit être rappelé. Il est envisagé de s’occuper de ce casse-tête dans la prochaine version majeure du standard POSIX.1.
VOIR AUSSI
fcntl(2), fsync(2), open(2), shutdown(2), unlink(2), fclose(3)
COLOPHON
Cette page fait partie de la publication 5.07 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page, peuvent être trouvées à l’adresse https://www.kernel.org/doc/man-pages/.
TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin [AT] laposte.net>, Thierry Vignaud <tvignaud [AT] mandriva.com>, François Micaux, Alain Portal <aportal [AT] univ-montp2.fr>, Jean-Philippe Guérard <fevrier [AT] tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon [AT] wanadoo.fr>, Julien Cristau <jcristau [AT] debian.org>, Thomas Huriaux <thomas.huriaux [AT] gmail.com>, Nicolas François <nicolas.francois [AT] centraliens.net>, Florentin Duneau <fduneau [AT] gmail.com>, Simon Paillard <simon.paillard [AT] resel.fr>, Denis Barbier <barbier [AT] debian.org>, David Prévot <david [AT] tilapin.org> et Jean-Philippe MENGUAL <jpmengual [AT] debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n’y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à <debian-l10n-french [AT] lists.org>.