Quando inicio um emulador de terminal (por exemplo, qterminal), ele inicia o shell padrão (por exemplo, bash). E quando eu saio do terminal (por exemplo, clicando no botão x ou matando o terminal), o shell também sai. Não permanece nenhum processo do shell. Gostaria de saber como esse mecanismo é implementado.
A princípio, suspeitei que o terminal enviasse algum sinal para o shell. Então eu prendo SIGQUIT, SIGINT, SIGTERM, SIGHUP no shell, mas nenhum sinal foi capturado. Eu não tenho nenhuma idéia além do sinal.
Pode depender do terminal e do shell e talvez do sistema operacional. Por favor, diga-me qualquer informação sobre esta situação.
Normalmente o terminal envia um hangup (SIGHUP) para o processo. Além disso, quando o terminal fecha sua extremidade 'mestre' do pty, certos processos anexados a ele também recebem automaticamente um SIGHUP do kernel – se o terminal enviou um ou não.
Embora o sinal do kernel não seja enviado para todos os processos que têm o pty como terminal de controle - não verifiquei exatamente, mas acho que é entregue especificamente apenas para o "pgroup de primeiro plano", basicamente o mesmo que com SIGINT/ SIGQUIT de Ctrl+C/Ctrl+\.
Os próprios shells, como o Bash, já possuem um manipulador para SIGHUP que fornece SIGHUPs adicionais para todos os trabalhos em segundo plano gerenciados pelo shell (ignorando aqueles que foram
disown
ed), por exemplo, asleep 1h &
será SIGHUP'd pelo Bash quando o último estiver prestes a sair devido à sua próprio SIGHUP recebido.Por exemplo, ao fechar o terminal de forma limpa:
E ao usar um depurador para emitir
close(ptmx_fd)
do processo do terminal:Finalmente, quando o pty é fechado, o shell (ou outro programa em primeiro plano) receberá EOF ao tentar ler a partir dele (ou seja
read()
, retornará 0), que será tratado como se você pressionasse Ctrl + D - isso também geralmente fazer com que o programa saia, embora é claro que ele possa ignorar o EOF (eu vi um programa específico entrar em um loop infinito neste caso, quando decidiu ignorar o SIGHUP e o EOF).É muito possível que o shell saia no EOF antes de chegar ao seu manipulador SIGHUP personalizado. Por exemplo, posso reproduzir seus resultados no Bash no GNOME Terminal (
trap ... SIGHUP
sem ser chamado), no entanto, se eu definir adicionalmenteIGNOREEOF=1
o Bash para não sair no EOF, a armadilha SIGHUP personalizada será realmente invocada.Uma armadilha personalizada também substitui o comportamento padrão de "sair no SIGHUP" do Bash. Então, quando eu digo ao Bash para ignorar EOFs e interceptar SIGHUP, ele continua tentando imprimir um prompt para um tty inexistente - a saída 'strace' mostra ele chamando todos os meus ganchos PROMPT_COMMAND usuais, tentando escrever o prompt para stdout, obtendo EIO , em seguida, tentando escrever mensagens de erro para stderr, obtendo EIO a partir disso, e somente depois ele decide que basta e sai.