Scroll to navigation

write(2) System Calls Manual write(2)

NOM

write - Écrire dans un descripteur de fichier

BIBLIOTHÈQUE

Bibliothèque C standard (libc, -lc)

SYNOPSIS

#include <unistd.h>
ssize_t write(int fd, const void buf[.count], size_t count);

DESCRIPTION

write() écrit au maximum count octets dans le tampon démarrant à buf dans le fichier référencé par le descripteur de fichier fd.

Le nombre d'octets écrits peut être inférieur à count par exemple si la place disponible sur le média physique est insuffisante, ou si la limite de ressource RLIMIT_FSIZE est atteinte (consultez setrlimit(2)), ou l'appel est interrompu par un gestionnaire de signal après avoir écrit moins de count octets. (Consultez aussi pipe(7).)

Pour un fichier sur lequel lseek(2) est possible (par exemple un fichier ordinaire), l'écriture a lieu à la position pointée dans le fichier, et elle est déplacée du nombre d'octets effectivement écrits. Si le fichier était ouvert par open(2) avec O_APPEND, la position pointée est fixée d'abord à la fin du fichier avant l'écriture. La modification de la position et l'écriture sont effectuées de façon atomique.

POSIX réclame qu'une lecture avec read(2) effectuée de façon avérée après le retour d'une écriture avec write(), renvoie les nouvelles données. Notez que tous les systèmes de fichiers ne sont pas compatibles avec POSIX.

Selon POSIX.1, si count est supérieur à SSIZE_MAX, le résultat est défini par l'implémentation ; consultez NOTES pour la limite supérieure dans Linux.

VALEUR RENVOYÉE

En cas de succès, le nombre d'octets écrits est renvoyé. Si cet appel système échoue, il renvoie -1 et errno est défini pour indiquer l'erreur.

Il faut remarquer qu’un appel write() réussi peut transférer moins que count octets. Ces écritures partielles peuvent se produire pour diverses raisons, par exemple, à cause d’un espace insuffisant dans le périphérique disque pour écrire tous les octets demandés, ou à cause d’un write() bloqué pour un socket, un tube ou similaire, était interrompu par un gestionnaire de signal après un transfert partiel, mais avant le transfert de tout les octets demandés. Dans l’éventualité d’une écriture partielle, l’appelant peut faire un autre appel write() pour transférer les octets restants. Cet appel consécutif transfère les octets supplémentaires ou peut aboutir à une erreur (par exemple, le disque est désormais rempli).

Si count vaut zéro et si fd correspond à un fichier ordinaire, write() peut renvoyer un code d'erreur si l'une des erreurs ci-dessous est détectée. Si aucune erreur n'est détectée ou si la détection d'erreur n'est pas effectuée, 0 sera renvoyé sans autre effet. Si count vaut zéro et fd est un fichier autre qu'un fichier ordinaire, les résultats ne sont pas définis.

ERREURS

Le descripteur de fichier fd fait référence à un fichier autre qu'un socket et a été marqué comme non bloquant (O_NONBLOCK), et l'écriture devrait bloquer. Consultez open(2) pour plus de détails sur l'attribut O_NONBLOCK.
Le descripteur de fichier fd fait référence à un fichier autre qu'un socket et a été marqué comme non bloquant (O_NONBLOCK), et l'écriture devrait bloquer. POSIX.1-2001 permet de renvoyer l'une ou l'autre des erreurs dans ce cas et n'exige pas que ces constantes aient la même valeur. Une application portable devrait donc tester les deux possibilités.
fd n'est pas un descripteur de fichier valable, ou n'est pas ouvert en écriture.
fd fait référence à un socket de datagramme pour lequel l'adresse du correspondant n'a pas été initialisée avec connect(2).
Le quota de blocs de disque de l'utilisateur sur le système de fichiers contenant le fichier correspondant à fd a été atteint.
buf pointe en dehors de l'espace d'adressage accessible.
Tentative d'écriture d'une plage dépassant la taille maximale d'un fichier définie par l'implémentation ou la limite de taille de fichier du processus, ou bien sur une position au-delà de celle maximum autorisée.
L'appel système a été interrompu par un signal avant d'avoir pu écrire quoi que ce soit ; consultez signal(7).
fd correspond à un objet sur lequel il est impossible d'écrire, ou bien le fichier a été ouvert avec l'attribut O_DIRECT, et soit l'adresse définie dans buf, soit la valeur définie dans count, soit la position dans le fichier ne sont pas alignées correctement.
Une erreur d'E/S de bas niveau est survenue pendant la modification de l'inœud. Cette erreur peut être liée à l'écriture en retour de données écrites par un appel de write() antérieur qui peut être fournie pour un descripteur de fichier différent sur le même fichier. Depuis Linux 4.13, les erreurs à partir des écritures en retour arrivent avec l'annonce qu'elles peuvent être signalées par des requêtes ultérieures de write() et seront signalées par un appel de fsync ultérieur (qu'elles aient été ou non signalées par write()). Une autre cause de EIO sur des systèmes de fichiers en réseau se produit quand un verrouillage coopératif a été pris sur le descripteur de fichier et qu'il a été perdu. Consultez la section Verrouillages perdus de fcntl(2) pour plus de détails.
Le périphérique correspondant à fd n'a plus de place disponible.
La lecture a été interrompue par un signal ; consultez fnctl(2).
fd est connecté à un tube (pipe) ou un socket dont l'extrémité de lecture est fermée. Quand cela se produit, le processus écrivain reçoit un signal SIGPIPE. (Ainsi la valeur de retour de write n'est vue que si le programme intercepte, bloque ou ignore ce signal.)

D'autres erreurs peuvent se produire suivant le type d'objet associé à fd.

STANDARDS

SVr4, 4.3BSD, POSIX.1-2001.

Sous SVr4, un appel write() peut être interrompu, et renvoyer EINTR à n'importe quel moment, pas seulement avant l'écriture des données.

NOTES

Les types size_t et ssize_t sont respectivement les types de données entiers non signés et signés définis par POSIX.1.

Une réussite de write() n'offre aucune garantie que les données se trouvent sur le disque. Sur certains systèmes de fichiers, y compris NFS, elle ne garantit même pas que l'espace suffisant a été réservé pour les données. Dans certains cas, certaines erreurs pourraient être différées à une prochaine invocation de write(), de fsync(2) ou même de close(2). La seule manière d'être sûr de la réussite est d'invoquer fsync(2) après avoir écrit les données.

Si un write() est interrompu par un gestionnaire de signaux avant d'avoir écrit quoi que ce soit, l'appel échoue avec EINTR ; s'il est interrompu après avoir écrit au moins un octet, l'appel réussit et renvoie le nombre d'octets écrits.

Dans Linux, write() et les appels systèmes analogues transfèrent au maximum 0x7ffff000 (2 147 479 552) octets, renvoyant le nombre d'octets réellement transférés. (Cela est vrai aussi bien sur les systèmes 32 bits que sur les systèmes 64 bits.)

Le renvoi d'une valeur d'erreur pendant l'exécution de write() utilisant les E/S directes ne signifie pas que la totalité de l'écriture a échoué. Des données partielles ont pu être écrites et les données à la position pointée dans le fichier où l'appel write() était tenté devraient être considérées comme incohérentes.

BOGUES

Selon POSIX.1-2008/SUSv4, Section XSI 2.9.7 ("Thread Interactions with Regular File Operations") :

Toutes les fonctions suivantes doivent être atomiques et ne pas se perturber mutuellement pour ce qui concerne les effets spécifiés dans POSIX.1-2008 lorsqu'elles opèrent sur les fichiers réguliers ou sur les liens symboliques : ...

write() et writev(2) figurent parmi les API listées par la suite. En outre, la mise à jour du décalage de fichier fait partie des effets qui doivent être atomiques pour les threads (et pour les processus). Cependant, avant Linux 3.14, cela n'était pas le cas : si deux processus partageant un même descripteur de fichier (consultez open(2)) effectuaient une action write() (ou writev(2)) simultanément, alors les opération E/S n'étaient pas atomiques pour ce qui concernait la mise à jour du décalage de fichier. En conséquence, les écritures effectuées par les deux processus pouvaient se chevaucher au niveau des blocs de données (de façon incorrecte). Ce problème a été résolu dans Linux 3.14.

VOIR AUSSI

close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)

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@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>

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@lists.debian.org.

4 décembre 2022 Pages du manuel de Linux 6.02