信号之sigaction函数


sigaction函数的功能是检查或修改与指定信号相关联的处理动作(或同时执行这两种操作)。

#include <signal.h>
 sigaction(  signo,   sigaction *restrict act,  sigaction *-

其中,参数signo是要检测或修改其具体动作的信号编号。若act指针非空,则要修改其动作。如果oact指针非空,则系统经由oact指针返回该信号的上一个动作。此函数使用下列结构:

    (*sa_handler)();    
        sa_flags;               

    
        (*sa_sigaction)(, siginfo_t *,  *

当更改信号动作时,如果sa_handler字段包含一个信号捕捉函数的地址(与常量SIG_IGN或SIG_DFL相对),则sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加到进程的信号屏蔽字中。。这样,在调用信号处理程序时就能阻塞某些信号。因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号的处理结束为止。

一旦对给定的信号设置了一个动作,那么在调用sigaction显式地改变它之前,该设置就一直有效。(早期版本并非如此,而是:

act结构的sa_flags字段指定对信号进行处理的各个选项。

                                                        表10-5 处理每个信号的选项标志(sa_flags)

sa_sigaction字段是一个替代的信号处理程序,当在sigaction结构中使用了SA_SIGINFO标志时,使用该信号处理程序。对于sa_sigaction字段和sa_handler字段这两者,其实现可能使用同一存储区,所以应用程序只能一次使用这两个字段中的一个。

通常,按下列方式调用信号处理程序:

 handler( signo);

但是,如果设置了SA_SIGINFO标志,那么按下列方式调用信号处理程序:

 handler( signo, siginfo_t *info,  *context);

siginfo_t结构包含了信号产生原因的有关信息。该结构的大致样式如下所示:

      si_signo;        
          si_errno;        
          si_code;         
        *si_addr;         
          si_status;       
         si_band;         
    

 

各种信号的si_code值(包括上面的相关数据结构和标志选项),可通过man sigaction命令进行查看。

若信号是SIGCHLD,则将设置si_pid、si_status和si_uid字段。

若信号是SIGILL或SIGSEGV,则si_addr包含造成故障的根源地址,尽管该地址可能并不准确。

若信号是SIGPOLL,那么si_band字段将包含STREAMS消息的优先级(priority band),该消息产生POLL_IN、POLL_OUT或POLL_MSG事件。

si_errno字段包含错误编号,它对应于引发信号产生的条件,并由实现定义。

信号处理程序的context参数是无类型指针,它可被强制转换为ucntext_t结构类型,用于标识信号传递时进程的上下文。

 

 实例:signal函数

现在用sigaction实现signal函数。很多平台都是这样做的。

程序清单10-12 用sigaction实现signal函数

#include 

* signo, Sigfunc *=&= (signo ==|=|=(sigaction(signo, &act, &oact) < 

注意,必须用sigemptyset函数初始化act结构的sa_mask成员。不能保证:act.sa_mask = 0;会做同样的事情。

对除SIGALRM以外的所有信号,我们都有尝试设置SA_RESTART标志,于是被这些信号中断的系统调用都能自动重启动。不希望重启动由SIGALRM信号中断的系统调用的原因是:我们希望对I/O操作可以设置时间限制。

实例:signal_intr函数

程序清单10-13是signal函数的另一种版本,它力图阻止任何被中断的系统调用重启动。

程序清单10-13 signal_intr函数

#include * signo, Sigfunc *=&= |=
    (sigaction(signo, &act, &oact) < 

 

如果系统定义了SA_INTERRUPT标志,那么为了提高可移植性,我们在sa_flags中增加该标志,这样也就阻止了被中断的系统调用重启动。

 

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

相关内容