Linux программирование в примерах
Заменить маску сигналов процесса содержимымSIG_SETMASK.*setЕсли
равенset, aNULL— нет, значениеoldsetневажно. Эта комбинация получает маску сигналов текущего процесса, не меняя ее. (Это явно выражено в стандарте POSIX, но не ясно из справочной страницы GNU/Linux.)howint sigpending(sigset_t *set)Эта функция позволяет увидеть, какие сигналы ожидают решения; т.е.
заполнен этими сигналами, которые были посланы, но они еще не доставлены, поскольку заблокированы.*setint sigsuspend(const sigset_t *set)Эта функция временно заменяет маску сигналов процесса содержимым
, а затем приостанавливает процесс, пока сигнал не будет получен. По определению, заставить функцию вернуться может только сигнал, не находящийся в*set(см. раздел 10.7 «Сигналы для межпроцессного взаимодействия).*set10.6.4. Перехват сигналов:
sigaction()Наконец мы готовы взглянуть на функцию
. Эта функция сложна, и мы намеренно опускаем множество деталей, которые предназначены для специального использования. Стандарт POSIX и справочная страница sigaction(2) предоставляют все подробности, хотя вы должны тщательно прочесть и то, и другое, чтобы полностью все усвоить.sigaction()#include <signal.h> /* POSIX */int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);Аргументы следующие:
int signumИнтересующий сигнал, как в случае с другими функциями обработки сигналов.
const struct sigaction *actОпределение нового обработчика для сигнала
.signumstruct 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.signumint 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. Как POSIX, так и справочная страница GNU/Linux указывают, что эти два поля могут перекрываться в памяти (т. е. быть частьюact->sa_handler). Таким образом, никогда не следует использовать оба поля в одной и той жеunion.struct sigactionПоле
составляется с помощью побитового ИЛИ значений одного или более флагов, перечисленных в табл. 10.3.sa_flagsТаблица 10.3. Значения флагов для
sa_flags
Флаг Значение SA_NOCLDSTOPЭтот флаг имеет смысл лишь для . Когда он установлен, родитель не получает сигнал при остановке порожденною процесса сигналамиSIGCHLD,SIGSTOP,SIGTSTPилиSIGTTIN. Эти сигналы обсуждаются позже, в разделе 10.8.2SIGTTOUSA_NOCLDWAIТЭтот флаг имеет смысл лишь для . Его поведение сложно. Мы отложим объяснение на потом, см. раздел 10.8.3SIGCHLDSA_NODEFERОбычно данный сигнал блокируется, когда вызывается обработчик сигнала. Когда установлен один из этих флагов, данный сигнал не блокируется при запуске обработчика является официальным именем POSIX данного флага (которое и следует использовать)SA_NODEFERSA_NOMASKАльтернативное имя для [110]SA_NODEFERSA_SIGINFOОбработчик сигнала принимает три аргумента. Как упоминалось, при данном установленном флаге должно использоваться поле вместоsa_sigaction.sa_handlerSA_ONSTACKЭто продвинутая возможность. Обработчики сигналов могут вызываться с использованием предоставленной пользователем памяти в качестве «альтернативного стека сигнала». Эта память даётся ядру для подобного использования посредством (см. sigaltstack(2)). Эта особенность больше не описывается в данной книгеsigaltstack()SA_RESETHANDЭтот флаг обеспечивает поведение V7: после вызова обработчика восстанавливается действие сигнала по умолчанию. Официальным именем POSIX флага (которое следует использовать) является SA_RESETHANDSA_ONESHOTАльтернативное имя для SA_RESETHAND.SA_RESTARTЭтот флаг предоставляет семантику BSD: системные вызовы, которые могут завершиться с ошибкой и которые получают этот сигнал, запускаются повторно.EINTR