SIGPWR — 30 (SA=29, MP=19) — Подача питания скоро прекратится — Заверш.
SIGQUIT — 3 — Выход с терминала — + — Ядро
SIGSEGV — 11 — Неверная ссылка памяти — + — Ядро
SIGSTKFLT — 16 (SAM=н/опр, P=36) — Ошибка стека на сопроцессоре — Заверш.
SIGSTOP — 19 (SA=17, M=23, P=24) — Императивная остановка — + — Стоп
SIGSYS — 31 (SAMP=12) — Неверный системный вызов — + — Ядро
SIGTERM — 15 — Завершить процесс — + — Заверш.
SIGTRAP — 5 — Ловушка точки прерывания — + — Ядро
SIGTSTP — 20 (SA=18, M=24, P=25) — Остановка с терминала — + — Стоп
SIGTTIN — 21 (M=26, P=27) — Чтение с терминала ФП — + — Стоп
SIGTTOU — 22 (M=27, P=28) — Запись в терминал ФП — + — Стоп
SIGURG — 23 (SA=16, M=21, P=29) — Срочные данные на сокете — + — Игнор.
SIGUSR1 — 10 (SA=30, MP=16) — Пользовательский сигнал 1 — + — Заверш.
SIGUSR2 — 12 (SA=31, MP=17) — Пользовательский сигнал 2 — + — Заверш.
SIGVTALRM — 26 (M=28, P=20) — Закончилось время виртуального таймера — + — Заверш.
SIGWINCH — 28 (M=20, P=23) — Изменен размер окна терминала — Игнор.
SIGXCPU — 24 (M=30, P=33) — Превышено ограничение времени ЦПУ — + — Ядро
SIGXFSZ — 25 (M=31, P=34) — Превышено ограничение размера файла — + — Ядро
Обратите внимание на следующие замечания касаемо поведения по умолчанию некоторых сигналов из табл 20.1.
• В Linux 2.2 действие по умолчанию для сигналов SIGXCPU, SIGXFSZ, SIGSYS и SIGBUS — завершить процесс без создания файла дампа ядра. Начиная с версии ядра 2.4, Linux соответствует требованиям стандарта SUSv3, требующим, чтобы эти сигналы завершали процесс с генерацией дампа ядра. В некоторых других реализациях UNIX сигналы SIGXCPU и SIGXFSZ обрабатываются так же, как и в Linux 2.2.
• Сигнал SIGPWR в иных реализациях UNIX (где встречается) по умолчанию игнорируется.
• Сигнал SIGIO в некоторых реализациях UNIX (в частности, производных от BSD) по умолчанию игнорируется.
• Сигнал SIGEMT не утвержден стандартами, но встречается практически во всех реализациях UNIX. Однако в других реализациях он приводит к завершению с дампом ядра.
• В стандарте SUSv1 действие по умолчанию для сигнала SIGURG было указано как завершение процесса, оно является действием по умолчанию в некоторых старых реализациях UNIX. В стандарте SUSv2 была принята текущая спецификация (игнорирование).
В системах UNIX предоставляется два способа изменения диспозиции сигнала: signal() и sigaction(). Системный вызов signal(), описываемый в этом разделе, изначально был API для установки диспозиции сигнала, кроме того, данный вызов предлагает более простой интерфейс по сравнению с sigaction(). С другой стороны, sigaction() предоставляет функционал, недоступный в signal(). Существует несколько вариаций поведения функции signal() в различных реализациях UNIX (см. раздел 22.7), а это значит, что данная функция никогда не должна использоваться для установки обработчиков сигналов в переносимых программах. Из-за обозначенных проблем с переносимостью функция sigaction() является предпочтительным API для установки обработчиков сигналов. После того как мы объясним применение sigaction() в разделе 20.13, мы всегда будем задействовать данный вызов для установки обработчиков сигналов в примерах программ.
Несмотря на то что функция signal() задокументирована во втором разделе справочных страниц Linux, на самом деле эта функция реализована в glibc как библиотечная, реализованная поверх системного вызова sigaction().
#include
void (*signal(int
Возвращает предыдущую диспозицию сигнала при успешном завершении или SIG_ERR при ошибке
Прототип функции signal() требует небольших пояснений. Первый аргумент, sig, обозначает сигнал, диспозицию которого мы хотим изменить. Второй аргумент, handler, — это адрес функции, которую нужно вызывать по получении данного сигнала. Эта функция ничего не возвращает (void) и принимает один целочисленный аргумент. Таким образом, обработчик сигнала имеет следующую общую форму:
void
handler(int sig)
{
/* Код обработчика */
}
Мы описываем предназначение аргумента sig функции обработчика в разделе 20.4.
Возвращаемое значение функции signal() — это предыдущая диспозиция сигнала. Как и аргумент handler, данное значение — указатель на функцию, ничего не возвращающую и принимающую один целочисленный аргумент. Иными словами, мы могли бы написать код, подобный тому, что приведен ниже, для временной установки обработчика сигнала и последующего сброса его диспозиции до любого предшествовавшего значения:
void (*oldHandler)(int);
oldHandler = signal(SIGINT, newHandler);
if (oldHandler == SIG_ERR)
errExit("signal");
/* Сделать здесь что-то еще. Если в это время получен SIGINT,
для обработки сигнала будет использован newHandler. */
if (signal(SIGINT, oldHandler) == SIG_ERR)
errExit("signal");
С помощью функции signal() невозможно получить текущую диспозицию сигнала без одновременного изменения ее значения. Чтобы сделать это, нам необходимо воспользоваться функцией sigaction().