Системный вызов
signal()
устанавливает новый обработчик сигнала с номером
signum
в соответствии с параметром
sighandler,
который может быть функцией пользователя,
SIG_IGN
или
SIG_DFL.
При получении процессом сигнала с номером
signum
происходит следующее:
если устанавливаемое значение обработчика равно
SIG_IGN,
то сигнал игнорируется;
если оно равно
SIG_DFL,
то выполняются стандартные действия, связанные с сигналом (см.
signal(7)).
Наконец, если обработчик установлен в функцию
sighandler,
то сначала устанавливает значение обработчика в SIG_DFL
или выполняется зависимая от реализации блокировка сигнала,
а затем вызывается функция
sighandler
с параметром
signum.
Использование функции-обработчика сигнала называется
"перехватом сигнала".
Сигналы
SIGKILL
и
SIGSTOP
не могут быть "перехвачены" или игнорированы.
ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ
Функция
signal()
возвращает предыдущее значение обработчика сигнала или
SIG_ERR
при ошибке.
ПОРТИРУЕМОСТЬ
Стандартная функция
signal()
в UNIX устанавливает значение обработчика равным SIG_DFL;
System V (а также ядро Linux и libc4,5) выполняют то же самое.
С другой стороны, BSD не перезагружает обработчик, а блокирует
новые сигналы на время вызова обработчика.
Библиотека glibc2 следует поведению BSD.
В системе libc5 включение
<bsd/signal.h>
вместо
<signal.h>,
приводит к переопределению
signal
в
__bsd_signal,
и эта функция начинает работать, как в BSD. Но это нежелательно.
В системе glibc2 при определении тестового макроса типа
_XOPEN_SOURCE
или при использовании отдельной функции
sysv_signal
поведение функции будет стандартным. Это тоже нежалательно.
Попытаться изменить семантику этой функции при помощи
определений и включений - не очень хорошая идея.
Лучше избегать использования функции
signal
вообще, и использовать вместо нее
sigaction(2).
ЗАМЕЧАНИЯ
Согласно POSIX, поведение процесса после игнорирования сигналов
SIGFPE,
SIGILL
или
SIGSEGV,
не созданных при помощи функций
kill(2)
или
raise(3),
не определено.
Деление на ноль имеет непредсказуемый характер.
На некоторых машинах это приведет к получению сигнала
SIGFPE.
Более того, деление самого большого по модулю
отрицательного числа на -1 приведет к появлению
SIGFPE.
Игнорирование этого сигнала может привести к появлению бесконечнного цикла.
POSIX (3.3.1.3) не определяет, что случается при
SIGCHLD,
установленном в
SIG_IGN.
Поведение BSD и SYSV в этом случае различно. Это приводит к тому,
что BSD-программы, устанавливающие поведение
SIGCHLD
равным
SIG_IGN,
в Linux не работают.
Использование
sighandler_t
является расширением GNU.
Разные версии libc определяют этот тип; libc4 и libc5 определяют
SignalHandler,
glibc определяет
sig_t
и
_GNU_SOURCE,
а также
sighandler_t.