signal() overwriting other signal handlers

c++, dll, sigint

Solution

The `signal()` call:

- Installs the handler you specify as a new signal handler, and

- Tells you what the old handler was.

The new handler will be called instead of the old one. If you want to chain them, you need to do something like:

    typedef void (*Handler)(int signum);

    static Handler old_int_handler = SIG_IGN;

    static void int_handler(int signum)    /* New signal handler */
    {
        /* ...do your signal handling... */
        if (old_int_handler != SIG_IGN && old_int_handler != SIG_DFL)
            (*old_int_handler)(signum);
    }

    static void set_int_handler(void)  /* Install new handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old != SIG_IGN)
        {
            old_int_handler = old;
            signal(SIGINT, int_handler);
        }
    }

    static void rst_int_handler(void)    /* Restore original handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old == int_handler)
        {
            signal(SIGINT, old_int_handler);
            old_int_handler = SIG_IGN;
        }
    }

    void another_function()
    {
        /* ... */
        set_int_handler();
        /* ... */
        rst_int_handler();
        /* ... */
    }

If interrupts were being ignored, this keeps them ignored. If interrupts were being handled by a user-defined interrupt handler, then this calls your signal handling code and the original signal handling code.

Note that the advice from Christian.K about not handling signals in a DLL (shared library) is also relevant and valid. The description above assumes you decide to ignore that advice.

Problem

Does the `signal()` function overwrite other signal calls a process might have set up? I.e. if a `SIGINT` handler has been setup by a process, and a DLL calls `signal(SIGINT,xxx)` to handle its own termination code, does the original `SIGINT` handler get disabled?

Original source