Skip to content
/linux-syscalls

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

ArchitectureNuméroABIPoint d'entrée
x86 (i386)4i386sys_write
x64 (x86_64)1commonsys_write
ARM64 (aarch64)64—sys_write

Historique noyau

Introduit dans Linux 1.0.

  1. 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é).

Syscalls liés