sigaction 函数原型定义如下:
  int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact)
  这个系统调用的作用是改变进程接收到的指定信号的行动。
  使用这个函数需要包含头文件#include <signal.h>
  函数参数说明如下:
  signum : 说明具体信号,它可以是除了SIGKILL和SIGSTOP之外的任何有效信号值。
  act : 将要安装的signum定义信号的新行动。
  oldact: 用来保存signum定义信号的过去的行动。
  sigaction 结构体定义如下:
  struct sigaction {
  void (*sa_handler)(int);
  void (*sa_sigaction)(int, siginfo_t* , vid*);
  sigset_t sa_mask;
  int sa_flags;
  void (*sa_restorer)(void);
  };
  sa_restorer:这个成员已经过时了,不应该再被使用。POSIX不再指定sa_restorer元素。
  sa_handler:这个成员指出了和signum关联的行动,设置为SIG_DFL表示默认行动,设置为SIG_IGN表示忽略这个信号,或者设置为处理函数的指针。这个函数接收signum作为它的参数。
  sa_flags: 给出了一个可以改变信号行为的标志集合。它由以下零个或多个值的按位或形成:
  SA_NOCLDSTOP
  SA_NOCLDWAIT
  SA_NODEFER
  SA_ONSTACK
  SA_RESETHAND
  SA_RESTART
  SA_SIGINFO
  如果sa_flags被指定为SA_SIGINFO,那么sa_sigacton代替sa_handler表示signum信号处理函数。
  这个函数接收signum作为它的第一个参数,一个siginfo_t的指针作为第二参数,一个ucontext_t的指针作为第三个参数。
  sa_mask: 这个参数指明了在信号处理函数执行过程中应该被阻止的信号的mask值。此外,触发这个handler的信号应该被阻止。
  除非设置了SA_NODEFER标志。
  sa_sigaction函数中的siginfo_t 参数是一个如下定义的结构体:
  siginfo_t {
  int si_signo; /*信号编号*/
  int si_errno; /*错误号*/
  int si_code; /*信号码*/
  int si_trapno;/*导致硬件产生信号的trap号*/
  pid_t si_pid; /*发送进程ID*/
  uid_t si_uid; /*发送进程真实的用户ID*/
  int si_status; /*退出值*/
  clock_t si_utime; /*花费的用户时间*/
  clock_t si_stime; /*花费的系统时间*/
  sigval_t si_value; /*信号值*/
  int si_int ; /*POSIX.1b 信号*/
  void *si_ptr; /*POSIX.1b 信号*/
  int si_overrun
  int si_timerid
  void *si_addr
  long si_band
  int si_fd;
  short si_addr_lsb;
  }
  si_signo, si_errno和si_code为所有信号定义。
  si_erron在Linux中通常不用。
  使用kill和sigqueue发送信号要填充si_pid和si_uid。另外,使用sigqueue发送信号,信号发送者要用指定的值填充si_int和si_ptr。
  使用POSIX.1b定时器发送信号填充si_overrun和si_timerid。
  字段si_timerid是内核用来识别定时器使用的内部标识。它和timer_create
  返回定时器ID是不同的。字段si_overrun是定时器超时计数器;通过调用timer_getoverrun可以获取相同的信息。这些字段是非标准Linux扩展。
  发送消息队列通知的信号要填充si_int/si_ptr,使用sigev_value提供给mq_notify(3);
  si_pid,表示消息发送方的进程ID;
  表示消息发送者的真实用户ID。