Linux Signal (4): sigaction

来源:互联网 发布:win7部分软件显示乱码 编辑:程序博客网 时间:2024/05/20 07:17

sigaction函数是用作检查/修改与指定信号相关联的处理动作. 在UNIX早期版本中使用signal, 后来改用了sigaction, 可见它的功能比signal要强大. 另外, signal函数也是可以用sigaction实现的.

1. sigaction原型:

#include <signal.h>

int sigaction(int signo, const struct sigaction *restrict act,
                               struct sigaction *restrict oact);

成功则返回0, 出错则返回-1.
首先说一下struct sigaction这个结构:

struct sigaction
{
    void (*sa_handler)(int); /* addr of signal handler or
                                SIG_IGN, SIG_DFL */
    sigset_t sa_mask;        /* additional signals to block */
    int sa_flags;            /* signal options */

    /* alternate handler */
    void (*sa_sigaction)(int, siginfo_t *, void *);
};
sa_hanlder: 一个带有int参数的函数指针, 或者SIG_IGN(忽略), 或者SIG_DFL(默认).
sa_mask: 信号屏蔽字(集). 当该信号处理函数返回时, 屏蔽字恢复.
sa_sigaction: 替代的信号处理程序, 当使用了SA_SIGINFO标志时, 使用该信号处理程序.

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启
SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针


对于sa_flags和siginfo结构, 具体参考《unix环境高级编程》262页.

 

2.实例:

下面的代码是用sigaction实现signal函数:

 

#include "apue.h"
Sigfunc *signal(int signo,Sigfunc *func)
{
  struct sigaction act;//新的信号关联信息

  struct sigaction oact;//老的信号关联信息

  act.sa_handler = func;//新的信号处理函数

  sigemptyset(&act.sa_mask);//初始化屏蔽字

  act.sa_flags = 0;//初始化flags

  if (signo == SIGALRM) {//不会重启动
#ifdef SA_INTERRUPT
     act.sa_flags |= SA_INERRUPT;
#endif
  } else { //重启动
#ifdef SA_RESTART
     act.sa_flags |= SA_RESTART;
#endif
  }
  if (sigaction(signo, &act, &oact) < 0)//新老交换
      return(SIG_ERR);
   return (oact.sa_handler);
}