write(2) | System Calls Manual | write(2) |
write - Écrire dans un descripteur de fichier
Bibliothèque C standard (libc, -lc)
#include <unistd.h>
ssize_t write(int fd, const void buf[.count], size_t count);
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.
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.
D'autres erreurs peuvent se produire suivant le type d'objet associé à fd.
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.
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.
Selon POSIX.1-2008/SUSv4, Section XSI 2.9.7 ("Thread Interactions with Regular File Operations") :
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.
close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)
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.03 |