Fichiers
Progression
#Fichiers
Dans un OS moderne, un fichier est d'abord une abstraction. Derrière un simple chemin se cachent des métadonnées (droits, propriétaire, dates), des blocs de données, des caches et parfois des verrous distribués. Le développeur n'accède jamais directement au disque : il passe par une poignée appelée descripteur de fichier.
#1. Tables et descripteurs
Lorsqu'un processus appelle open
, le noyau vérifie les permissions, crée une entrée dans la table des fichiers ouverts du processus et renvoie un entier. Ce nombre n'a pas de signification intrinsèque : c'est un indice dans un tableau. Les descripteurs 0, 1 et 2 sont réservés à l'entrée standard, la sortie standard et la sortie d'erreur. Chaque entrée pointe vers une structure globale contenant la position courante, les flags (lecture seule, append...) et un lien vers l'inode. Ainsi, deux processus peuvent partager le même descripteur via dup
ou fork
, ce qui explique pourquoi un enfant hérite des fichiers ouverts par son parent.
#2. Lecture, écriture, repositionnement
read
lit jusqu'à N octets et fait avancer la position. write
ajoute des données ; si le fichier a été ouvert en mode append, le noyau décale automatiquement le curseur en fin de fichier avant l'écriture. lseek
permet de repositionner la tête de lecture. Il est crucial de vérifier systématiquement le nombre d'octets réellement transférés, car les appels peuvent être interrompus par des signaux et retourner partiellement. Les bibliothèques standard (stdio) enveloppent ces appels dans un tampon utilisateur pour limiter les transitions noyau-utilisateur, mais le comportement fondamental reste identique.
#3. Fichiers spéciaux et uniformité Unix
L'une des grandes forces d'Unix réside dans le principe « tout est fichier ». Les périphériques blocs et caractères situés dans /dev
, les tubes (pipe
), les sockets Unix, le pseudo-système /proc
qui expose l'état du noyau : tout se manipule avec les mêmes appels open
, read
, write
. Cette uniformité permet de brancher des composants entre eux sans modification. Elle impose aussi de maîtriser les permissions et les modes, faute de quoi un programme peut se retrouver bloqué à attendre un périphérique absent.
1int fd = open("journal.log", O_WRONLY | O_CREAT | O_APPEND, 0640);2if (fd == -1) { perror("open"); return 1; }3write(fd, buffer, length);4close(fd);
#Atelier
Tracez l'exécution d'un éditeur minimal qui écrit dans un fichier texte : capturez les appels open
, write
, fsync
grâce à strace -e ioctls=all -e trace=file
. Rejouez ensuite l'expérience avec un programme qui écrit 10 000 petites lignes et mesurez l'impact de fsync
et du tampon utilisateur (setvbuf
). Vous observerez que la performance dépend autant du système de fichiers que de la discipline côté application.