sigaction
Function Prototype
int sigaction(int signo,
const struct sigaction *act,
struct sigaction *oact);signo:要處理的 signal 編號act:非 NULL 則用新的 handler 替換舊的oact:非 NULL 則會將舊的 handler 存在這裡
struct sigaction {
void (*sa_handler)(int); // 傳統的 handler 函數
sigset_t sa_mask; // 要額外阻擋的 signal 集合
int sa_flags; // 各種旗標設定
void (*sa_sigaction)(int, siginfo_t *, void *); // 進階 handler
};sa_handler:跟 signal (unreliable) 一樣的 signal handlersa_mask:在執行 signal handler 要 block 哪些 signalsa_flags:各種 flag 設定sa_sigaction:更進階的 signal handler
Feature
Signal Mask
- 在 signal handler 執行時可以選擇要 block 哪些 signal
- 正在處理的那個 signal 本身也自動會被 block
- handler 執行結束後,這個 signal mask 才會失效
Handler 持續有效
- 與 signal (unreliable) 版本的 signal handler 一次有效不同,用
sigaction設定的 handler 會持續有效直到我們再次將其替換掉
Flags
SA_INTERRUPT
Slow system call 根據使用的 OS 在被 signal interrupt 之後會自動重啟,設定此 flag 可以讓 slow system call 不會自動重啟
SA_NOCLDWAIT
此 flag 專門用來處理 SIGCHLD,可以用來防止 zombie process 的產生
當使用此 flag:
- child process 終止後不會產生 zombie process
- parent process 呼叫 wait 後會 block 直到所有 child 終止,然後返回 -1 並設定 errno 為
ECHILD
SA_NODEFER
在沒有設定 SA_NODEFER 時:
- signal handler 執行時,觸發 handler 的 signal 會自動被 block
- 這可以避免同一個 signal 重複進入 handler
設定 SA_NODEFER 後:
- signal handler 執行時觸發的 signal 就不會被自動阻擋
- 這種 behavior 和 signal (unreliable) 一樣
SA_RESETHAND
讓 signal handler 被觸發一次後就會重置成 default action
SA_RESTART
跟 SA_INTERRUPT 相反,設定後 slow system call 會重啟
SA_SIGINFO
使用進階的 signal handler (sa_sigaction)