(Volver a publicar en Unix según la sugerencia en /programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groups )
La pregunta corta es, ¿qué debe hacer un shell si está en un grupo de proceso huérfano que no posee el tty? Pero recomiendo leer la larga pregunta porque es divertida.
Aquí hay una manera divertida y emocionante de convertir su computadora portátil en un calentador de espacio portátil, utilizando su carcasa favorita (a menos que sea uno de esos bichos raros):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Esto hace que bash fije la CPU al 100%. zsh y fish hacen lo mismo, mientras que ksh y tcsh murmuran algo sobre el control del trabajo y luego se desploman, lo cual es un poco mejor, pero no mucho. Ah, y es un delincuente agnóstico de plataforma: OS X y Linux están afectados.
Mi (potencialmente mal) explicación es la siguiente: la cáscara niño detecta que no está en primer plano: tcgetpgrp(0) != getpgrp()
. Por lo tanto, trata de detener a sí mismo: killpg(getpgrp(), SIGTTIN)
. Pero su grupo de proceso es huérfano, porque su padre (el programa C) fue el líder y murió, y se lo SIGTTIN
envió a un grupo de proceso huérfano (de lo contrario, nada podría iniciarlo de nuevo). Por lo tanto, el shell hijo no se detiene, pero todavía está en segundo plano, por lo que lo hace todo de nuevo, de inmediato. Enjuague y repita.
Mi pregunta es, ¿cómo puede un shell de línea de comando detectar este escenario y qué es lo que debe hacer? Tengo dos soluciones, ninguna de las cuales es ideal:
- Intente señalar el proceso cuyo pid coincide con nuestra ID de grupo. Si eso falla
ESRCH
, significa que probablemente estamos huérfanos. - Intente una lectura sin bloqueo de un byte de
/dev/tty
. Si eso fallaEIO
, significa que probablemente estamos huérfanos.
(Nuestro problema para rastrear esto es https://github.com/fish-shell/fish-shell/issues/422 )
Gracias por tus pensamientos!