(Ripubblicazione in unix per il suggerimento in /programming/13718394/what-should-interactive-shells-do-in-orphaned-process-groups )
La domanda breve è: cosa dovrebbe fare una shell se si trova in un gruppo di processi orfani che non possiede il tty? Ma raccomando di leggere la lunga domanda perché è divertente.
Ecco un modo divertente ed eccitante per trasformare il tuo laptop in un riscaldatore di spazio portatile, usando la tua shell preferita (a meno che tu non sia uno di quei bizzarri tcsh):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Questo fa sì che bash tocchi la CPU al 100%. zsh e fish fanno lo stesso, mentre ksh e tcsh mormorano qualcosa sul controllo del lavoro e poi si chinano, il che è un po 'meglio, ma non molto. Oh, ed è un offensore agnostico della piattaforma: OS X e Linux sono entrambi colpiti.
La mia (potenzialmente sbagliato) spiegazione è la seguente: il guscio bambino rileva che non è in primo piano: tcgetpgrp(0) != getpgrp()
. Quindi cerca di fermare se stesso: killpg(getpgrp(), SIGTTIN)
. Ma il suo gruppo di processo è rimasto orfano, perché il suo genitore (il programma C) era il leader ed è morto, e SIGTTIN
inviato a un gruppo di processi orfano è appena stato eliminato (altrimenti nulla potrebbe riavviarlo). Pertanto, la shell figlio non viene arrestata, ma è ancora in background, quindi esegue di nuovo tutto immediatamente. Risciacqua e ripeti.
La mia domanda è: come può una shell da riga di comando rilevare questo scenario e qual è la cosa giusta da fare? Ho due soluzioni, nessuna delle quali è l'ideale:
- Prova a segnalare il processo il cui pid corrisponde al nostro ID gruppo. Se fallisce
ESRCH
, significa che probabilmente siamo orfani. - Prova una lettura non bloccante di un byte da
/dev/tty
. Se fallisceEIO
, significa che probabilmente siamo orfani.
(Il nostro problema di tracciamento è https://github.com/fish-shell/fish-shell/issues/422 )
Grazie per i tuoi pensieri!