直接从新的调用默认信号处理程序

时间:2018-10-04 15:17:24

标签: c linux signals signal-handling userspace

我有一个用于计时器信号的信号处理程序。这是库的一部分,我不想对调用程序已经启用的任何其他计时器处理程序进行任何假设,因此我希望处理程序仅在事件中触发,并为所有事件调用默认处理程序其他事件。

我已经看过有关此主题的几篇文章,并且大多数建议将信号处理程序重写回原始处理程序,然后重新引发信号。我的问题是,如果其他信号抢占了我的位置,我将不再在该信号的下一个实例上被调用。为此,我找到了一个解决方案,您可以在其中直接调用旧的信号处理程序。我所拥有的如下:

/* Set up signal handler. */
if (sigaction(sigNo, &sa, &old_sa) == -1)
...
te.sigev_value.sival_ptr = my_timer_id;
timer_create(CLOCK_REALTIME, &te, my_timer_id);
...

static void
my_timer_handler(int sig, siginfo_t *si, void *uc) {
    timer_t *tidp = si->si_value.sival_ptr;
    if ( *tidp == my_timer_id ) {
        // do my stuff
    } else {
        if (old_sa.sa_sigaction) {
            (*old_sa.sa_sigaction)(sig, si, uc);
        } else if(old_sa.sa_handler)
            (*old_sa.sa_handler)(sig);
    }
}

但这也是有缺陷的-根据有关帮助的手册页:

  

在某些体系结构上涉及联合:不要同时分配给sa_handler和sa_sigaction。

表示我可能调用了错误的函数。那么,有没有一种标准的方法来调用正确的信号处理程序?

1 个答案:

答案 0 :(得分:2)

我认为使用sigevent结构-timer_create-的参数将是更好的解决方案。您可以看到此答案作为示例:https://stackoverflow.com/a/38356989/8067109

如果您想这样做,则应选中SA_SIGINFO标志。 SA_SIGINFO标志告诉sigaction()使用sa_sigaction字段。

应该是

if (old_sa.sa_flags & SA_SIGINFO) {
       (*old_sa.sa_sigaction)(sig, si, uc);
 else 
       (*old_sa.sa_handler)(sig);