Pokud generujete SIGINT
pomocí Ctrl +C na unixovém systému, pak je signál posílán celé skupině procesů.
Musíte použít setpgid nebo setsid k umístění podřízeného procesu do jiné skupiny procesů, takže nebude přijímat signály generované řídicím terminálem.
[Edit:]
Nezapomeňte si přečíst část ODŮVODNĚNÍ v setpgid
stránku pečlivě. Zapojit sem všechny potenciální závodní podmínky je trochu složité.
Aby bylo 100% zaručeno, že žádné SIGINT
bude doručen vašemu dítěti, musíte udělat něco takového:
#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);
Přísně vzato, každý z těchto kroků je nezbytný. V případě, že uživatel stiskne Ctrl, musíte signál zablokovat +C hned po zavolání na fork
. Musíte zavolat setpgid
v dítěti v případě execl
stane dříve, než rodič stihne cokoliv udělat. Musíte zavolat na setpgid
v nadřazeném v případě rodič běží a někdo stiskne Ctrl +C před dítětem má čas na cokoliv.
Výše uvedená sekvence je neohrabaná, ale zvládne 100 % podmínek závodu.