Маска сигналов процесса вначале пуста - заблокированных сигналов нет. (Это упрощение; см. раздел 10.9 «Сигналы, передающиеся через fork()
и exec()
.) Три функции позволяют работать непосредственно с маской сигналов процесса:
#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *set);
Функции следующие:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
Если oldset
не равен NULL
, получается маска сигналов текущего процесса и помещается в *oldset
. Затем маска сигналов процесса обновляется в соответствии с содержимым set
и значением how
, который должен иметь одно из следующих значений:
SIG_BLOCK
Объединить сигналы в *set
с маской сигналов текущего процесса. Новая маска является объединением текущей маски и *set
.
SIG_UNBLOCK
Удалить сигналы в *set
из маски сигналов процесса. Это не представляет проблемы, если *set
содержит сигнал, который не содержится в текущей маске сигналов процесса.
SIG_SETMASK
Заменить маску сигналов процесса содержимым *set
.
Если set
равен NULL
, a oldset
— нет, значение how
неважно. Эта комбинация получает маску сигналов текущего процесса, не меняя ее. (Это явно выражено в стандарте POSIX, но не ясно из справочной страницы GNU/Linux.)
int sigpending(sigset_t *set)
Эта функция позволяет увидеть, какие сигналы *set
заполнен этими сигналами, которые были посланы, но они еще не доставлены, поскольку заблокированы.
int sigsuspend(const sigset_t *set)
Эта функция *set
, а затем приостанавливает процесс, пока сигнал не будет получен. По определению, заставить функцию вернуться может только сигнал, не находящийся в *set
(см. раздел 10.7 «Сигналы для межпроцессного взаимодействия).
10.6.4. Перехват сигналов: sigaction()
Наконец мы готовы взглянуть на функцию sigaction()
. Эта функция сложна, и мы намеренно опускаем множество деталей, которые предназначены для специального использования. Стандарт POSIX и справочная страница
#include
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*)