sigaction函数是设置信号处理的接口。比signal函数更健壮
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
signum指除了SIGKILL 和 SIGSTOP之外,要捕获的信号。struct sigaction *act是要安装的信号。结构题定义为:
/* Structure describing the action to be taken when a signal arrives. */
struct sigaction
{
/* Signal handler. */
#if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDED
union
{
/* Used if SA_SIGINFO is not set. */
__sighandler_t sa_handler;
/* Used if SA_SIGINFO is set. */
void (*sa_sigaction) (int, siginfo_t *, void *);
}
__sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction __sigaction_handler.sa_sigaction
#else
__sighandler_t sa_handler;
#endif
/* Additional set of signals to be blocked. */
__sigset_t sa_mask;
/* Special flags. */
int sa_flags;
/* Restore handler. */
void (*sa_restorer) (void);
};
其中,sa_handler为信号的处理函数。sa_mask设置在进程原有信号掩码基础上增加信号掩码,来过滤信号,指定哪些信号不能发送给本进程。sa_mask是信号集sigset_t类型,定义在x86_64-linux-gnu/bits/types/__sigset_t.h文件:
#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
typedef struct
{
unsigned long int __val[_SIGSET_NWORDS];
} __sigset_t;
sa_flags用来设置程序收到信号时的行为,和struct sigaction一样,在x86_64-linux-gnu/bits/sigaction.h文件中定义
关于信号集sigset_t类型,signal.h文件中定义了一些函数来操作信号集,包括:
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
拿来《linux高性能服务器编程》中的捕捉信号函数:
void addsig(int sig, void (*sig_handler)(int))
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sig_handler;
sa.sa_flags |= SA_RESTART;
sigfillset(&sa.sa_mask);
assert(sigaction(sig, &sa, NULL) != -1);
}