Se stai generando il file SIGINT
con Ctrl +C su un sistema Unix, il segnale viene inviato all'intero gruppo di processi.
Devi utilizzare setpgid o setsid per inserire il processo figlio in un gruppo di processi diverso in modo che non riceva i segnali generati dal terminale di controllo.
[Modifica:]
Assicurati di leggere la sezione RAZIONALE del setpgid
pagina con attenzione. È un po' complicato collegare qui tutte le potenziali condizioni di gara.
Per garantire al 100% che nessun SIGINT
verrà consegnato al tuo processo figlio, devi fare qualcosa del genere:
#define CHECK(x) if(!(x)) { perror(#x " failed"); abort(); /* or whatever */ }
/* Block SIGINT. */
sigset_t mask, omask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
CHECK(sigprocmask(SIG_BLOCK, &mask, &omask) == 0);
/* Spawn child. */
pid_t child_pid = fork();
CHECK(child_pid >= 0);
if (child_pid == 0) {
/* Child */
CHECK(setpgid(0, 0) == 0);
execl(...);
abort();
}
/* Parent */
if (setpgid(child_pid, child_pid) < 0 && errno != EACCES)
abort(); /* or whatever */
/* Unblock SIGINT */
CHECK(sigprocmask(SIG_SETMASK, &omask, NULL) == 0);
A rigor di termini, ognuno di questi passaggi è necessario. Devi bloccare il segnale nel caso in cui l'utente prema Ctrl +C subito dopo la chiamata a fork
. Devi chiamare setpgid
nel bambino nel caso in cui il execl
accade prima che il genitore abbia il tempo di fare qualsiasi cosa. Devi chiamare setpgid
nel genitore nel caso in cui il genitore corre e qualcuno preme Ctrl +C prima del bambino ha tempo per fare qualsiasi cosa.
La sequenza sopra è goffa, ma gestisce il 100% delle condizioni di gara.