Emuladores de terminal
O lado mestre substitui a linha (o par de fios TX / RX) que vai para o terminal.
O terminal exibe os caracteres que recebe em um dos fios (alguns são caracteres de controle e o fazem fazer coisas como mover o cursor, mudar de cor ...) e envia em outro fio os caracteres correspondentes às teclas digitadas.
Emuladores de terminal como o xterm não são diferentes, exceto que, em vez de enviar e receber caracteres nos fios, eles lêem e escrevem caracteres no descritor de arquivo para o lado mestre. Uma vez que eles geraram o terminal escravo, e iniciaram seu shell nisso, eles não tocam mais nisso. Além de emular o par de fios, o xterm também pode alterar algumas das propriedades da disciplina de linha por meio do descritor de arquivo para o lado mestre. Por exemplo, eles podem atualizar os atributos de tamanho para que um SIGWINCH seja enviado aos aplicativos que interagem com o escravo para notificá-los sobre um tamanho alterado.
Fora isso, há pouca inteligência no terminal / emulador de terminal.
O que você escreve em um dispositivo terminal (como o escravo pty) é o que você quer que seja exibido lá, o que você lê nele é o que você digitou lá, portanto, não faz sentido que o emulador de terminal leia ou grave nele . Eles são os que estão do outro lado.
A disciplina tty line
Uma boa parte da inteligência está na disciplina linha tty . A disciplina de linha é um módulo de software (residente no driver, no kernel) colocado em cima de um dispositivo serial / pty que fica entre esse dispositivo e a linha / fio (o lado principal de um pty).
Uma linha serial pode ter um terminal na outra extremidade, mas também um mouse ou outro computador para conexão em rede. Você pode anexar uma disciplina de linha SLIP, por exemplo, para obter uma interface de rede em cima de um dispositivo serial (ou dispositivo pty), ou pode ter uma disciplina de linha tty . A disciplina de linha tty é a disciplina de linha padrão, pelo menos no Linux, para dispositivos seriais e pty. No Linux, você pode alterar a disciplina da linha com ldattach
.
Você pode ver o efeito de desabilitar a disciplina de linha tty emitindo stty raw -echo
(observe que o prompt do bash ou outros aplicativos interativos, como vi
o terminal, definem o modo exato de que precisam, portanto, você deseja usar um aplicativo idiota que gosta cat
de experimentar isso). Então, tudo o que é gravado no dispositivo terminal escravo chega imediatamente ao lado mestre para o xterm ler, e todos os caracteres gravados pelo xterm no lado mestre ficam imediatamente disponíveis para leitura no dispositivo escravo.
A disciplina de linha é onde o editor de linha interno do dispositivo de terminal é implementado. Por exemplo, com stty icanon echo
(como é o padrão), quando você digita a
, xterm grava a
no mestre, a disciplina de linha o ecoa de volta (torna a
disponível para leitura por xterm
para exibição), mas não disponibiliza nada para leitura no lado escravo . Então, se você digita backspace, xterm envia um ^?
ou ^H
caráter, a disciplina de linha (como que ^?
ou ^H
corresponde à erase
definição de linha de disciplina) envia de volta no mestre um ^H
, space
e ^H
para xterm
apagar aa
você acabou de digitar na tela e ainda não envia nada para o aplicativo lendo do lado escravo, apenas atualiza seu buffer interno do editor de linha para remover o que a
você digitou anteriormente.
Então, quando você pressiona Enter, o xterm envia ^M
(CR), que a disciplina de linha converte na entrada para ^ ^ (LF) e envia o que você inseriu até agora para leitura no lado escravo (um aplicativo lendo /dev/pts/x
receberá o que você digitou incluindo o LF, mas não o a
desde que o excluiu); enquanto no lado mestre, ele envia um CR e LF para mover o cursor para a próxima linha e o início da tela.
A disciplina de linha também é responsável por enviar o SIGINT
sinal para o grupo de processos em primeiro plano do terminal quando recebe um ^C
caractere no lado mestre etc.
Muitos aplicativos de terminal interativos desativam a maioria dos recursos dessa disciplina de linha para implementá-los. Mas, em qualquer caso, lembre-se de que o terminal ( xterm
) tem pouco envolvimento nisso (exceto exibindo o que é solicitado para exibir).
E pode haver apenas uma sessão por processo e por dispositivo terminal. Uma sessão pode ter um terminal de controle conectado a ela, mas não é necessário (todas as sessões começam sem um terminal até abrirem um). xterm
, no processo em que você executa a execução de seu shell normalmente criará uma nova sessão (e, portanto, será desconectada do terminal de onde você iniciou xterm
), abra a nova /dev/pts/x
gerada, conectando esse dispositivo à nova sessão. Ele executará seu shell nesse processo, para que ele se torne o líder da sessão. Seu shell ou qualquer shell interativo nessa sessão normalmente faz malabarismos com grupos de processos e tcsetpgrp()
, para definir os trabalhos de primeiro e segundo plano para esse terminal.
Quanto às informações armazenadas por um dispositivo terminal com uma disciplina tty (serial ou pty) , normalmente é o que o stty
comando exibe e modifica. Toda a configuração da disciplina: tamanho da tela do terminal, local, sinalizadores de saída de entrada, configurações para caracteres especiais (como ^ C, ^ Z ...), velocidade de entrada e saída (não relevante para ptys). Isso corresponde às funções tcgetattr()
/ tcsetattr()
que no Linux são mapeadas para TCGETS
/ TCSETS
ioctls e TIOCGWINSZ
/ TIOCSWINSZ
para o tamanho da tela. Você pode argumentar que o grupo de processos atual em primeiro plano é outra informação armazenada no dispositivo terminal ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls) ou no buffer de entrada ou saída atual.
Observe que as informações de tamanho de tela armazenadas no dispositivo terminal podem não refletir a realidade. O emulador de terminal normalmente o define (através do mesmo ioctl no tamanho principal) quando sua janela é redimensionada, mas pode ficar fora de sincronia se um aplicativo chamar o ioctl no lado escravo ou quando o redimensionamento não for transmitido (no caso de uma conexão ssh que implica outro pty gerado por sshd
se ssh
ignora o, SIGWINCH
por exemplo). Alguns terminais também podem ser consultados em seu tamanho por meio de seqüências de escape, para que um aplicativo possa consultá-lo dessa maneira e atualizar a disciplina de linha com essas informações.
Para mais detalhes, você pode dar uma olhada nas páginas de manual termios
e tty_ioctl
no Debian, por exemplo.
Para jogar com outras disciplinas de linha:
Emule um mouse com um pseudo-terminal:
socat pty,link=mouse fifo:fifo
sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
xinput list # see the new mouse there
exec 3<> fifo
printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
Acima, o lado mestre do pty é finalizado por socat em um pipe nomeado ( fifo
). Nós conectamos esse fifo a um processo (o shell) que grava 0x87 0x0a 0x00, o que significa no protocolo dos sistemas de mouse no button pressed, delta(x,y) = (10,0)
. Aqui, nós (o shell) não estamos emulando um terminal, mas um mouse, os 3 bytes que enviamos não devem ser lidos (potencialmente transformados) por um aplicativo do dispositivo terminal ( mouse
acima do qual é um link simbólico feito por socat
algum /dev/pts/x
dispositivo) , mas devem ser interpretados como um evento de entrada do mouse.
Crie uma interface SLIP:
# on hostA
socat tcp-listen:12345,reuseaddr pty,link=interface
# after connection from hostB:
sudo ldattach SLIP interface
ifconfig -a # see the new interface there
sudo ifconfig sl0 192.168.123.1/24
# on hostB
socat -v -x pty,link=interface tcp:hostA:12345
sudo ldattach SLIP interface
sudo ifconfig sl0 192.168.123.2/24
ping 192.168.123.1 # see the packets on socat output
Acima, o fio serial é emulado socat
como um soquete TCP entre o hostA e o hostB. A disciplina de linha SLIP interpreta os bytes trocados nessa linha virtual como pacotes IP encapsulados em SLIP para entrega na sl0
interface.
cat /dev/ptmx &
que abre um novo pty, mas não há um processo que eu possa encontrar associado a ele, então como você o usaria? Segundo eu tenteiecho "1" >/dev/ptmx
, mas isso não fez nada ... Por que estou interessado nisso? Porque muitas vezes quando alguém se conecta remotamente viassh
(por exemplo), você recebePTY allocation request failed
ouNo controlling tty: open /dev/tty
erro, o que impede o controle do trabalho. Seria bom entender melhor isso.pty
página de manual para detalhes.physical term
----tty
----bash
nos terminais epty(m)
----tty
----pty(s)
----bash
nos emuladores de terminais? Atty
disciplina também foi responsável pelo eco dos caracteres no terminal físico? 2. É o programa emulador de terminal que se conecta ao teclado / tela para gerenciar as entradas? 3. De acordo com o que entendi, você disse que o buffer de linha dos comandos bash / toda a entrada do terminal é feito portty
disciplina de linha, em vez de buffers de E / S das funções de CI / O. Isso está correto?Edit: Desde esta resposta, escrevi um artigo dedicado no meu blog, para pessoas que estariam interessadas em mais detalhes.
Depois de muita leitura, foi o que eu entendi.
/dev/ptmx
não aloca a parte escrava : aloca a "parte principal do pseudo terminal". / dev / ptmx não é o pseudo terminal mestre : é um multiplexador mestre de pseudo terminal . Foi criado com o padrão Unix98 PTY para evitar condições de corrida ao alocar pseudo terminal principal ( fonte ).A parte principal (ptm) do pseudo terminal não está representada no sistema de arquivos. É representado por um descritor de arquivo.
A parte escrava (pts) é representada por um arquivo em
/dev/pts/N
queN
está um número.Os pts é obtido a partir da PTM por meio da chamada sucessiva de
grandpt
,unlockpt
,ptsname
. ( Fonte )O ptm substitui o driver AUR dedicado à comunicação com o dispositivo e a edição de linha. Portanto, ele não emula de forma alguma um terminal, mas fornece o recurso de edição de linha e fornece uma maneira de visualizar e se comunicar com pts. ( Fonte )
Aqui está um gráfico do que era um TTY conectado a um dispositivo de hardware
E aqui está um gráfico de um tty conectado a um ptm
O arquivo ptm manipula diferentes argumentos Ioctl (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL) que os pts.
Os processos interagem com os dispositivos por meio de ações realizadas em um arquivo virtual (leitura, gravação, ioctl ..). O arquivo em si não existe e o driver usa o arquivo para acionar ações quando métodos de leitura ou gravação são chamados. (Consulte o anexo para obter informações sobre drivers)
Um TTY define uma maneira precisa de interagir com ele. Os processos gravam e leem do dispositivo e esperam o mesmo comportamento, independentemente do tipo de TTY implementado.
Os pts se comportam como um driver TTY. Seu método de leitura e gravação é usado para implementar o comportamento do driver TTY. Como não há um dispositivo real para enviar os dados, um par de fluxos é criado e o ptm implementa uma função de leitura para ler os dados enviados por pontos ao fluxo e uma função de gravação para enviar dados ao fluxo que estarão disponíveis quando os pts irão lê-lo.
Lembre-se, o arquivo que representa um dispositivo não é um arquivo clássico e, se
xterm
quiser ver o que foi gravado no arquivo, ele não pode simplesmente ser chamado de aberto e lido, pois essas funções têm um comportamento completamente diferente aqui.Acho que não, o ID da sessão é definido pelo primeiro processo que anexa os pontos (bash geralmente), e não vejo uma maneira de criar outra sessão e anexá-los aos mesmos pontos. Talvez uma ferramenta como
socat
poderia fazer isso?Os pts armazenam 2 categorias de informações sobre o terminal com o qual está se comunicando: o
Terminfo
e oTermcap
. Geralmente, muitos emuladores de terminal são baseados em bibliotecas que gerenciam informações de termcap para eles (que fornecerão todos os valores de recursos para emular um VTX100, por exemplo). Um exemplo dessa biblioteca é a libvte . Editar (consulte o comentário de Stephane Chazelas): Os recursos do terminal não são armazenados pelos pts.Anexo
fonte
Aqui está um esquema que fiz há algum tempo sobre como
sshd
funciona. Não diz respeito à operação da disciplina de linha e outras coisas, mas adiciona uma ilustração da vida real de quem interage com o que:fonte
-T
qual o homem diz que desabilita a alocação de pseudo-terminal. por exemplo:ssh -T emasculateur@localhost "sleep 10"
entãops aux|grep sleep
mostra o seguinte:emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10
Nesse caso, onde o bash escrevestdout
estderr
? Espero que minha pergunta faça sentido./dev/null
gostar de um daemon normal, mas não tenho certeza. Veja também: serverfault.com/questions/593399/…nohup
ouscreen
/tmux
.man pts
diz:Sobre
/dev/pts/X indexing
:cada X é uma sessão que você abre, então os escravos precisam indexar.
Sobre
TeteType (/dev/ttyN
):Seu console real foi gerado pelo seu sistema de inicialização, como
sysV
.Sobre Por que o escravo instalado no mestre: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png
fonte