stdin, stdout, stderr são alguns números inteiros que indexam em uma estrutura de dados que 'sabe' quais canais de E / S devem ser usados para o processo. Entendo que essa estrutura de dados é exclusiva para todos os processos. Os canais de E / S são nada além de algumas estruturas de matriz de dados com alocação dinâmica de memória?
8
Respostas:
Em Unix-like sistemas operacionais, os fluxos de entrada, saída e erro padrão são identificados pelos descritores de arquivos
0
,1
,2
. No Linux, eles são visíveis noproc
sistema de arquivos em/proc/[pid]/fs/{0,1,2}
. Na verdade, esses arquivos são links simbólicos para um dispositivo pseudoterminal no/dev/pts
diretórioUm pseudoterminal (PTY) é um par de dispositivos virtuais, um mestre pseudoterminal (PTM) e um escravo pseudoterminal (PTS) (coletivamente chamado de par pseudoterminal ), que fornecem um canal IPC, semelhante a um canal bidirecional entre um programa que espera estar conectado a um dispositivo terminal e a um programa de driver que use o pseudoterminal para enviar e receber informações do programa anterior.
Um ponto importante é que o escravo pseudo-terminal aparece como um terminal comum, por exemplo, pode ser alternado entre os modos não-canônico e canônico (o padrão), no qual interpreta certos caracteres de entrada, como gerar um
SIGINT
sinal quando um caractere de interrupção (normalmente gerado pressionando Ctrl+ Cno teclado) é gravado no mestre pseudoterminal ou fazendo com que o próximoread()
retorne0
quando um caractere de fim de arquivo (normalmente gerado por Ctrl+ D) é encontrado. Outras operações suportadas pelos terminais estão ativando ou desativando o eco, definindo o grupo de processos em primeiro plano etc.Os pseudoterminais têm vários usos:
Eles permitem que programas gostem
ssh
de operar programas orientados a terminal em outro host conectado via rede. Um programa orientado ao terminal pode ser qualquer programa que normalmente seria executado em uma sessão interativa do terminal. A entrada, saída e erro padrão de tal programa não podem ser conectados diretamente ao soquete, pois os soquetes não suportam a funcionalidade relacionada ao terminal acima mencionada.Eles permitem programas como
expect
dirigir um programa interativo orientado ao terminal a partir de um script.Eles são usados por emuladores de terminal, como
xterm
para fornecer funcionalidade relacionada ao terminal.Eles são usados por programas como
screen
multiplexar um único terminal físico entre vários processos.Eles são usados por programas como
script
para gravar todas as entradas e saídas que ocorrem durante uma sessão de shell.PTYs no estilo Unix98 , usados no Linux, são configurados da seguinte maneira:
O programa do driver abre o multiplexador mestre do pseudo-terminal em
dev/ptmx
, no qual recebe um descritor de arquivo para um PTM, e um dispositivo PTS é criado no/dev/pts
diretório Cada descritor de arquivo obtido pela abertura/dev/ptmx
é um PTM independente com seu próprio PTS associado.Os programas do driver chamam
fork()
para criar um processo filho, que por sua vez executa as seguintes etapas:A criança chama
setsid()
para iniciar uma nova sessão, da qual a criança é líder da sessão. Isso também faz com que a criança perca seu terminal de controle .A criança continua a abrir o dispositivo PTS que corresponde ao PTM criado pelo programa do driver. Como a criança é líder de sessão, mas não possui terminal de controle, o PTS se torna o terminal de controle da criança.
A criança usa
dup()
para duplicar o descritor de arquivo para o dispositivo escravo nele, entrada, saída e erro padrão.Por fim, a criança chama
exec()
para iniciar o programa orientado ao terminal que deve ser conectado ao dispositivo pseudoterminal.Nesse momento, tudo o que o programa do driver grava no PTM aparece como entrada para o programa orientado ao terminal no PTS e vice-versa.
Ao operar no modo canônico, a entrada para o PTS é armazenada em buffer linha por linha. Em outras palavras, assim como nos terminais regulares, a leitura do programa de um PTS recebe uma linha de entrada somente quando um caractere de nova linha é gravado no PTM. Quando a capacidade do buffer estiver esgotada, outras
write()
chamadas serão bloqueadas até que parte da entrada tenha sido consumida.No kernel Linux, as chamadas de sistema relacionado arquivo
open()
,read()
,write()
stat()
etc. são implementados na camada Virtual sistema de arquivos (VFS), que fornece uma interface de sistema de arquivos uniforme para programas de espaço de usuário. O VFS permite que diferentes implementações do sistema de arquivos coexistam no kernel. Quando os programas de espaço do usuário chamam as chamadas de sistema mencionadas acima, o VFS redireciona a chamada para a implementação apropriada do sistema de arquivos.Os dispositivos PTS abaixo
/dev/pts
são gerenciados peladevpts
implementação do sistema de arquivos definida em/fs/devpts/inode.c
, enquanto o driver TTY que fornece optmx
dispositivo no estilo Unix98 é definido emdrivers/tty/pty.c
.O buffer entre dispositivos TTY e as disciplinas de linha TTY , como pseudo-terminais, é fornecida uma estrutura de buffer mantida para cada dispositivo tty, definido em
include/linux/tty.h
Antes da versão 3.7 do kernel, o buffer era um buffer flip :
A estrutura continha armazenamento dividido em dois buffers de tamanho igual. Os buffers foram numerados
0
(primeira metade dechar_buf/flag_buf
) e1
(segunda metade). O driver armazenou dados no buffer identificado porbuf_num
. O outro buffer pode ser liberado para a disciplina de linha.O buffer foi 'invertido' alternando
buf_num
entre0
e1
. Quandobuf_num
alterado,char_buf_ptr
eflag_buf_ptr
foi definido como o início do buffer identificado porbuf_num
, ecount
foi definido como0
.Desde a versão 3.7 do kernel, os buffers flip TTY foram substituídos por objetos alocados por meio de
kmalloc()
anéis organizados . Em uma situação normal para uma porta serial acionada por IRQ em velocidades típicas, seu comportamento é praticamente o mesmo do antigo buffer de buffer; dois buffers acabam alocados e o kernel alterna entre eles como antes. No entanto, quando há atrasos ou a velocidade aumenta, a nova implementação do buffer tem um desempenho melhor, pois o buffer pool pode crescer um pouco.fonte
Nas páginas de manual de qualquer um dos três, explica a resposta:
fonte
stdin
,stdout
estderr
do ponto de vista da biblioteca C, mas a questão é explicitamente sobre a implementação do kernel. Eu tentei explicar o ponto de vista do kernel na minha resposta .