Gestion des fichiers ouverts
Dans un système unix ce sont les process qui ouvrent des fichiers, mais le noyaux en garde en sous-main le contrôle pour permettre à des process différents de se partager les ressources ouvertes.
Process
Chaque process doit garder une liste des fichiers qu'il a ouvert et peut donc utiliser.
A chaque fichier ouvert est associé un numéro nommé Un descripteur de fichier (file descriptor). Les différents fichiers ouvert par un process donné sont accessibles via leurs file descriptor dans leurs /proc :
ls -la /proc/$$/fd
Tout process a toujours 3 file descriptors :
- 0 qui est stdin
 - 1 qui est stdout
 - 2 qui est stderr
 - 255 uniquement si vous utilisez bash (utilisé pour ses besoins internes)
 
Ces fichiers ouverts sont des redirections vers le fichier tty correspondant.
Les fichiers stdin, stdout et stderr  présent dans /dev/ sont des liens.
Vers quoi pointent-ils ?
solution
solution
vers les files descriptor de /proc/self/ qui est le process actuellement entrain d'être exécuté (et il change de nombreuses fois par secondes...).
A chaque lecture du fichier /proc/self/, le noyau va donner le process actuellement entrain d'être exécuté, c'est à dire celui qui lit le dossier. Ainsi, si vous exécutez la commande :
ls -l /proc/self
Cela vous affichera le process du ls entrain de lire /proc/self.
De la même manière si vous écrivez :
echo "coucou" >> /dev/stdout
C'est dans le stdout de echo que vous écrivez (et c'est donc identique à écrire echo "coucou").
Ouvrez deux terminaux :
- vérifiez que les 3 FD ne pointent pas vers le même tty
 - écrivez dans le stdout de l'un à partir de l'autre.
 
Vous pouvez connaître leurs informations dans le dossier fdinfo :
ls -la /proc/$$/fdinfo/1
Fichiers ouverts
Si vous utilisez la commande lsof -p $$ vous verrez que process ouvre plus de fichiers que les fide descriptors numériques (qui sont des entrées/sorties) :
$ lsof -p $$
COMMAND    PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
bash    928549 fbrucker  cwd    DIR   0,24        4 5241736 /proc/928549/fd
bash    928549 fbrucker  rtd    DIR    8,2     4096       2 /
bash    928549 fbrucker  txt    REG    8,2  1415800  655454 /usr/bin/bash
bash    928549 fbrucker  mem    REG    8,2  8321104  662997 /usr/lib/locale/locale-archive
bash    928549 fbrucker  mem    REG    8,2  1641496  663748 /usr/lib/aarch64-linux-gnu/libc.so.6
bash    928549 fbrucker  mem    REG    8,2   195784  658635 /usr/lib/aarch64-linux-gnu/libtinfo.so.6.3
bash    928549 fbrucker  mem    REG    8,2   187776  663741 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
bash    928549 fbrucker  mem    REG    8,2    27004  664116 /usr/lib/aarch64-linux-gnu/gconv/gconv-modules.cache
bash    928549 fbrucker    0u   CHR  136,1      0t0       4 /dev/pts/1
bash    928549 fbrucker    1u   CHR  136,1      0t0       4 /dev/pts/1
bash    928549 fbrucker    2u   CHR  136,1      0t0       4 /dev/pts/1
bash    928549 fbrucker  255u   CHR  136,1      0t0       4 /dev/pts/1
Il y a :
- le dossier où est le shell (ici 
/proc/928549/fd) - le fichier exécuté bash lui-même !
 - les bibliothèques partagées utilisées par le programme bash
 - les fichiers de communications stdin, stdout, stderr et 255.
 
- ouvrez un fichier texte avec 
less - trouver son PID avec 
ps aux | grep less - voir ses fichiers ouverts
 
On peut également faire le contraire et regarder quel process ouvre tel fichier en utilisant la commande fuser :
$ fuser -v /usr/bin/bash
                     UTIL.       PID ACCÈS  COMMANDE
/usr/bin/bash:       fbrucker  928549 ...e. bash
Limites
Un process particulier ne peut pas forcément ouvrir autant de fichier. Par défaut, la limite est 1024. Comme annoncée dans le fichier limits du process :
$ cat /proc/$$/limits
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            8388608              unlimited            bytes     
Max core file size        0                    unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             7422                 7422                 processes 
Max open files            1024                 1048576              files     
Max locked memory         257257472            257257472            bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       7422                 7422                 signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited       
Vous pouvez aussi utiliser la commande : ulimit -a et ses différentes options pour particulariser la limite à chercher. Exemple ulimit -n.
Noyau
Le noyau maintient à jour une table globale contenant tous les fichiers ouverts par tous les process. Cette table, nommé file table contient :
- le type d'accès au fichier : lecture ou écriture
 - un lien vers le fichier : inode pour un fichier classique ou un dossier, socket, etc
 - la position dans le fichier
 - le nombre de file descriptor pointant vers cette structure
 
Chaque file descriptor est alors associé à un élément de la file table.
process             noyau
  FD         Table         
              T1  ---------> inode/socket/pipe/...
  23 -        T2 
       \        
        \     Ti  ---
         \            \
  42  ----->  Fj   ------->  Vk
Plusieurs file descriptor (d'un même process ou de process différents) peuvent pointer vers le même élément de la table, et plusieurs élément de la table peuvent ouvrir le même fichier.
La table est initialisée au démarrage et contient toutes les structures, le type de fichier étant libre. Il y a donc un nombre maximum de fichier qui peuvent être ouvert en même temps pour un système.
On peut bien sur connaître le nombre de fichier actuellement ouvert : cat /proc/sys/fs/nr_open et le nombre de fichier maximum cat /proc/sys/fs/file-max. Chez moi cela donne :
$ cat /proc/sys/fs/nr_open
1048576
$ cat /proc/sys/fs/file-max
9223372036854775807
Fork
Lors de la création de nouveaux process, les files descriptors sont dupliqués :
- l'enfant à le même nombre de file descriptor que son parent
 - les file descriptors de l'enfant pointent vers les même élément de la table que son parent