Эта функция позволяет увидеть, какие сигналы ожидают решения; т.е.
*set
заполнен этими сигналами, которые были посланы, но они еще не доставлены, поскольку заблокированы.
int sigsuspend(const sigset_t *set)
Эта функция временно заменяет маску сигналов процесса содержимым
*set
, а затем приостанавливает процесс, пока сигнал не будет получен. По определению, заставить функцию вернуться может только сигнал, не находящийся в
*set
(см. раздел 10.7 «Сигналы для межпроцессного взаимодействия).
10.6.4. Перехват сигналов:
sigaction
Наконец мы готовы взглянуть на функцию
sigaction
.
Эта функция сложна, и мы намеренно опускаем множество деталей, которые предназначены для специального использования. Стандарт POSIX и справочная страница sigaction(2) предоставляют все подробности, хотя вы должны тщательно прочесть и то, и другое, чтобы полностью все усвоить.
#include <signal.h> /* POSIX */
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Аргументы следующие:
int signum
Интересующий сигнал, как в случае с другими функциями обработки сигналов.
const struct sigaction *act
Определение нового обработчика для сигнала
signum
.
struct sigaction *oldact
Определение текущего обработчика. Если не
NULL
, система до установки
*act
заполняет
*oldact
.
*act
может быть
NULL
, в этом случае
*oldact
заполняется, но больше ничего не меняется.
Таким образом,
sigaction
и устанавливает новый обработчик, и получает старый за одно действие.
struct sigaction
выглядит следующим образом.
/* ПРИМЕЧАНИЕ: Порядок в структуре может варьировать. Могут быть
также и другие поля! */
struct sigaction {
sigset_t sa_mask; /* Дополнительные сигналы для блокирования */
int sa_flags; /* Контролирует поведение */
void (*sa_handler)(int);
/* Может образовать объединение с sa_sigaction */
void (*sa_sigaction)(int, siginfo_t*, void*);
/* Может образовать объединение с sa_handler */
}
Поля следующие:
sigset_t sa_mask
Набор дополнительных сигналов для блокирования при запуске функции обработчика. Таким образом, когда вызывается обработчик, общий набор заблокированных сигналов является объединением сигналов в маске процесса, сигналов в
act->mask
и, если
SA_NODEFER
сброшен,
signum
.
int sa_flags
Флаги, контролирующие обработку сигнала ядром. См. обсуждение далее.
void (*sa_handler)(int)
Указатель на «традиционную» функцию обработчика. У нее такой же прототип (возвращаемый тип и список параметров), как у функции обработчика для
signal
,
bsd_signal
и
sigset
.
void (*sa_sigaction)(int, siginfo_t*, void*)
Указатель на функцию обработчика «нового стиля». Функция принимает три аргумента, которые вскоре будут описаны.
Которая из функций
act->sa_handler
и
act->sa_sigaction
используется, зависит от флага
SA_SIGINFO
в
act->sa_flags
. Когда имеется, используется
act->sa_sigaction
; в противном случае используется
act->sa_handler
. Как POSIX, так и справочная страница GNU/Linux указывают, что эти два поля могут перекрываться в памяти (т. е. быть частью
union
). Таким образом, никогда не следует использовать оба поля в одной и той же
struct sigaction
.
Поле
sa_flags
составляется с помощью побитового ИЛИ значений одного или более флагов, перечисленных в табл. 10.3.
Таблица 10.3. Значения флагов для
sa_flags
Флаг
Значение
SA_NOCLDSTOP
Этот
флаг имеет смысл лишь для
SIGCHLD
. Когда он установлен, родитель не получает сигнал при остановке порожденною процесса сигналами
SIGSTOP
,
SIGTSTP
,
SIGTTIN
или
SIGTTOU
. Эти сигналы обсуждаются позже, в разделе 10.8.2
SA_NOCLDWAIТ
Этот флаг имеет смысл лишь для
SIGCHLD
. Его поведение сложно. Мы отложим объяснение на потом, см. раздел 10.8.3
SA_NODEFER
Обычно данный сигнал блокируется, когда вызывается обработчик сигнала. Когда установлен один из этих флагов, данный сигнал не блокируется при запуске обработчика
SA_NODEFER
является официальным именем POSIX данного флага (которое и следует использовать)
Обработчик сигнала принимает три аргумента. Как упоминалось, при данном установленном флаге должно использоваться поле
sa_sigaction
вместо
sa_handler
.
SA_ONSTACK
Это продвинутая возможность. Обработчики сигналов могут вызываться с использованием предоставленной пользователем памяти в качестве «альтернативного стека сигнала». Эта память даётся ядру для подобного использования посредством
sigaltstack
(см. sigaltstack(2)). Эта особенность больше не описывается в данной книге
SA_RESETHAND
Этот флаг обеспечивает поведение V7: после вызова обработчика восстанавливается действие сигнала по умолчанию. Официальным именем POSIX флага (которое следует использовать) является
SA_RESETHAND
SA_ONESHOT
Альтернативное имя для
SA_RESETHAND.
SA_RESTART
Этот флаг предоставляет семантику BSD: системные вызовы, которые могут завершиться с ошибкой
EINTR
и которые получают этот сигнал, запускаются повторно.
110
Насколько мы смогли определить, имена
SA_NOMASK
и
SA_ONESHOT
являются специфическими для GNU/Linux. Если кому-нибудь известно иное, пожалуйста, сообщите нам!
Когда в
act->sa_flags
установлен флаг
SA_SIGINFO
, поле
act->sa_sigaction
является указателем на функцию, объявленную следующим образом: