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

#include <signal.h>
int sigaction( int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);
返回值:若成功则返回0,若出错则返回-

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

struct sigaction {
void (*sa_handler)(int); /* addr of signal handler, or SIG_IGN, or SIG_DFL */
sigset_t sa_mask; /* additional signals to block */
int sa_flags; /* signal options */ /* alternate handler */
void (*sa_sigaction)(int, siginfo_t *, void *);
};

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

一旦对给定的信号设置了一个动作,那么在调用sigaction显式地改变它之前,该设置就一直有效。(早期版本并非如此,而是:在进程每次接到信号对其进行处理时,随即将该信号动作复位为默认值。见http://www.cnblogs.com/nufangrensheng/p/3515035.html)

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

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

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

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

void handler(int signo);

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

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

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

struct siginfo {
int si_signo; /* signal number */
int si_errno; /* if nonzero, errno value from <errno.h> */
int si_code; /* additional info (depends on signal) */
pid_t si_pid; /* sending process ID */
uid_t si_uid; /* sending process real user ID */
void *si_addr; /* address that caused the fault */
int si_status; /* exit value or signal number */
long si_band; /* band number for SIGPOLL */
/* possibly other fields also */
};

各种信号的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 "apue.h"

/* Reliable version of signal(), using POSIX sigaction(). */
Sigfunc *
signal(int signo, Sigfunc *func)
{
struct sigaction act, oact; act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = ;
if(signo == SIGALRM)
{
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}
else
{
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART;
#endif
}
if(sigaction(signo, &act, &oact) < )
return(SIG_ERR);
return(oact.sa_handler);
}

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

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

实例:signal_intr函数

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

程序清单10-13 signal_intr函数

#include "apue.h"

Sigfunc *
signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact; act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = ;
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
if(sigaction(signo, &act, &oact) < )
return(SIG_ERR);
return(oact.sa_handler);
}

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

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

信号之sigaction函数的更多相关文章

  1. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

  2. Linux 信号(三)—— sigaction 函数

    ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 #include <signal.h> int sigaction(int signo, con ...

  3. 信号的捕捉与sigaction函数

    一.内核如何实现信号的捕捉 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号.由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 1. 用户程序注册了SI ...

  4. 第二十五篇:使用 sigaction 函数实现可靠信号

    前言 在前文中,讲述了一个可靠信号的示例.它分成几个步骤组成( 请参考前文 ).在 Linux 系统编程中,有个方法可以将这些步骤给集成起来,让我们使用起来更加的方便. 那就是调用 sigaction ...

  5. 使用 sigaction 函数实现可靠信号

    前言 在前文中,讲述了一个可靠信号的示例.它分成几个步骤组成( 请参考前文 ).在 Linux 系统编程中,有个方法可以将这些步骤给集成起来,让我们使用起来更加的方便.那就是调用 sigaction ...

  6. 信号发送接收函数:sigqueue/sigaction

    信号是一种古老的进程间通信方式,下面的例子利用sigqueue发送信号并附带数据:sigaction函数接受信号并且处理时接受数据. 1.sigqueue: 新的信号发送函数,比kill()函数传递了 ...

  7. Linux C--信号 sigaction函数

    使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...

  8. sigaction 函数

    本文主要参考<unix环境高级编程>   sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作).   int sigaction(int signo,con ...

  9. 信号之sigsuspend函数

    更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞.使用这种技术可以保护不希望由信号中断的代码临界区.如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,则又将如何呢?假定信 ...

随机推荐

  1. 详解WPF Blend工具中的复合路径功能 ( 含路径标记语法 )

    写此文章的目的是为了简单分析一下 Blend工具中提供的"复合路径"功能.有人在我的博文中留言问我复合路径的问题.  稍微琢磨一下,觉得应该是对的.因此贴出来和大家分享.有不对的说 ...

  2. AWS Summit 2014 San Francisco站总结

    我上个月去San Francisco参加了AWS Summit 2014 会议,总结一下参加这个会议的情况. 什么是AWS Summit? AWS Summit 是AWS在全球各地举办的,针对AWS用 ...

  3. 应用删除后 Launchpad 上仍有应用图标无法删除的解决方法

    应用删除后 Launchpad 上仍有应用图标上带有问号且无法删除时,可以将 launchpad 重置. 在终端输入: defaults write com.apple.dock ResetLaunc ...

  4. asp web api 怎么使用put和delete。

    Method Overriding RESTful services allow the clients to act on the resources through methods such as ...

  5. 验证dictionary重复键

    if (dict.ContainsKey("sadsa")) { }

  6. Linux下Python获取IP地址

    <lnmp一键安装包>中需要获取ip地址,有2种情况:如果服务器只有私网地址没有公网地址,这个时候获取的IP(即私网地址)不能用来判断服务器的位置,于是取其网关地址用来判断服务器在国内还是 ...

  7. windos系统快捷键 2015-05-08 23:31 24人阅读 评论(0) 收藏

    WIN7的向上按钮消失了,但是它的快捷键没有消失: Alt + ↑: 文件夹的后退前进 Alt +← 和Alt →: 切换到上个操作的窗口Alt +Esc: 版权声明:本文为博主原创文章,未经博主允许 ...

  8. 什么是S-OFF,什么是S-ON,HBOOT命令,玩转Android

    什么是S-OFF?S代表 Security Lock,是安全锁,保护锁的意思.S-OFF就是安全保护关,S-ON就是安全保护开.Secure Lock 就是安全锁.是硬件设计厂商用于保护固件不被刷写而 ...

  9. HDU 4284Travel(状压DP)

    HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...

  10. POJ1275Cashier Employment(查分约束系统)

    链接1275Cashier Employment 题目大意就是说有一些人来应聘一个超级市场的工作,每个人的应聘的起始时间在0~23时之间,而超市在时间i需要R[i]个工作人员,而每个人的工作时间都是8 ...