如果您在Unix系統上使用Ctrl-c生成SIGINT
,則信號將發送到整個process group。
您需要使用setpgid或setsid將子進程放入不同的進程組,以便它不會接收控制終端生成的信號。
[編輯]
請務必仔細閱讀setpgid
頁面的基本原理部分。在這裏插入所有潛在的競爭條件是有點棘手的。
要保證沒有SIGINT
將交付給你的孩子的過程100%,你需要做的是這樣的:
#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);
嚴格地說,這些步驟每一個需要。如果用戶在呼叫fork
後立即點擊Ctrl-C,則必須阻止該信號。如果execl
發生在父母有時間做任何事之前發生,您必須在子女中撥打setpgid
。如果父級運行,並且有人在子級有時間做任何事情之前點擊Ctrl-C,則必須在父級中調用setpgid
。
上面的序列很笨拙,但它確實能夠處理100%的競爭條件。
什麼操作系統? – Nemo
目前我在Debian 5.0.8上進行測試 – xx77aBs