Advanced Signal Management高级信号管理
#include <signal.h>
int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact);
如果act不是NULL,系统调用将更改act指定的信号的当前行为。如果oldact不是null,则调用将存储以前(或当前,如果为空)行为。
struct sigaction {
void (*sa_handler)(int); /* signal handler or action */
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask; /* signals to block */
int sa_flags; /* flags */
void (*sa_restorer)(void); /* obsolete and non-POSIX */
};
sa_handler字段指示接收信号时要采取的操作。
sa_mask字段提供一组信号,该信号在信号处理器的执行期间该系统应该阻塞。
sa_flags字段是一个零、一个或多个标志的位掩码,这些标志改变了signo给出的信号的处理。
- SA_NOCLDSTOP
如果signo是SIGCHLD,则此标志指示系统在子进程停止或恢复时不提供通知。 - SA_NOCLDWAIT
如果signo是SIGCHLD,则此标志启用自动子进程捕获:子进程在终止时不会变成僵尸,并且父节点不需要(也不能)对它们调用wait() - SA_NOMASK
同SA_NODEFER - SA_ONESHOT
通SA_RESETHEAD - SA_ONSTACK
- SA_RESTART
- SA_RESETHEAD
此标志启用“一击”模式。一旦信号处理程序返回,给定信号的行为将重置为默认值。
Sigaction()在成功时返回0。如果失败,调用将返回−1并将errno设置。
typedef struct siginfo_t {
int si_signo; /* signal number */
int si_errno; /* errno value */
int si_code; /* signal code */
pid_t si_pid; /* sending process's PID */
uid_t si_uid; /* sending process's real UID */
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 payload value */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
void *si_addr; /* memory location that caused fault */
int si_band; /* band event */
int si_fd; /* file descriptor */
};
The Wonderful World of si_code
si_code字段指示信号的原因。对于用户发送的信号,字段指示信号是如何发送的.对于内核发送的信号,字段指示发送信号的原因。
- SI_ASYNCIO
The signal was sent due to the completion of asynchronous I/O (see Chapter 5). - SI_KERNEL
The signal was raised by the kernel. - SI_MESGQ
The signal was sent due to a state change of a POSIX message queue (not covered
in this book). - SI_QUEUE
The signal was sent by sigqueue() (see the next section). - SI_TIMER
The signal was sent due to the expiration of a POSIX timer (see Chapter 11). - SI_TKILL
The signal was sent by tkill() or tgkill(). These system calls are used by threading libraries and are not covered in this book. - SI_SIGIO
The signal was sent due to the queuing of SIGIO. - SI_USER
The signal was sent by kill() or raise().
以下si_code值仅对SIGBUS有效。它们指示发生的硬件错误的类型: - BUS_ADRALN进程发生了对齐错误。
- BUS_ADRERR进程访问无效的物理地址。
- BUS_OBJERR进程导致了其他形式的硬件错误。
对于SIGCHLD,以下值标识子程序如何生成发送给其父节点的信号: - CLD_CONTINUED
子进程被停止了,但是已经恢复了。 - CLD_DUMPED
不正常地终止了子进程。 - CLD_EXITED
子程序通过EXIT()终止。 - CLD_KILLED
子进程被杀了。 - CLD_STOPPED
子进程停了下来。
-CLD_TRAPPED
子进程被困在陷阱里。
以下值仅对SIGFPE有效。它们解释了所发生的算术错误的类型: - FPE_FLTDIV
The process performed a floating-point operation that resulted in division by zero. - FPE_FLTOVF
The process performed a floating-point operation that resulted in an overflow. - FPE_FLTINV
The process performed an invalid floating-point operation. - FPE_FLTRES
The process performed a floating-point operation that yielded an inexact or invalid result. - FPE_FLTSUB
The process performed a floating-point operation that resulted in an out-of-range subscript. - FPE_FLTUND
The process performed a floating-point operation that resulted in an underflow. - FPE_INTDIV
The process performed an integer operation that resulted in division by zero. - FPE_INTOVF
The process performed an integer operation that resulted in an overflow.
以下si_code值仅对SIGILL有效。他们解释了非法执行指令的性质: - ILL_ILLADR
The process attempted to enter an illegal addressing mode. - ILL_ILLOPC
The process attempted to execute an illegal opcode. - ILL_ILLOPN
The process attempted to execute on an illegal operand. - ILL_PRVOPC
The process attempted to execute a privileged opcode. - ILL_PRVREG
The process attempted to execute on a privileged register. - ILL_ILLTRP
The process attempted to enter an illegal trap.
对于SIGPOLL,下列值标识生成信号的I/O事件: - POLL_ERR
An I/O error occurred. - POLL_HUP
The device hung up or the socket disconnected. - POLL_IN
The file has data available to read. - POLL_MSG
A message is available. - POLL_OUT
The file is capable of being written to. - POLL_PRI
The file has high-priority data available to read.
以下代码对SIGSEGV有效,描述了两种类型的无效内存访问:
- SEGV_ACCERR
The process accessed a valid region of memory in an invalid way—that is, the process violated memory-access permissions. - SEGV_MAPERR
The process accessed an invalid region of memory.
对于SIGTRAP,这两个si_code值标识陷阱命中的类型: - TRAP_BRKPT
The process hit a break point. - TRAP_TRACE
The process hit a trace trap.
Sending a Signal with a Payload
正如我们在上一节中所看到的,在SA_SIGINFO标志中注册的信号处理程序被传递一个siginfo_t参数。此结构包含一个名为si_value的字段,它是可选的有效载荷。 从信号发生器到信号接收器。
#include <signal.h>
int sigqueue (pid_t pid, int signo, const union sigval value);
union sigval {
int sival_int;
void *sival_ptr;
};
sigval value;
int ret;
value.sival_int = 404;
ret = sigqueue (1722, SIGUSR2, value);
if (ret)
perror ("sigqueue");
网友评论