系統呼叫 sigaction() 用來改變接收到特定 signal 時執行的動作。
#include <signal.h>
int sigaction(
int signum, // signal 號碼,除了 SIGKILL 和 SIGSTOP
const struct sigaction *act, // 不是 NULL 時安裝新動作
struct sigaction *oldact); // 不是 NULL 時存舊動作
struct sigaction {
void (*sa_handler)(int signum);
void (*sa_sigaction)(int signum, siginfo_t *, void *ucontext);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
- sa_handler 和 sa_sigaction 指定相關的執行動作,sa_flags 有 SA_SIGINFO 用後者否則用前者,有些架構 sa_handler 和 sa_sigaction 是 union。
- sa_handler 可以是 SIG_DFL 用預設動作,SIG_IGN 忽略這個 signal,或指到只收 signal number 的 signal handling 函數。
- sa_sigaction 接收 3 個的引數,signum 是 signal number,siginfo_t 是包含 signal 進一步資訊的 structure,ucontext。
- sa_mask 指定 siganl 發生執行動作時,要遮蔽的 signal。此外,驅動的 signal 也會遮蔽,除非使用 SA_NODEFER flag。
- sa_flags 指定 a set of flags which modify the behavior of the signal. It is formed by the bitwise OR of zero or more of the following:
- SA_NOCLDSTOP:
- SA_NOCLDWAIT:
- SA_NODEFER:
- SA_ONSTACK
- SA_RESETHAND
- SA_RESTART
- SA_RESTORER
- SA_SIGINFO
- The sa_restorer field is not intended for application use. (POSIX does not specify a sa_restorer field.) Some further details of the purpose of this field can be found in sigreturn(2).
void (*sa_sigaction)(int sig, siginfo_t *info, void *ucontext); 有三個引數,sig 是 singal number,siginfo_t 資料結構如下:
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value,在 Linux 一般不使用 */
int si_code; /* Signal code */
int si_trapno; /* Trap number that caused hardware-generated signal
(unused on most architectures) */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count; POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address (Linux 2.6.32+) */
void *si_lower; /* Lower bound when address violation occurred (Linux 3.19+) */
void *si_upper; /* Upper bound when address violation occurred (Linux 3.19+) */
int si_pkey; /* Protection key on PTE that caused fault (Linux 4.6+) */
void *si_call_addr; /* Address of system call instruction (Linux 3.5+) */
int si_syscall; /* Number of attempted system call (Linux 3.5+) */
unsigned int si_arch; /* Architecture of attempted system call (Linux 3.5+) */
}
ucontext 其實是指到 ucontext_t 結構 (為什麼要 cast to void *?),包含 signal context information that was saved on the user-space stack by the kernel; for details, see sigreturn(2). Further information about the ucontext_t structure can be found in getcontext(3).
sigaction, rt_sigaction - examine and change a signal action
參考
- man sigaction
- man sigreturn
沒有留言:
張貼留言