Выбрать главу

sigemptyset(&hup);

sigaddset(&hup, SIGHUP);

sigprocmask(SIG_BLOCK, &hyp, NULL);

src = someString;

while(*src)

 *dest++ = *src++;

sigprocmask(SIG_UNBLOCK, &hup, NULL);

Сложность обеспечения безопасности обработчика сигналов от состояния состязаний должно заставить вас писать обработчики, насколько возможно, простыми.

12.2.5. Нахождение набора ожидающих сигналов

Очень легко найти сигналы, находящиеся в состоянии ожидания (сигналы, которые должны быть доставлены, но в данный момент заблокированы).

#include <signal.h>

int sigpending(sigset_t *set);

Эта функция записывает по адресу, указанному set, набор сигналов, которые в данный момент находятся в состоянии ожидания.

12.2.6. Ожидание сигналов

Когда программа построена преимущественно вокруг сигналов, часто необходимо, чтобы она ожидала появления какого-то сигнала, прежде чем продолжать работу. Системный вызов pause() предоставляет простую возможность для этого.

#include <unistd.h>

int pause(void);

Функция pause() не возвращает управления до тех пор, пока сигнал не будет доставлен процессу. Если зарегистрирован обработчик для этого сигнала, то он запускается до того, как pause() вернет управление, pause() всегда возвращает -1 и устанавливает errno равным EINTR.

Системный вызов sigsuspend() предлагает альтернативный метод ожидания вызова сигнала.

#include <signal.h>

int sigsuspend(const sigset_t *mask);

Как и pause(), sigsuspend() временно приостанавливает процесс до тех пор, пока не будет получен сигнал (и обработан связанным с ним обработчиком, если таковой предусмотрен), возвращая -1 и устанавливая errno в EINTR.

В отличие от pause(), sigsuspend() временно устанавливает маску сигналов процесса в значение, находящееся по адресу, указанному в mask, на период ожидания появления сигнала. Как только сигнал поступает, маска сигналов восстанавливается в то значение, которое она имела до вызова sigsuspend(). Это позволяет процессу ожидать появления определенного сигнала за счет блокирования всех остальных сигналов[63].

12.3. Доступные сигналы

Linux предоставляет в распоряжение процессов сравнительно немного сигналов, и все они собраны в табл. 12.1.

Таблица 12.1. Сигналы

Сигнал Описание Действие по умолчанию
SIGABRT Доставляется вызовом abort(). Прервать, сбросить дамп
SIGALRM Истек срок действия alarm(). Прервать
SIGBUS Ошибка, зависящая от оборудования. Прервать, сбросить дамп
SIGCHLD Дочерний процесс прерван. Игнорировать
SIGCONT Выполнение процесса продолжается после приостановки. Игнорировать
SIGFPE Арифметическая ошибка. Прервать, сбросить дамп
SIGHUP Закрыт процесс, управляющий терминалом. Прервать
SIGILL Обнаружена недопустимая инструкция. Прервать
SIGINT Пользователь послал символ прерывания (^C). Прервать
SIGIO Принят асинхронный ввод-вывод. Прервать
SIGKILL Не перехватываемое прерывание процесса. Прервать
SIGPIPE Процесс пишет в канал при отсутствии читателя. Прервать
SIGPROF Закончился сегмент профилирования. Прервать
SIGPWR Обнаружен сбой питания. Прервать
SIGQUIT Пользователь послал символ выхода (^\). Прервать, сбросить дамп
SIGSEGV Нарушение памяти. Прервать, сбросить дамп
SIGSTOP Приостановка процесса без его прерывания. Процесс приостановить
SIGSYS Неверный системный вызов. Прервать, сбросить дамп
SIGTERM Перехватываемый запрос на прерывание процесса. Прервать
SIGTRAP Получена инструкция точки прерывания. Прервать, сбросить дамп
SIGTSTP Пользователь послал символ приостановки (^Z). Процесс приостановить
SIGTTIN Фоновый процесс читает с управляющего терминала. Процесс приостановить
SIGTTOU Фоновый процесс пишет на управляющий терминал. Процесс приостановить
SIGURG Условие срочного ввода-вывода. Игнорировать
SIGUSR1 Определяемый процессом сигнал. Прервать
SIGUSR2 Определяемый процессом сигнал. Прервать
SIGVTALRM Таймер, установленный с помощью setitimer(), устарел. Прервать
SIGWINCH Размер управляющего терминала изменился. Игнорировать
SIGXCPU Достигнуто ограничение ресурсов центрального процессора. Прервать, сбросить дамп
SIGXFSZ Достигнуто ограничение размера файла. Прервать, сбросить дамп
вернуться

63

Применение sigprocmask() и pause() для получения требуемого поведения может вызвать состояние состязаний, если сигнал, появление которого ожидается, поступит между этими двумя системными вызовами.