信号#3

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");
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容