Au niveau du descripteur de fichier, stdin est défini comme étant le descripteur de fichier 0 , stdout est défini comme étant le descripteur de fichier 1; et stderr est défini comme étant le descripteur de fichier 2 . Regarde ça.
Même si votre programme -ou le shell- change (par exemple rediriger avec dup2(2)) le descripteur de fichier 0, il reste toujours stdin (puisque par définition STDIN_FILENO
est 0).
Les appels système comme open(2) ou pipe(2) ou socket(2) peuvent donner par ex. STDIN_FILENO
(c'est-à-dire 0) si ce descripteur de fichier est libre (par exemple parce qu'il a été close(2)-d auparavant). Mais quand cela se produit, c'est toujours stdin par définition.
Bien sûr, dans stdio(3), le FILE
stream stdin est un peu plus complexe. Votre programme pourrait fclose(3), freopen(3), fdopen(3) ...
Bien que quelques réponses existaient déjà, mais je ne les ai pas trouvées suffisamment informatives pour expliquer l'histoire complète.
Depuis que j'ai avancé et fait des recherches supplémentaires, j'ajoute mes découvertes.
Chaque fois qu'un processus démarre, une entrée du processus en cours est ajoutée au /proc/<pid>
annuaire. C'est l'endroit où sont conservées toutes les données relatives au processus. De plus, au démarrage du processus, le noyau alloue 3 descripteurs de fichier au processus pour la communication avec les 3 flux de données appelés stdin
, stdout
et stderr
.
le noyau Linux utilise un algorithme pour toujours créer un FD avec la valeur entière la plus basse possible afin que ces flux de données soient mappés sur les nombres 0
, 1
et 2
.
Puisque ce ne sont que des références à un flux et nous pouvons fermer un flux. On peut facilement appeler close(<fd>)
, dans notre cas close(1)
, pour fermer le descripteur de fichier.
en faisant ls -l /proc/<pid>/fd/
, nous ne voyons que 2 FD répertoriés ici 0
et 2
.
Si nous faisons maintenant un open()
appeler le noyau créera un nouveau FD pour mapper cette nouvelle référence de fichier et puisque le noyau utilise l'algorithme de l'entier le plus bas en premier, il récupérera la valeur entière 1
.
Alors maintenant, le nouveau FD créé pointe vers le fichier que nous avons ouvert (en utilisant le open()
appel système)
Tout transfert de données qui se produit maintenant ne se fait pas via le flux de données par défaut qui était précédemment lié, mais le nouveau fichier que nous avons ouvert.
Alors oui, on peut cartographier le FD 0
, 1
ou 2
à n'importe quel fichier et pas nécessaire stdin
, stdout
ou stderr