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 handler
  • sa_mask:在執行 signal handler 要 block 哪些 signal
  • sa_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)