sigaction函數詳解

來源:互聯網
上載者:User

【sigaction系統調用】
 
功能描述:
處理訊號。既可用於設定對任意訊號的處理方式,也可用於檢驗該訊號的目前預設處置方式。
 
 
用法:
#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
      
 
參數:
signum:除了SIGKILL和SIGSTOP之外的其它任何訊號編碼。
act:如果值非NULL,將安裝為signum關聯訊號的新處理方式。
oldact:如果值非NULL,儲存以前對signum關聯訊號的處理方式。

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共用一個聯合體(union),所以不要同時指定兩個欄位的值。

sa_restorer欄位已淘汰,不應該再被使用。

sa_handler欄位指定與signum訊號關聯的行為,可能是SIG_DFL預設行為,SIG_IGN忽略接送到的訊號,或者一個訊號處理函數指標。這個函數以一個訊號編碼作為它的唯一參數。

如果sa_flags中存在SA_SIGINFO標誌,那麼sa_sigaction將作為signum訊號的處理函數。這個函數的第一參數是訊號編碼,第二參數是siginfo_t結構的指標,第三參數是ucontext_t結構指標(造型為void *)。

sa_mask指定訊號處理函數執行的過程中應被阻塞的訊號。另外,除了SA_NODEFER標誌被指定外,觸發訊號處理函數執行的那個訊號也會被阻塞。

sa_flags指定一系列用於修改訊號處理過程行為的標誌,由下面的0個或多個標誌通過or運算組合而成:
 SA_NOCLDSTOP //此標誌為on時,假如signum的值是SIGCHLD,則在子進程停止或恢複執行時不會傳訊號給調用本系統調用的進程。
 SA_NOCLDWAIT //此標誌為on時,當調用此系統調用的進程之子進程終止時,系統不會建立zombie進程。
 SA_RESETHAND //此標誌為on時,訊號處理函數接收到訊號後,會先將對訊號處理的方式設為預設方式,而且當函數處理該訊號時,後來發生的訊號將不會被阻塞。
 SA_ONSTACK //如果利用sigaltstack()建立訊號專用堆棧,則此標誌會把所有訊號送往該堆棧。
 SA_RESTART //此標誌為on時,核心會自動重啟訊號中斷的系統調用,否則返回EINTR錯誤值。
 SA_NODEFER //當此標誌為on時,在訊號處理函數處置訊號的時段中,核心程式不會把這個間隙中產生的訊號阻塞。
 SA_SIGINFO //此標誌為on時,指定訊號處理函數需要三個參數,所以應使用sa_sigaction替代sa_handler。

sa_sigaction第二個參數siginfo_t結構的原型如下:

siginfo_t {
    int      si_signo;  /* Signal number */
    int      si_errno;  /* An errno value */
    int      si_code;   /* Signal code */
    pid_t    si_pid;    /* Sending process ID */
    uid_t    si_uid;    /* Real user ID of sending process */
    int      si_status; /* Exit value or signal */
    clock_t  si_utime;  /* User time consumed */
    clock_t  si_stime;  /* System time consumed */
    sigval_t si_value;  /* Signal value */
    int      si_int;    /* POSIX.1b signal */
    void *   si_ptr;    /* POSIX.1b signal */
    void *   si_addr;   /* Memory location which caused fault */
    int      si_band;   /* Band event */
    int      si_fd;     /* File descriptor */
}

開頭的三個欄位si_signo,si_errno 和
si_code為所有訊號使用(Linux中si_signo不被使用),結構的剩下部分可看作聯合體,所以應該唯讀取對給定訊號有意義的欄位。
POSIX.1b訊號和SIGCHLD填寫si_pid 和 si_uid兩個欄位。SIGCHLD訊號同時填寫si_status,
si_utime 和 si_stime。si_int 和
si_ptr為POSIX.1b訊號寄件者而指定。SIGILL,SIGFPE,SIGSEGV 和 SIGBUS用出錯地址填寫si_addr欄位。

 

si_code指示訊號發送的原因。它是一個值,而不是位元遮罩。下面表中列出任何訊號的可能值:

    +-------------------------------------------------------------------+
       |                             si_code                               |
       +-----------+-------------------------------------------------------+
       |Value      | Signal origin                                         |
       +-----------+-------------------------------------------------------+
       |SI_USER    | kill(), sigsend(), or raise()                         |
       +-----------+-------------------------------------------------------+
       |SI_KERNEL  | The kernel                                            |
       +-----------+-------------------------------------------------------+
       |SI_QUEUE   | sigqueue()                                            |
       +-----------+-------------------------------------------------------+
       |SI_TIMER   | POSIX timer expired                                   |
       +-----------+-------------------------------------------------------+
       |SI_MESGQ   | POSIX message queue state changed (since Linux 2.6.6) |
       +-----------+-------------------------------------------------------+
       |SI_ASYNCIO | AIO completed                                         |
       +-----------+-------------------------------------------------------+
       |SI_SIGIO   | queued SIGIO                                          |
       +-----------+-------------------------------------------------------+
       |SI_TKILL   | tkill() or tgkill() (since Linux 2.4.19)              |
       +-----------+-------------------------------------------------------+

       +-------------------------------------+
       |               SIGILL                |
       +-----------+-------------------------+
       |ILL_ILLOPC | illegal opcode          |
       +-----------+-------------------------+
       |ILL_ILLOPN | illegal operand         |
       +-----------+-------------------------+
       |ILL_ILLADR | illegal addressing mode |
       +-----------+-------------------------+
       |ILL_ILLTRP | illegal trap            |
       +-----------+-------------------------+
       |ILL_PRVOPC | privileged opcode       |
       +-----------+-------------------------+
       |ILL_PRVREG | privileged register     |
       +-----------+-------------------------+
       |ILL_COPROC | coprocessor error       |
       +-----------+-------------------------+
       |ILL_BADSTK | internal stack error    |
       +-----------+-------------------------+

       +----------------------------------------------+
       |                   SIGFPE                     |
       +-----------+----------------------------------+
       |FPE_INTDIV | integer divide by zero           |
       +-----------+----------------------------------+
       |FPE_INTOVF | integer overflow                 |
       +-----------+----------------------------------+
       |FPE_FLTDIV | floating point divide by zero    |
       +-----------+----------------------------------+
       |FPE_FLTOVF | floating point overflow          |
       +-----------+----------------------------------+
       |FPE_FLTUND | floating point underflow         |
       +-----------+----------------------------------+
       |FPE_FLTRES | floating point inexact result    |
       +-----------+----------------------------------+
       |FPE_FLTINV | floating point invalid operation |
       +-----------+----------------------------------+
       |FPE_FLTSUB | subscript out of range           |
       +-----------+----------------------------------+

       +----------------------------------------------------+
       |                      SIGSEGV                       |
       +------------+---------------------------------------+
       |SEGV_MAPERR | address not mapped to object          |
       +------------+---------------------------------------+
       |SEGV_ACCERR | invalid permissions for mapped object |
       +------------+---------------------------------------+

       +--------------------------------------------+
       |                  SIGBUS                    |
       +-----------+--------------------------------+
       |BUS_ADRALN | invalid address alignment      |
       +-----------+--------------------------------+
       |BUS_ADRERR | non-existent physical address  |
       +-----------+--------------------------------+
       |BUS_OBJERR | object specific hardware error |
       +-----------+--------------------------------+

       +--------------------------------+
       |            SIGTRAP             |
       +-----------+--------------------+
       |TRAP_BRKPT | process breakpoint |
       +-----------+--------------------+
       |TRAP_TRACE | process trace trap |
       +-----------+--------------------+

       +----------------------------------------------------------------+
       |                            SIGCHLD                             |
       +--------------+-------------------------------------------------+
       |CLD_EXITED    | child has exited                                |
       +--------------+-------------------------------------------------+
       |CLD_KILLED    | child was killed                                |
       +--------------+-------------------------------------------------+
       |CLD_DUMPED    | child terminated abnormally                     |
       +--------------+-------------------------------------------------+
       |CLD_TRAPPED   | traced child has trapped                        |
       +--------------+-------------------------------------------------+
       |CLD_STOPPED   | child has stopped                               |
       +--------------+-------------------------------------------------+
       |CLD_CONTINUED | stopped child has continued (since Linux 2.6.9) |
       +--------------+-------------------------------------------------+

       +-----------------------------------------+
       |                SIGPOLL                  |
       +---------+-------------------------------+
       |POLL_IN  | data input available          |
       +---------+-------------------------------+
       |POLL_OUT | output buffers available      |
       +---------+-------------------------------+
       |POLL_MSG | input message available       |
       +---------+-------------------------------+
       |POLL_ERR | i/o error                     |
       +---------+-------------------------------+
       |POLL_PRI | high priority input available |
       +---------+-------------------------------+
       |POLL_HUP | device disconnected           |
       +---------+-------------------------------+

返回說明:
成功執行時,返回0。失敗返回-1,errno被設為以下的某個值
EFAULT:act或oldact指向的記憶體區並非有效進程地址空間
EINVAL:指定無效的訊號,或者嘗試改變SIGKILL 或  SIGSTOP訊號的處理方式

 


 





 
例子:

2007-10-02 13:13

 #include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>

void sig_handler(int);
void count_prime(int);

int main(int argc, char **argv)
{
 struct sigaction nact;
 int i;
 
 if(argc < 2) {
  printf("Usage: argv[0] <number> /n/n");
  exit(1);
 }
 
 i = atoi(argv[1]);
 nact.sa_handler = sig_handler;
 nact.sa_flags = SA_RESTART;
 
 sigaction(SIGINT, &nact, NULL);
 printf("****************************************************************************/n");
 count_prime(i);
 printf("****************************************************************************/n");

 exit(0);

}

void sig_handler(int sig){
 printf("SIGINT is caught/n");

 return;
}

void count_prime(int num)
{
 static int j, k = 2;
 static unsigned int total = 0;

 puts("counting ...");
 
 for(; k <= num; ++k) {
  j = 2;
  
  while(k % j != 0)
   ++j;
  
  if(j == k) {
   printf("%d/t", k);
   
   if(total % 10 == 0)
    printf("/n");
  
   ++total;
  }
 }
 
 printf("/n");
 printf("Total number of primes between 0~%d is %d /n", num, total);
 return;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.