• linux 信号处理过程中 行为的标志意义


    http://www.ej38.com/showinfo/linux-193735.html
     

    功能描述: 
    处理信号。既可用于设定对任意信号的处理方式,也可用于检验该信号的目前预设处置方式。
     
      
    用法: 
    #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;
    }

  • 相关阅读:
    OD 实验(十三)
    第一个 Windows 界面程序
    C 语言
    C 语言
    OD 实验(十二)
    PowerShell 常用命令
    OD 实验(十一)
    OD 实验(十)
    redis
    memcached缓存系统
  • 原文地址:https://www.cnblogs.com/leaven/p/1917285.html
Copyright © 2020-2023  润新知