Страница 143 из 253
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 и справочная страница 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