2022年7月6日 星期三

[Linux 系統程式設計] 關於sigaction 的 SA_RESTART flag

 

Linux 系統程式設計


 #include <signal.h>

       int sigaction(int signum, const struct sigaction *restrict act,
                     struct sigaction *restrict oldact);
   The sigaction structure is defined as something like:

           struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };

在sigaction結構中, 有一個 sa_flags 欄位可以設定為 SA_RESTART , 這代表什麼意思呢? 原文如下
SA_RESTART     
       If a blocked call to one of the following interfaces is
       interrupted by a signal handler, then the call is automatically
       restarted after the signal handler returns if the SA_RESTART flag
       was used; otherwise the call fails with the error EINTR.


例如, Socket programming 的 accept() 就是一個blocked system call,當程序停留在這個系統呼叫時, 若收到signal 則會跳到對應的signal handler去執行, 那signal handler 執行完成後呢? 

其結果可以是繼續回到原呼叫 accept() 的狀態, 就好像沒有跳出去一樣,  或者讓 accept() 直接返回, 並且返回錯誤碼為 EINTR .

OK, 那要繼續回到原呼叫 accept() 的狀態,,可以在sigaction結構的sa_flags 設定SA_RESTART , 再呼叫sigaction() 中進行設定即可

       
    struct sigaction sa;
   sa.sa_handler = &signal_handler;
   sa.sa_flags = SA_RESTART;
   sigfillset(&sa.sa_mask);
   if (sigaction(SIGUSR1, &sa, NULL) == -1) {
      fprintf(stderr,"error\n");
   }