Como o ssh sempre consegue redefinir os atributos do terminal?

3

Se eu correr

strace -e trace=ioctl -v ssh some_remote_host

vejo uma linha como esta:

ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x6006, c_oflags=0x4, c_cflags=0x
4bf, c_lflags=0xa00, c_line=0, c_cc[VMIN]=1, c_cc[VTIME]=0, c_cc="\x03\x1c\x7f\x
15\x04\x00\x01\xff\x11\x13\x1a\xff\x12\x0f\x17\x16\xff\x00\x00"}) = 0

O que faz sentido: ssh tem que alterar muitas configurações do terminal, por exemplo:

  • desativa ISIG porque ^ C e ^ Z devem interromper e suspender o processo no host remoto, não o processo ssh em execução localmente;
  • desativa ICANON porque deseja receber a entrada do teclado sem buffer em vez de armazenar em linha;
  • desativa ECHO porque se o eco ocorrer deve depender dos atributos definidos no pseudo-terminal do host remoto, em vez de ocorrer automaticamente no terminal local

Se você sair da sessão ssh , os atributos originais do terminal serão restaurados por uma segunda chamada ioctl :

ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x6d02, c_oflags=0x5, c_cflags=0x
4bf, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\xff\x11\x13\x
1a\xff\x12\x0f\x17\x16\xff\x00\x00"}) = 0

Mas o que eu acho estranho é que, mesmo se ssh for eliminado com SIGKILL antes que tenha a chance de fazer a segunda chamada ioctl , você recuperará os atributos originais do terminal. Caso contrário, você notaria que algo está muito errado (por exemplo, os comandos digitados no shell não seriam ecoados). Como o ssh consegue garantir que os atributos originais do terminal sejam restaurados, mesmo que não seja possível chamar ioctl novamente?

    
por Brian Bi 14.11.2015 / 08:10

1 resposta

3

O shell sabe que ssh morreu e pode redefinir o terminal.

Rastreando um shell bash enquanto eu mato uma criança ssh mostra que faz várias chamadas ioctl ().

--- SIGCHLD (Child exited) @ 0 (0) ---
ioctl(255, TIOCSPGRP, [52631])          = 0
ioctl(0, TIOCGWINSZ, {ws_row=25, ws_col=147, ws_xpixel=902, ws_ypixel=329}) = 0
ioctl(0, TIOCSWINSZ, {ws_row=25, ws_col=147, ws_xpixel=902, ws_ypixel=329}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {c_iflags=0x500, c_oflags=0x5, c_cflags=0xbf, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x16\x00\x00\x00"}) = 0
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x400, c_oflags=0x5, c_cflags=0xbf, c_lflags=0x8a31, c_line=0, c_cc[VMIN]=1, c_cc[VTIME]=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x00\x12\x0f\x17\x00\x00\x00\x00"}) = 0
    
por 14.11.2015 / 08:59