sigaction 函数原型定义如下:
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact)
这个系统调用的作用是改变进程接收到的指定信号的行动。
使用这个函数需要包含头文件#include <signal.h>
函数参数说明如下:
(1) signum : 说明具体信号,它可以是除了SIGKILL和SIGSTOP之外的任何有效信号值。
(2) act : 将要安装的signum定义信号的新行动。
(3) oldact: 用来保存signum定义信号的过去的行动。
(4) 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。