В отличие от большинства глав в данной книге, наше представление здесь историческое, связанное с освещением развития API, включая API, которые никогда не следует использовать в новом коде. Мы делаем это, потому что это упрощает изложение, делая понятным, почему функция POSIX API
sigaction
поддерживает все те возможности, которые поддерживает.
10.2. Действия сигналов
Каждый сигнал (вскоре мы представим полный список) имеет связанное с ним действие по умолчанию. POSIX обозначает это как диспозицию (disposition) сигнала. Это то действие, которое ядро осуществляет для процесса, когда поступает определенный сигнал. Действие по умолчанию варьирует:
Завершение
Процесс завершается.
Игнорирование
Сигнал игнорируется. Программа никогда не узнает, что что-то случилось.
Снимок
образа процесса
Процесс завершается, и ядро создает файл core (в текущем каталоге процесса), содержащий образ работавшей на момент поступления сигнала программы. Снимок процесса может впоследствии использоваться с отладчиком для исследования состояния программы (см. главу 15 «Отладка»).
По умолчанию системы GNU/Linux создают файлы с именем
core.pid
, где
pid
является ID завершаемого процесса. (Это можно изменить; см. sysctl(8).) Такое именование позволяет хранить в одном и том же каталоге несколько файлов
core
, за счет использования большего дискового пространства. [105] Традиционные системы Unix называют файл
core
, и это ваше дело сохранить какие-нибудь файлы
core
для последующего изучения, если есть шанс создания других таких же файлов в том же каталоге.
105
По крайней мере один поставщик дистрибутивов GNU/Linux отменяет сознание файлов
core
«с иголочки». Для повторного подключения этой возможности поместите в свой файл
~/.profile
строку '
ulimit -S -с unlimited
' — Примеч. автора.
Остановка
Процесс останавливается. Впоследствии он может быть возобновлен. (Если вы использовали управление заданиями оболочки с помощью CTRL-Z,
fg
и
bg
, вы понимаете остановку процесса.)
10.3. Стандартные сигналы С:
signal
и
raise
Стандарт ISO С определяет первоначальный API управления сигналами V7 и новый API для посылки сигналов. Вы должны использовать их для программ, которым придется работать на не-POSIX системах, или в случаях, когда предоставляемые ISO С API возможности являются достаточными.
10.3.1. Функция
signal
Действие сигнала изменяется с помощью функции
signal
. Вы можете изменить действие на «игнорировать сигнал», «восстановить для сигнала действие системы по умолчанию» или «вызвать при появлении сигнала мою функцию с номером сигнала в качестве параметра».
Функция, которую вы предоставляете для распоряжения сигналом, называется обработчиком сигнала (или просто обработчиком), а установка ее в соответствующем месте осуществляет перехват (catch) сигнала.
Получив эти сведения, давайте перейдем к API. В заголовочном файле
<signal.h>
представлены определения макросов для поддерживаемых сигналов и объявления функций управления сигналами, предоставляемыми стандартом С:
является указателем на функцию с возвращаемым типом
void
, которая принимает один целый аргумент. Это целое является номером поступающего сигнала.
Функция
signal
принимает номер сигнала в качестве своего первого параметра, а указатель функции (новый обработчик) в качестве своего второго аргумента. Если последний не является указателем функции, он может быть лишь
SIG_DEF,
что означает «восстановить действие по умолчанию», либо
SIG_IGN
, что означает «игнорировать сигнал».
signal
изменяет действие для
signum
и возвращает предыдущее действие. (Это дает вам возможность восстановить при желании предыдущее действие.) Возвращаемое значение может равняться также
SIG_ERR
, что указывает на произошедшую ошибку. (Некоторые сигналы невозможно перехватить или игнорировать; предоставление для них обработчика сигнала или неверный
signum
создают эту ошибку.) В табл. 10.1 перечислены сигналы, доступные под GNU/Linux, их числовые значения, действия по умолчанию для каждого, формальный стандарт или современная операционная система, которые их определяют, и смысл каждого.