Уже отмечалось, что при получении сигнала от пользовательского процесса структура siginfo_t содержит дополнительные поля (табл. 2.20).
Таблица 2.20. Дополнительные поля структуры siginfo_t
Значение поля si_signo |
Дополнительные поля | Значение |
|---|---|---|
| SIGILL SIGFPE | caddr_t si_addr |
Адрес недопустимой инструкции |
| SIGSEGV SIGBUS | caddr_t si_addr |
Адрес недопустимой области памяти |
| SIGCHLD | pid_t si_pid |
Идентификатор дочернего процесса |
int si_status |
Код возврата сигнала | |
| SIGPOLL | long si_band |
Ошибка канала (для модулей STREAMS) |
Установить маску сигналов или получить текущую маску можно с помощью функции sigprocmask(2):
#include <signal.h>
int sigprocmask(int how, sigset_t *set, sigset_t *oset);
Маска сигналов изменяется в соответствии с аргументом how, который может принимать следующие значения:
SIG_BLOCK |
Результирующая маска получится путем объединения текущей маски и набора set |
SIG_UNBLOCK |
Сигналы набора set будут удалены из текущей маски |
SIG_SETMASK |
Текущая маска будет заменена на набор set |
Если указатель set равен NULL, то аргумент how игнорируется. Если аргумент oset не равен NULL, то в набор, адресованный этим аргументом, помещается текущая маска сигналов.
Функция sigpending(2) используется для получения набора заблокированных сигналов, ожидающих доставки:
#include <signal.h>
int sigpending(int how, sigset_t *set, sigset_t *oset);
Список сигналов, ожидающих доставки, возвращается в наборе, адресованном аргументом set.
Системный вызов sigsuspend(2) замещает текущую маску набором, адресованным аргументом set, и приостанавливает выполнение процесса до получения сигналов, диспозиция которых установлена либо на завершение выполнения процесса, либо на вызов функции-обработчика сигнала.
#include <signal.h>
int sigsuspend(const sigset_t *set);
При получении сигнала, завершающего выполнение процесса, возврата из функции sigsuspend(2) не происходит. Если же диспозиция полученного сигнала установлена на вызов функции-обработчика, возврат из sisuspend(2) происходит сразу после завершения обработки сигнала. При этом восстанавливается маска, существовавшая до вызова sigsuspend(2).
Заметим, что в BSD UNIX вызов signal(3) является упрощенным интерфейсом к более общей функции sigaction(2), в то время как в ветви System V signal(3) подразумевает использование старой семантики ненадежных сигналов.
В заключение для иллюстрации изложенных соображений, приведем версию функции signal(), позволяющую использовать надежные сигналы. Похожая реализация используется в BSD UNIX. С помощью этой "надежной" версии мы повторим пример, рассмотренный нами выше, в измененном виде.