Fichiers & E/S · Section 2
lseek(2)
Repositionne le décalage lecture/écriture d'un descripteur de fichier.
Signature
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);- fd
- Descripteur seekable (fichier régulier, périphérique bloc).
- offset
- Décalage signé en octets, interprété selon whence.
- whence
- SEEK_SET (absolu), SEEK_CUR (relatif), SEEK_END (depuis EOF), SEEK_DATA (prochaines données après offset), SEEK_HOLE (prochain trou après offset).
Description
lseek() repositionne le décalage du descripteur fd à offset octets interprétés selon whence : SEEK_SET (absolu depuis le début), SEEK_CUR (relatif au courant), SEEK_END (relatif à la fin — offset négatif pour reculer). Retourne le décalage absolu résultant, ou (off_t) -1 avec errno. lseek() ne fait pas d'E/S — il ajuste le curseur de position par fd côté noyau. Chercher au-delà de la fin d'un fichier inscriptible puis écrire crée un trou creux (les pages intermédiaires sont à zéro en lecture mais non allouées sur disque). lseek() ne fonctionne pas sur tubes, sockets, FIFO ou terminaux — pas d'accès aléatoire, retour -1/ESPIPE. Sur les ABI 32 bits avec off_t 64 bits, le noyau expose _llseek() (retournant le décalage via un paramètre de sortie pour éviter le rognage 32 bits) ; la glibc moderne choisit transparemment le bon syscall.
Numéros par architecture
| Architecture | Numéro | ABI | Point d'entrée |
|---|---|---|---|
| x86 (i386) | 19 | i386 | sys_lseek |
| x64 (x86_64) | 8 | common | sys_lseek |
Historique noyau
Introduit dans Linux 1.0.
1.0
lseek() est l'un des syscalls originels. La signature 32 bits limite offset à 2 GiB sur i386 ; _llseek() (1995) a ajouté le chemin 64 bits.
3.1
SEEK_DATA et SEEK_HOLE ont été standardisés pour parcourir efficacement les fichiers creux sans lire chaque octet. Supportés par ext4, XFS, btrfs et tmpfs ; sur ceux qui n'exposent pas l'info de trou, le noyau retombe sur tout-le-fichier comme une seule région de données.
seccomp & conteneurs
Docker default profile
Autorisé
Podman default profile
Autorisé
lseek() et _llseek() sont dans tout profil par défaut. Pas de filtrage d'arguments utile — les applications utilisent whence et offset librement.
libseccomp
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(_llseek), 0);Exemple strace
$ strace -e lseek dd if=/etc/hostname of=/dev/null bs=1 count=4 skip=2
lseek(0, 2, SEEK_SET) = 2Les lignes lseek() s'associent à read()/write() pour former le mouvement d'E/S complet. L'usage le plus informatif est de suivre un parcours de fichier creux : SEEK_DATA → read → SEEK_HOLE → SEEK_DATA → read. -e lseek filtre.
Sécurité & observabilité
lseek() est rarement un signal direct. Motif notable : évasion de rotation de log où un malware reculer dans un fichier de log et écrase des octets antérieurs (au lieu d'append) pour masquer des entrées — mais la plupart des logs modernes sont append-only via O_APPEND, ce qui rend la course seek+write inopérante. Le tracepoint eBPF sys_enter_lseek est généralement trop bruyant pour la supervision.
Erreurs
- EBADF
- fd n'est pas un descripteur ouvert.
- EINVAL
- whence invalide, ou offset produirait une position absolue invalide (négative).
- ENXIO
- SEEK_DATA / SEEK_HOLE : offset au-delà d'EOF.
- EOVERFLOW
- Décalage résultant hors plage off_t (programme 32 bits non-LFS atteignant 4 GiB+).
- ESPIPE
- fd désigne un tube, une socket ou un FIFO — pas d'accès aléatoire.
Drapeaux
- SEEK_SET
- 0
- —
- SEEK_CUR
- 1
- —
- SEEK_END
- 2
- —
- SEEK_DATA
- 3
- Atteint le début de la prochaine région de données à ou après offset. Utilisé par cp --sparse et rsync pour sauter efficacement les trous.
- SEEK_HOLE
- 4
- Atteint le prochain trou à ou après offset. Combiné à SEEK_DATA, donne une énumération O(trous+données) de la disposition d'un fichier creux.