(Postando novamente em unix, de acordo com a sugestão em /programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groups )
A pergunta curta é: o que um shell deve fazer se estiver em um grupo de processos órfãos que não possui o tty? Mas recomendo a leitura da longa pergunta porque é divertida.
Aqui está uma maneira divertida e emocionante de transformar seu laptop em um aquecedor de ambiente portátil, usando seu shell favorito (a menos que você seja um desses esquisitos do tcsh):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Isso faz com que o bash atrele a CPU a 100%. O zsh e o fish fazem o mesmo, enquanto o ksh e o tcsh murmuram algo sobre o controle do trabalho e depois caem, o que é um pouco melhor, mas não muito. Ah, e é um infrator independente de plataforma: OS X e Linux são afetados.
Meu (potencialmente errado) explicação é a seguinte: o shell criança detecta que não está em primeiro plano: tcgetpgrp(0) != getpgrp()
. Por isso, tenta impedi-se: killpg(getpgrp(), SIGTTIN)
. Mas seu grupo de processos é órfão, porque seu pai (o programa C) foi o líder e morreu, e SIGTTIN
enviado para um grupo de processos órfão é descartado (caso contrário, nada poderia iniciá-lo novamente). Portanto, o shell filho não é parado, mas ainda está em segundo plano, e faz tudo de novo imediatamente. Enxague e repita.
Minha pergunta é: como um shell de linha de comando pode detectar esse cenário e qual é a coisa certa a fazer? Eu tenho duas soluções, nenhuma das quais é ideal:
- Tente sinalizar o processo cujo pid corresponde ao nosso ID de grupo. Se isso falhar
ESRCH
, significa que provavelmente somos órfãos. - Tente uma leitura sem bloqueio de um byte
/dev/tty
. Se isso falharEIO
, significa que provavelmente somos órfãos.
(Nosso problema de rastreamento é https://github.com/fish-shell/fish-shell/issues/422 )
Obrigado por seus pensamentos!