Fichiers & E/S · Section 2
write(2)
Écrit jusqu'à count octets depuis buf vers le fichier référencé par fd.
Signature
#include <unistd.h>
ssize_t write(int fd, const void * buf, size_t count);- fd
- Descripteur de fichier ouvert en écriture (O_WRONLY ou O_RDWR).
- buf
- Pointeur sur les données à écrire. Le tampon est en lecture seule du côté noyau.
- count
- Nombre d'octets à écrire. Le noyau plafonne à 0x7ffff000 par appel.
Description
write() écrit jusqu'à count octets depuis le tampon débutant à buf vers le fichier référencé par fd. Le nombre d'octets effectivement écrits est renvoyé ; il peut être inférieur à count (écriture partielle) si, par exemple, le support sous-jacent est lent, un signal interrompt l'appel, ou si count dépasse le plafond noyau (0x7ffff000 actuellement). Une valeur de -1 avec errno positionné indique un échec. write() est l'un des appels système les plus fréquents sur tout système Linux et sous-tend pratiquement toute forme de sortie : fichiers, sockets, tubes, terminaux.
Numéros par architecture
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x86 (i386) | 4 | i386 | sys_write |
| x64 (x86_64) | 1 | common | sys_write |
| ARM64 (aarch64) | 64 | — | sys_write |
Historique noyau
Introduit dans Linux 1.0.
1.0
write() est présent dans Linux depuis 1.0 ; le comportement suit POSIX.1 avec de petites extensions Linux autour des écritures partielles sur les tubes et le plafond de 0x7ffff000.
seccomp & conteneurs
Docker default profile
Autorisé
Podman default profile
Autorisé
write() figure dans les profils par défaut de Docker et Podman. Le bloquer est en pratique impossible — sans write(), le processus ne peut même pas produire de sortie sur stderr. Pour contraindre les E/S, mieux vaut restreindre par descripteur côté espace utilisateur (Landlock, wrapper) que par seccomp.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);Exemple strace
$ strace -e write echo hello
write(1, "hello\n", 6) = 6
+++ exited with 0 +++strace tronque les grands tampons par défaut ; utiliser -s 4096 pour en voir davantage. Les écritures vers un tube peuvent être filtrées via -e trace=write -P /dev/stdout pour un seul fd.
Sécurité & observabilité
write() est l'appel d'exfiltration canonique : toute donnée quittant le processus — socket, tube, fichier, /dev/tcp — y passe. Le tracepoint eBPF sys_enter_write se déclenche à chaque appel ; un monitoring à fort volume doit échantillonner ou filtrer par catégorie de fd pour éviter la saturation. Certains rootkits hookent write() pour masquer les lignes de journal mentionnant leurs propres fichiers (filtre 'log-grepper') ; la détection est aisée si l'on capture aussi les écritures au niveau noyau via lsm/file_permission.
Erreurs
- EBADF
- fd n'est pas un descripteur valide ou n'est pas ouvert en écriture.
- EFAULT
- buf est hors de l'espace d'adressage accessible au processus.
- EFBIG
- —
- EINTR
- L'appel a été interrompu par un signal avant qu'aucune donnée n'ait été écrite.
- EINVAL
- —
- EIO
- —
- ENOSPC
- Le périphérique contenant le fichier référencé par fd est plein.
- EPIPE
- fd renvoie sur un tube ou une socket dont l'extrémité de lecture est fermée. SIGPIPE est également délivré (sauf s'il est bloqué ou ignoré).