signal() overwriting other signal handlers

The signal() call:

  1. Installs the handler you specify as a new signal handler, and
  2. 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.


This is not a "literal" answer to your question, but a recommendation: You shouldn't do this in a DLL.

It is unexpected and often annoying for the application that uses the DLL. A DLL should (normally) be "passive" and only provide functions for the application to call.

So rather provide a public function from your DLL that applications are required to call e.g. MyDllCleanup(). Then let the application decide how it calls that function (via a signal handler or other). BTW, the same goes for initialization: rather than relying on DllMain (or _init/_fini with libdl on UNIX) provide explicit functions for applications to call.

Tags:

C++

Dll

Sigint