直接从新信号处理程序调用默认信号处理程序
Calling default signal handler directly from new one
我有定时器信号的信号处理程序。这是库的一部分,我不想对调用程序已经启用的任何其他定时器处理程序做任何假设,所以我希望我的处理程序只在我的事件上触发,并为所有调用默认处理程序其他活动。
我看过几篇关于这个主题的帖子,大多数都建议将信号处理程序覆盖回原始处理程序,然后重新发出信号。我的问题是,如果其他人的信号抢占了我的信号,我就不会再在下一个信号实例上被调用。为此,我找到了一个可以直接调用旧信号处理程序的解决方案。我的情况如下:
/* 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);
}
}
但这也有缺陷——根据 sigaction 的手册页:
On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.
意思是我可能调用了错误的函数。那么,有没有标准的方法来调用正确的信号处理程序?
我认为使用 timer_create- 的 sigevent
结构参数会是更好的解决方案。您可以将此答案作为示例查看:
如果你想那样做,你应该检查 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);
我有定时器信号的信号处理程序。这是库的一部分,我不想对调用程序已经启用的任何其他定时器处理程序做任何假设,所以我希望我的处理程序只在我的事件上触发,并为所有调用默认处理程序其他活动。
我看过几篇关于这个主题的帖子,大多数都建议将信号处理程序覆盖回原始处理程序,然后重新发出信号。我的问题是,如果其他人的信号抢占了我的信号,我就不会再在下一个信号实例上被调用。为此,我找到了一个可以直接调用旧信号处理程序的解决方案。我的情况如下:
/* 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);
}
}
但这也有缺陷——根据 sigaction 的手册页:
On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.
意思是我可能调用了错误的函数。那么,有没有标准的方法来调用正确的信号处理程序?
我认为使用 timer_create- 的 sigevent
结构参数会是更好的解决方案。您可以将此答案作为示例查看:
如果你想那样做,你应该检查 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);