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);
}