Wenn Sie den SIGINT
generieren mit Strg +C auf einem Unix-System wird das Signal an die gesamte Prozessgruppe gesendet.
Sie müssen setpgid oder setsid verwenden, um den untergeordneten Prozess in eine andere Prozessgruppe zu stecken, damit er die vom steuernden Terminal generierten Signale nicht empfängt.
[Bearbeiten:]
Lesen Sie unbedingt den Abschnitt BEGRÜNDUNG von setpgid
Seite sorgfältig. Es ist etwas knifflig, hier alle potenziellen Rennbedingungen einzufügen.
Um 100% zu garantieren, dass kein SIGINT
an Ihren untergeordneten Prozess geliefert wird, müssen Sie etwa so vorgehen:
#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);
Genau genommen ist jeder dieser Schritte notwendig. Sie müssen das Signal blockieren, falls der Benutzer Strg drückt +C direkt nach dem Aufruf von fork
. Sie müssen setpgid
anrufen im Kindfall der execl
passiert, bevor die Eltern Zeit haben, etwas zu tun. Sie müssen setpgid
anrufen im Elternteil im Fall des Elternteils läuft und jemand drückt Strg +C vor dem Kind hat Zeit, alles zu tun.
Die obige Sequenz ist ungeschickt, aber sie bewältigt 100 % der Rennbedingungen.