Переписывает ли функция signal()
другие вызовы сигналов, которые мог настроить процесс? т.е. если обработчик SIGINT
был установлен процессом, а DLL вызывает signal(SIGINT,xxx)
для обработки собственного кода завершения, отключается ли исходный обработчик SIGINT
?
signal() перезаписывает другие обработчики сигналов
Ответы (2)
Вызов signal()
:
- Устанавливает обработчик, указанный вами как новый обработчик сигнала, и
- Сообщает вам, каким был старый обработчик.
Новый обработчик будет вызываться вместо старого. Если вы хотите связать их, вам нужно сделать что-то вроде:
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();
/* ... */
}
Если прерывания игнорировались, это сохраняет их игнорирование. Если прерывания обрабатывались определяемым пользователем обработчиком прерываний, то это вызывает ваш код обработки сигналов и исходный код обработки сигналов.
Обратите внимание, что совет от Christian.K о том, что нельзя обрабатывать сигналы в DLL (разделяемой библиотеке), также актуален и актуален. Описание выше предполагает, что вы решили проигнорировать этот совет.
Это не «буквальный» ответ на ваш вопрос, а рекомендация: вам не следует делать это в DLL.
Это неожиданно и часто раздражает приложение, использующее DLL. DLL должна (обычно) быть «пассивной» и предоставлять только функции для вызова приложения.
Поэтому лучше предоставьте общедоступную функцию из вашей DLL, которую приложения должны вызывать, например. MyDllCleanup()
. Затем позвольте приложению решить, как оно вызывает эту функцию (через обработчик сигнала или другое). Кстати, то же самое касается инициализации: вместо того, чтобы полагаться на DllMain
(или _init
/_fini
с libdl
в UNIX), предоставьте явные функции для вызова приложений.
sigint
поднимается и не поднимается.
- person Qix - MONICA WAS MISTREATED; 23.05.2012
SIGINT
, msdn.microsoft.com/en-us/library/xdkz3x12(VS.71).aspx - person Hasturkun   schedule 22.05.2012signal()
требуется стандартом C (C89), MSVC должен его поддерживать. Семантика может быть ограничена, но ее необходимо поддерживать. - person Jonathan Leffler   schedule 22.05.2012