Несмотря на то, что константа NSIG не указана в стандарте SUSv3, она определена в большинстве реализаций UNIX. Тем не менее, возможно, потребуется установить некоторые параметры компилятора для используемой реализации, чтобы сделать эту константу видимой. Например, в Linux мы должны определить один из макросов тестирования возможности _BSD_SOURCE, _SVID_SOURCE или _GNU_SOURCE.

Функции printSigMask() и printPendingSigs() применяют функцию printSigset() для вывода сигнальной маски процесса и набора сигналов, ожидающих доставки процессу, соответственно. Функции printSigMask() и printPendingSigs() соответственно применяют системные вызовы sigprocmask() и sigpending(). Вызовы sigprocmask() и sigpending() описаны в разделах 20.10 и 20.11.

Листинг 20.4. Функции для отображения наборов сигналов

signals/signal_functions.c

#define _GNU_SOURCE

#include

#include

#include "signal_functions.h" /* Объявляет определяемые здесь функции */

#include "tlpi_hdr.h"

/* ПРИМЕЧАНИЕ: Все следующие функции используют функцию fprintf(), не являющуюся

безопасной для асинхронных сигналов (см. подраздел 21.1.2). Следовательно, эти

функции также не являются безопасными для асинхронных сигналов (остерегайтесь

беспорядочно вызывать их из обработчиков сигналов). */

void /* Выводит список сигналов в наборе */

printSigset(FILE *of, const char *prefix, const sigset_t *sigset)

{

int sig, cnt;

cnt = 0;

for (sig = 1; sig < NSIG; sig++) {

if (sigismember(sigset, sig)) {

cnt++;

fprintf(of, "%s%d (%s)\n", prefix, sig, strsignal(sig));

}

}

if (cnt == 0)

fprintf(of, "%s\n", prefix);

}

int /* Напечатать маску заблокированных сигналов процесса */

printSigMask(FILE *of, const char *msg)

{

sigset_t currMask;

if (msg!= NULL)

fprintf(of, "%s", msg);

if (sigprocmask(SIG_BLOCK, NULL, &currMask) == –1)

return –1;

printSigset(of, "\t\t", &currMask);

return 0;

}

int /* Распечатать сигналы, ожидающие доставки процессу */

printPendingSigs(FILE *of, const char *msg)

{

sigset_t pendingSigs;

if (msg!= NULL)

fprintf(of, "%s", msg);

if (sigpending(&pendingSigs) == –1)

return –1;

printSigset(of, "\t\t", &pendingSigs);

return 0;

}

signals/signal_functions.c

20.10. Сигнальная маска (блокирование доставки сигналов)

Для каждого процесса ядро хранит сигнальную маску — набор сигналов, доставка которых в процесс временно заблокирована. Если в процесс отправляется заблокированный сигнал, то доставка этого сигнала откладывается до тех пор, пока сигнал не будет разблокирован путем удаления из сигнальной маски процесса. (В подразделе 33.2.1 мы увидим, что на самом деле сигнальная маска — это атрибут потока и что каждый поток многопоточного процесса может независимо просматривать и изменять сигнальную маску с помощью функции pthread_sigmask().)

Сигнал может быть добавлен в сигнальную маску одним из следующих способов.

• При активации обработчика сигнал, послуживший этому причиной, может быть автоматически добавлен в маску. Происходит это или нет, зависит от флагов, использованных при установке обработчика с помощью sigaction().

• Когда обработчик установлен с помощью вызова sigaction(), можно указать дополнительный набор сигналов, которые подлежат блокировке при активации обработчика.

• Системный вызов sigprocmask() может использоваться в любое время для явного добавления и удаления сигналов из сигнальной маски.

Мы отложим обсуждение первых двух случаев до того момента, пока не изучим функцию sigaction() в разделе 20.13, а вызов sigprocmask() рассмотрим прямо сейчас.

#include

int sigprogmask(int how, const sigset_t *set, sigset_t *oldset);

Возвращает 0 при успешном завершении или –1 при ошибке

Мы можем использовать функцию sigprocmask() для изменения сигнальной маски процесса, для получения существующей маски либо для совершения обоих действий. Аргумент how определяет изменения, вносимые функцией sigprocmask() в сигнальную маску.

• SIG_BLOCK — сигналы, включенные в набор сигналов, на который указывает аргумент set, добавляются в сигнальную маску. Иными словами, сигнальная маска — это объединение текущего значения маски и значения аргумента set.

• SIG_UNBLOCK — сигналы, указанные в наборе сигналов, на который указывает аргумент set, исключаются из сигнальной маски. Разблокирование незаблокированных сигналов не приводит к возврату кода ошибки.

• SIG_SETMASK — набор сигналов, на который указывает параметр set, присваивается сигнальной маске.

В каждом случае если значение аргумента oldset не равно NULL, то указывает на буфер sigset_t, используемый для возврата предыдущего значения сигнальной маски.

Если мы хотим получить сигнальную маску без внесения изменений, можно установить значение NULL для аргумента set, в этом случае аргумент how будет проигнорирован.

Перейти на страницу:

Похожие книги