I have signal handler for a timer signal. This is part of a library, and I'd like to not make any assumptions about any other timer handlers the calling program already has enabled, so I'd like my handler to trigger only on my events, and call the default handler for all other events.
I've seen several posts on this subject, and most suggest overriding the signal handler back to the original handler, and then re-raising the signal. My problem with that is that if some else's signal preempted mine, I no longer get called on the next instance of the signal. To that end, I found a solution where you can call the old signal handler directly. What I have is as follows:
/* 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);
}
}
But this is flawed as well -- according to the man page for sigaction:
On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.
meaning I could be calling the incorrect function. So, is there a standard way to call the correct signal handler?
I think using
sigevent
structure -parameter of the timer_create- would be better solution. You can see this answer as an example: https://stackoverflow.com/a/38356989/8067109If you want to do it that way, you should check
SA_SIGINFO
flag. The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field.So it should be