stdin, stdout, stderr sont des entiers qui indexent dans une structure de données qui «sait» quels canaux d'E / S doivent être utilisés pour le processus. Je comprends que cette structure de données est propre à chaque processus. Les canaux d'E / S ne sont-ils que des structures de tableaux de données avec allocation dynamique de mémoire?
8
Réponses:
Dans Unix systèmes d' exploitation, l'entrée standard, de sortie et les flux d' erreur sont identifiés par les descripteurs de fichiers
0
,1
,2
. Sous Linux, ceux-ci sont visibles sous leproc
système de fichiers dans/proc/[pid]/fs/{0,1,2}
. Ces fichiers sont en fait des liens symboliques vers un périphérique pseudoterminal sous le/dev/pts
répertoire.Un pseudoterminal (PTY) est une paire de dispositifs virtuels, un pseudoterminal master (PTM) et un pseudoterminal slave (PTS) (collectivement appelés pseudoterminal pair ), qui fournissent un canal IPC, un peu comme un tuyau bidirectionnel entre un programme qui attend à connecter à un terminal et à un programme pilote qui utilise le pseudoterminal pour envoyer et recevoir des données de l'ancien programme.
Un point clé est que l'esclave pseudoterminal apparaît comme un terminal normal, par exemple, il peut basculer entre le mode non canonique et canonique (par défaut), dans lequel il interprète certains caractères d'entrée, comme générer un
SIGINT
signal lorsqu'un caractère d' interruption (généré normalement en appuyant sur Ctrl+ Csur le clavier) est écrit sur le maître pseudoterminal ou provoque leread()
retour du suivant0
lorsqu'un caractère de fin de fichier (normalement généré par Ctrl+ D) est rencontré. D'autres opérations prises en charge par les terminaux activent ou désactivent l'écho, définissent le groupe de processus de premier plan, etc.Les pseudoterminaux ont un certain nombre d'utilisations:
Ils permettent à des programmes comme de
ssh
faire fonctionner des programmes orientés terminal sur un autre hôte connecté via un réseau. Un programme orienté terminal peut être n'importe quel programme, qui serait normalement exécuté dans une session de terminal interactif. L'entrée, la sortie et l'erreur standard d'un tel programme ne peuvent pas être connectées directement à la prise, car les prises ne prennent pas en charge la fonctionnalité liée au terminal susmentionnée.Ils permettent à des programmes comme
expect
de piloter un programme orienté terminal interactif à partir d'un script.Ils sont utilisés par les émulateurs de terminaux
xterm
afin de fournir des fonctionnalités liées aux terminaux.Ils sont utilisés par des programmes tels que
screen
le multiplexage d'un seul terminal physique entre plusieurs processus.Ils sont utilisés par des programmes comme
script
pour enregistrer toutes les entrées et sorties se produisant pendant une session shell.Les PTY de style Unix98 , utilisés sous Linux, sont configurés comme suit:
Le programme pilote ouvre le multiplexeur maître pseudo-terminal
dev/ptmx
sur lequel il reçoit un descripteur de fichier pour un PTM et un dispositif PTS est créé dans le/dev/pts
répertoire. Chaque descripteur de fichier obtenu par ouverture/dev/ptmx
est un PTM indépendant avec son propre PTS associé.Le pilote programme des appels
fork()
pour créer un processus enfant, qui à son tour effectue les étapes suivantes:L'enfant appelle
setsid()
pour démarrer une nouvelle session, dont l'enfant est le chef de session. Cela fait également perdre à l'enfant son terminal de contrôle .L'enfant procède à l'ouverture du dispositif PTS qui correspond au PTM créé par le programme pilote. Étant donné que l'enfant est un chef de session, mais n'a pas de terminal de contrôle, le PTS devient le terminal de contrôle de l'enfant.
L'enfant utilise
dup()
pour dupliquer le descripteur de fichier du périphérique esclave sur l'entrée, la sortie et l'erreur standard.Enfin, l'enfant appelle
exec()
pour démarrer le programme orienté terminal qui doit être connecté au dispositif pseudoterminal.À ce stade, tout ce que le programme pilote écrit sur le PTM apparaît en tant qu'entrée dans le programme orienté terminal sur le PTS, et vice versa.
En fonctionnement en mode canonique, l'entrée du PTS est mise en mémoire tampon ligne par ligne. En d'autres termes, tout comme avec les terminaux normaux, la lecture de programme à partir d'un PTS ne reçoit une ligne d'entrée que lorsqu'un caractère de nouvelle ligne est écrit dans le PTM. Lorsque la capacité de mise en mémoire tampon est épuisée, d'autres
write()
appels bloquent jusqu'à ce qu'une partie de l'entrée ait été consommée.Dans le noyau Linux, les appels système de fichiers liés
open()
,read()
,write()
stat()
etc. sont mis en œuvre dans la couche virtuelle Filesystem (VFS), qui fournit une interface de système de fichiers uniforme pour les programmes de l' espace utilisateur. Le VFS permet à différentes implémentations de système de fichiers de coexister dans le noyau. Lorsque les programmes de l'espace utilisateur appellent les appels système susmentionnés, le VFS redirige l'appel vers l'implémentation du système de fichiers appropriée.Les périphériques PTS sous
/dev/pts
sont gérés par l'devpts
implémentation du système de fichiers définie dans/fs/devpts/inode.c
, tandis que le pilote TTY fournissant le périphérique de style Unix98ptmx
est défini dans dansdrivers/tty/pty.c
.La mise en mémoire tampon entre les appareils TTY et les disciplines de ligne TTY , telles que les pseudoterminaux, est fournie une structure de mémoire tampon maintenue pour chaque appareil tty, définie dans
include/linux/tty.h
Avant la version 3.7 du noyau, le tampon était un tampon inversé :
La structure contenait un stockage divisé en deux tampons de taille égale. Les tampons ont été numérotés
0
(première moitié dechar_buf/flag_buf
) et1
(seconde moitié). Le pilote a stocké les données dans le tampon identifié parbuf_num
. L'autre tampon pourrait être vidé de la discipline de ligne.Le tampon a été inversé en basculant
buf_num
entre0
et1
. Une foisbuf_num
modifié,char_buf_ptr
et aflag_buf_ptr
été défini au début du tampon identifié parbuf_num
, et acount
été défini sur0
.Depuis la version 3.7 du noyau, les tampons de retournement TTY ont été remplacés par des objets alloués via
kmalloc()
organisés en anneaux . Dans une situation normale pour un port série piloté par IRQ à des vitesses typiques, leur comportement est à peu près le même qu'avec l'ancien tampon flip; deux tampons finissent par être alloués et le noyau passe entre eux comme précédemment. Cependant, lorsqu'il y a des retards ou que la vitesse augmente, la nouvelle implémentation de tampon fonctionne mieux car le pool de tampons peut augmenter un peu.la source
À partir des pages de manuel de l'un des trois, il explique la réponse:
la source
stdin
,stdout
etstderr
du point de vue de la bibliothèque C, mais la question est explicitement à propos de la mise en œuvre du noyau. J'ai essayé de tenir compte du point de vue du noyau dans ma réponse .