Calling default signal handler directly from new one

1.2k views Asked by At

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?

1

There are 1 answers

0
bca On BEST ANSWER

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/8067109

If 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

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