如何将代码添加到标准信号处理程序?

时间:2011-09-12 14:00:31

标签: c linux handler signals

我在Linux上运行了一个C应用程序,我需要在标准信号处理程序中添加一些代码。我的想法是设置我的处理程序保存指向标准的指针,并从我的代码中调用保存的处理程序。不幸的是,signal()和sigaction()都没有返回指向标准处理程序的指针。它们都返回NULL。 有没有办法进行自定义处理并继续标准处理而不删除自定义处理程序并再次发送相同的信号?

2 个答案:

答案 0 :(得分:3)

没有“标准信号处理程序”;相反,当信号未处理时,内核会执行默认操作。如果您想在收到信号时执行某些操作,然后按照默认操作,您可以在信号处理程序结束时执行以下操作:

sigset_t set;
signal(sig, SIG_DFL);
raise(sig);
sigemptyset(&set);
sigaddset(&set, sig);
sigprocmask(SIG_UNBLOCK, &set, 0);

这假设您使用sigaction来安装信号处理程序,并且未指定SA_NODEFERSA_RESETHAND标志。也可以使用这些标志实现你想要的东西并简单地调用raise,但是如果信号快速连续传递两次,那么这种情况就会变得很难看,所以你不应该这样做;而是使用我建议的方法。

编辑:实际上你不必做任何信号掩码工作,因为从信号处理程序返回将恢复旧的信号掩码。这应该工作:

signal(sig, SIG_DFL);
raise(sig);
return;

答案 1 :(得分:0)

当对signal()或sigaction()的调用返回NULL时,它意味着SIG_DFL(即默认信号处理程序)

如果你正在使用signal(),那么当调用处理程序时应该重置处理程序,你可以发出raise(SIGNAL)as 信号处理程序中的最后一行,它应该调用默认的处理程序。

如果你正在使用sigaction(),那么你应该传入SA_RESETHAND作为其中一个标志,这将允许你在该处理程序中使用raise(SIGNAL)调用。

绝大多数默认信号处理程序将终止应用程序,因此这种“一次性”替换将起作用。你可以加 在raise调用之后调用sigaction()再次存储新的处理程序,例如。

void sighandler(int signum)
{
    // Do my stuff
    raise(signup);
    signal(signum, sighandler);
}