Linux sigaction函數捕獲鍵盤信號

sigaction 結構體

下面的結構體需要傳到sigaction函數內使用的

struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
}
  • sa_handler: 函數指針,此信號的處理函數
  • sa_sigaction:帶有附加參數的信號處理函數指針(兩個信號處理函數指針只能二選一)
  • sa_mask:在處理該信號時暫時將sa_mask 指定的信號集擱置,sigemptyset(&act.sa_mask)置空
  • sa_flags:
    SA_RESETHAND:當調用信號處理函數時,將信號的處理函數重置爲缺省值SIG_DFL(比如我設置了Ctr+C的信號處理函數循環打印,如果設置SA_RESETHAND,當我第一次按Ctr+C,調用信號處理函數進行循環打印,此時已經將信號的處理函數重新設置爲系統默認,當我第二次再按Ctr+C的時候便退出程序-系統缺省狀態處理函數)
    SA_NODEFER :一般情況下, 當信號處理函數運行時,內核將阻塞該給定信號(不會阻塞其他信號,比如SIGQUIT照樣可以直接結束程序)。但是如果設置了 SA_NODEFER標記, 那麼在該信號處理函數運行時,內核將不會阻塞該信號(將前一個擱置,執行新的,新的執行完了再執行舊的);
    SA_RESTART:使被信號打斷的系統調用自動重新發起.
  • sa_restorer:廢棄的成員,不要使用

調試程序

void show_handler(int sig)
{
    printf("I got signal %d\n", sig);
    int i;
    for(i = 0; i < 5; i++) 
   {
        printf("i = %d\n", i);
        sleep(1);
    }
}
 
int main(void)
{
    int i = 0;
    struct sigaction act;
    act.sa_handler = show_handler;
    sigaddset(&act.sa_mask, SIGQUIT);   
    //sigemptyset(&act.sa_mask);
    act.sa_flags = SA_RESETHAND | SA_NODEFER; 
    //act.sa_flags = 0;                      
 
    sigaction(SIGINT, &act, NULL);
    while(1) 
   {
        sleep(1);
        printf("sleeping %d\n", i);
        i++;
    }
}
 

sigaciton 函數

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
  • signum:指出要捕獲的信號類型(可以用kill -l 或者man sigaction查看):

常用:

編號 按鍵 信號類型
2 Ctr+C SIGINT
  • act:參數指定新的信號處理方式(傳遞的是上面結構體)
  • oldact:返回舊的 struct sigaction 結構體,傳出參數,舊的處理方式
  • 返回值:0 表示成功,-1 表示有錯誤發生。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章