signal() overwriting other signal handlers

2019-06-19 08:26发布

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?

标签: c++ dll sigint
2条回答
趁早两清
2楼-- · 2019-06-19 08:59

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.

查看更多
不美不萌又怎样
3楼-- · 2019-06-19 09:17

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;
    }
}

...in 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.

查看更多
登录 后发表回答