signal() overwriting other signal handlers
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.
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.