WRITE |
Écrire |
---|---|
C pour Unix | unistd.h |
Syntaxe
ssize_t write(int fildes, const void *buf, size_t nbyte); |
Paramètres
Nom | Description |
---|---|
fildes | Ce paramètre permet d'indiquer le descripteur de fichier où les données doivent être écrites. Il peut correspondre à un fichier ouvert (open), un tube (pipe), un socket (socket), ou encore une sortie standard (STDOUT_FILENO, STDERR_FILENO). |
buf | Ce paramètre permet d'indiquer un pointeur vers un tampon contenant les données à écrire. Les nbyte premiers octets du tampon seront écrits. |
nbyte | Ce paramètre permet d'indiquer le nombre d'octets à écrire à partir du tampon buf. write essaie d'écrire exactement nbyte octets, mais il est possible que moins d'octets soient écrits (en raison d'une interruption système ou d'un espace insuffisant dans le fichier ou le tampon du périphérique). La valeur de retour permet de vérifier combien d'octets ont effectivement été écrits. |
Retour
En cas de réussite, ces fonctions renvoient le nombre d'octets réellement écrits dans le fichier associé à fildes. Ce nombre ne doit jamais être supérieur à nbyte. Sinon, la valeur -1 est renvoyée et errno est défini pour indiquer l'erreur.
Description
Cette fonction permet d'effectuer des écritures dans un fichier précédemment ouvert.
Remarques
- La fonction write() doit tenter d'écrire nbyte octets depuis le tampon pointé par buf vers le fichier associé au descripteur de fichier ouvert, fildes.
- Avant toute action décrite ci-dessous, et si nbyte vaut zéro et que le fichier est un fichier standard, la fonction write() peut détecter et renvoyer des erreurs comme décrit ci-dessous. En l'absence d'erreur, ou si la détection d'erreur n'est pas effectuée, la fonction write() doit renvoyer zéro et ne pas produire d'autres résultats. Si nbyte vaut zéro et que le fichier n'est pas un fichier standard, les résultats sont non spécifiés.
- Sur un fichier standard ou tout autre fichier capable de recherche, l'écriture des données doit se dérouler à partir de la position dans le fichier indiquée par le déplacement associé à fildes. Avant un retour réussi de write(), le déplacement du fichier doit être incrémenté du nombre d'octets réellement écrits. Sur un fichier standard, si la position du dernier octet écrit est supérieure ou égale à la longueur du fichier, celle-ci doit être fixée à cette position plus un.
- Sur un fichier non capable de recherche, l'écriture doit toujours commencer à la position actuelle. La valeur d'un déplacement de fichier associé à un tel périphérique est indéfinie.
- Si l'indicateur O_APPEND des indicateurs d'état du fichier est activé, le décalage du fichier doit être défini à la fin du fichier avant chaque écriture et aucune modification de fichier ne doit avoir lieu entre la modification du déplacement du fichier et l'écriture.
- Si une fonction write() demande l'écriture d'un nombre d'octets supérieur à la capacité disponible (par exemple, la taille limite du fichier du processus ou la fin physique d'un support), seul le nombre d'octets disponible doit être écrit. Par exemple, supposons qu'il y ait de la place pour 20 octets supplémentaires dans un fichier avant d'atteindre une limite. Une écriture de 512 octets renverra 20 octets. L'écriture suivante d'un nombre d'octets non nul renverra un échec (sauf indication contraire ci-dessous).
- Si la requête entraîne un dépassement de la taille du fichier par le processus et qu'il n'y a plus de place pour l'écriture d'octets, la requête échoue et l'implémentation génère le signal SIGXFSZ pour le processus léger.
- Si write() est interrompu par un signal avant l'écriture de données, elle renvoie -1 avec errno défini sur EINTR.
- Si write() est interrompu par un signal après l'écriture de données, elle renvoie le nombre d'octets écrits.
- Si la valeur de nbyte est supérieure à {SSIZE_MAX}, le résultat est défini par l'implémentation.
- Après le retour réussi d'une écriture dans un fichier standard :
- Toute écriture réussie à partir de chaque position d'octet du fichier modifiée par cette écriture renvoie les données spécifiées par write() pour cette position jusqu'à ce que ces positions soient à nouveau modifiées.
- Toute écriture réussie ultérieure à la même position d'octet du fichier écrase les données de ce fichier.
- Les requêtes d'écriture vers un tube ou une FIFO doivent être traitées de la même manière qu'un fichier standard, à l'exception des points suivants :
- Aucun déplacement de fichier n'est associé à un tube ; chaque requête d'écriture doit donc être ajoutée à la fin du tube.
- Les requêtes d'écriture de {PIPE_BUF} octets ou moins ne doivent pas être entrelacées avec les données d'autres processus effectuant des écritures sur le même tube. Les écritures supérieures à {PIPE_BUF} octets peuvent avoir des données entrelacées, selon des limites arbitraires, avec celles d'autres processus, que l'indicateur O_NONBLOCK des indicateurs d'état du fichier soit activé ou non.
- Si l'indicateur O_NONBLOCK est désactivé, une requête d'écriture peut bloquer le processus léger, mais, en cas d'exécution normale, elle doit renvoyer noctet.
- Si l'indicateur O_NONBLOCK est activé, les requêtes write() doivent être traitées différemment, comme suit :
- La fonction write() ne doit pas bloquer le processus léger.
- Une requête d'écriture de {PIPE_BUF} octets ou moins aura l'effet suivant : si l'espace disponible dans le tube est suffisant, write() transférera toutes les données et renverra le nombre d'octets demandés. Sinon, write() ne transférera aucune donnée et renverra -1 avec un numéro d'erreur défini sur EAGAIN.
- Une requête d'écriture de plus de {PIPE_BUF} octets entraînera l'un des événements suivants :
- Si au moins un octet peut être écrit, transférer ce qui est possible et renvoyer le nombre d'octets écrits. Si toutes les données précédemment écrites dans le tube sont lues, la requête transférera au moins {PIPE_BUF} octets.
- Si aucune donnée ne peut être écrite, ne transférer aucune donnée et renvoyer -1 avec un numéro d'erreur défini sur EAGAIN.
- Lors d'une tentative d'écriture dans un descripteur de fichier (autre qu'un tube ou une FIFO) prenant en charge les écritures non bloquantes et ne pouvant pas accepter les données immédiatement :
- Si l'indicateur O_NONBLOCK est désactivé, write() bloque le processus léger appelant jusqu'à ce que les données soient acceptées.
- Si l'indicateur O_NONBLOCK est activé, write() ne bloque pas le processus léger. Si des données peuvent être écrites sans bloquer le processus léger, write() écrit ce qu'il peut et renvoie le nombre d'octets écrits. Sinon, il renvoie -1 et définit errno sur EAGAIN.
- En cas de réussite, lorsque nbyte est supérieur à 0, write() marquera pour mise à jour les horodatages de la dernière modification des données et du dernier changement d'état du fichier. S'il s'agit d'un fichier standard, les bits S_ISUID et S_ISGID du mode fichier peuvent être effacés.
- Pour les fichiers standard, aucun transfert de données ne doit avoir lieu au-delà du déplacement maximal défini dans la description du fichier ouvert associée à fildes.
- Si fildes fait référence à un socket, write() sera équivalent à send() sans indicateur défini.
- Si le bit O_DSYNC est défini, les opérations d'écriture d'entrée/sortie sur le descripteur de fichier se termineront conformément à la finalisation de l'intégrité des données des entrées/sorties synchronisées.
- Si le bit O_SYNC est défini, les opérations d'écriture d'entrées/sorties sur le descripteur de fichier se termineront conformément à la finalisation de l'intégrité des fichiers des entrées/sorties synchronisées.
- Si fildes fait référence à un objet de mémoire partagée, le résultat de la fonction write() n'est pas spécifié.
- Si fildes fait référence à un objet mémoire typé, le résultat de la fonction write() n'est pas spécifié.
- Si fildes fait référence à un STREAM, l'exécution de write() est déterminée par les valeurs minimale et maximale de l'intervalle nbyte (taille de paquet) acceptée par le STREAM. Ces valeurs sont déterminées par le module STREAM de niveau supérieur. Si nbyte est compris dans la plage de taille de paquet, nbyte octets sont écrits. Si nbyte est hors de cette plage et que la valeur de taille de paquet minimale est 0, write() divise le tampon en segments de taille de paquet maximale avant d'envoyer les données en aval (le dernier segment peut contenir une taille de paquet inférieure à la taille maximale). Si nbyte est hors de cette plage et que la valeur minimale est différente de zéro, write() échoue avec un errno défini sur ERANGE. L'écriture d'un tampon de longueur nulle (nbyte est 0) sur un périphérique STREAM envoie 0 octet avec 0 renvoyé. Cependant, l'écriture d'un tampon de longueur nulle dans un tube ou une FIFO basé sur STREAMS n'envoie aucun message et renvoie 0. Le processus peut exécuter l'ioctl() I_SWROPT pour activer l'envoi de messages de longueur nulle via le tube ou la FIFO.
- Lors de l'écriture dans un STREAM, les messages de données sont créés avec une bande de priorité de 0. Lors de l'écriture dans un STREAM qui n'est ni un tube ni une FIFO :
- Si O_NONBLOCK est à zéro et que le STREAM ne peut accepter de données (la file d'attente d'écriture du STREAM est pleine en raison de conditions de contrôle de flux interne), write() se bloque jusqu'à ce que les données soient acceptées.
- Si O_NONBLOCK est défini et que le STREAM ne peut accepter de données, write() renvoie -1 et définit errno sur EAGAIN.
- Si O_NONBLOCK est défini et qu'une partie du tampon a été écrite alors qu'une condition empêchant le STREAM d'accepter des données supplémentaires se produit, write() se termine et renvoie le nombre d'octets écrits.
- De plus, write() échouera si l'entête STREAM a traité une erreur désynchronise avant l'appel. Dans ce cas, la valeur de errno ne reflète pas le résultat de write(), mais l'erreur précédente.
- La fonction pwrite() est équivalente à write(), à la différence qu'elle écrit à une position donnée et ne modifie pas le déplacement du fichier (que O_APPEND soit défini ou non). Les trois premiers paramètres de pwrite() sont identiques à ceux de write(), avec en plus un quatrième paramètre, offset, pour la position souhaitée dans le fichier. Toute tentative d'exécution de pwrite() sur un fichier dont la recherche est impossible entraînera une erreur.
Erreurs
Ces fonctions échoueront si :
Constante | Description |
---|---|
EAGAIN | Le fichier n'est ni un tube, ni une FIFO, ni un socket, l'indicateur O_NONBLOCK est activé pour le descripteur de fichier et le processus léger serait retardé dans l'opération write(). |
EBADF | Le paramètre fildes n'est pas un descripteur de fichier valide ouvert en écriture. |
EFBIG | Une tentative d'écriture d'un fichier excède la taille maximale définie par l'implémentation ou la limite de taille de fichier du processus, et il n'y avait plus de place pour écrire des octets. |
EFBIG | Le fichier est un fichier standard, nbyte est supérieur à 0 et la position de départ est supérieure ou égale au déplacement maximal défini dans la description du fichier ouvert associée à fildes. |
EINTR | L'opération d'écriture a été interrompue suite à la réception d'un signal et aucune donnée n'a été transférée. |
EIO | Le processus est membre d'un groupe de processus d'arrière-plan et tente d'écrire sur son terminal de contrôle. TOSTOP est activé, le processus léger appelant ne bloque pas SIGTTOU, le processus n'ignore pas SIGTTOU et le groupe de processus du processus est orphelin. Cette erreur peut également être renvoyée dans des conditions définies par l'implémentation. |
ENOSPC | Il n'y avait plus d'espace libre sur le périphérique contenant le fichier. |
ERANGE | La taille de la requête de transfert était hors de la plage prise en charge par le fichier STREAMS associé à fildes. |
EAGAIN | Le fichier est un tube ou une FIFO, l'indicateur O_NONBLOCK est activé pour le descripteur de fichier et le processus léger serait retardé dans l'opération d'écriture. |
EAGAIN ou EWOULDBLOCK | Le fichier est un socket, l'indicateur O_NONBLOCK est activé pour le descripteur de fichier et le processus léger serait retardé dans l'opération d'écriture. |
ECONNRESET | Une tentative d'écriture a été effectuée sur un socket non connecté. |
EPIPE | Tentative d'écriture dans un tube ou une FIFO qui n'est ouvert en lecture par aucun processus, ou dont une seule extrémité est ouverte. Un signal SIGPIPE doit également être envoyé au processus léger. |
EPIPE | Tentative d'écriture sur un socket fermé en écriture ou déconnecté. Dans ce dernier cas, si le socket est de type SOCK_STREAM, un signal SIGPIPE doit également être envoyé au processus léger. |
EINVAL | Le STREAM ou le multiplexeur référencé par fildes est lié (directement ou indirectement) en aval d'un multiplexeur. |
EIO | Une erreur d'entrée/sortie physique s'est produite. |
ENOBUFS | Les ressources disponibles sur le système étaient insuffisantes pour effectuer l'opération. |
ENXIO | Une requête a été effectuée sur un périphérique inexistant, ou la requête dépassait les capacités du périphérique. |
ENXIO | Un blocage s'est produit sur le flux en cours d'écriture. L'écriture dans un fichier STREAMS peut échouer si un message d'erreur a été reçu au niveau de la tête du flux. Dans ce cas, errno est défini sur la valeur incluse dans le message d'erreur. |
EACCES | Une tentative d'écriture a été effectuée sur un socket et le processus appelant ne dispose pas des privilèges appropriés. |
ENETDOWN | Une tentative d'écriture a été effectuée sur un socket et l'interface réseau locale utilisée pour atteindre la destination est indisponible. |
ENETUNREACH | Une tentative d'écriture a été effectuée sur un socket et aucune route vers le réseau n'est présente. |
Exemple
L'exemple suivant écrit les données du tampon pointé par buf dans le fichier associé au descripteur de fichier fd :
Dernière mise à jour : Vendredi, le 5 Juin 2020