Основы программирования в Linux
Шрифт:
Надежный интерфейс сигналов
Мы рассмотрели подробно возбуждение и перехват сигналов с помощью
signal
и родственных функций, поскольку они очень часто применяются в старых UNIX-программах. Тем не менее, стандарты X/Open и спецификации UNIX рекомендуют более современный программный интерфейс для сигналов sigaction
, который более надежен.
#include <signal.h>
int sigaction<int sig, const struct sigaction *act, struct sigaction *oact);
Структура
sigaction
, применяемая для определения действий, предпринимаемых при получении сигнала, заданного в аргументе sig
, определена в файле signal.h и как минимум включает следующие элементы:
void (*)(int)sa_handler /* функция, SIG_DFL или SIG_IGN */
sigset_t sa_mask /* сигналы, заблокированные для sa_handler */
int sa_flags /* модификаторы действий сигнала */
Функция
sigaction
задает действие, связанное с сигналом sig
. Если oact
не null
, sigaction
записывает предыдущее действие для сигнала в указанное oact
место. Если act
равен null
, это все, что делает функция sigaction
. Если указатель act
не null
, задается действие для указанного сигнала. Как и функция
signal
, sigaction
возвращает 0 в случае успешного выполнения и -1 в случае ошибки. Переменная errno
получит значение EINVAL
, если заданный сигнал некорректен или была предпринята попытка захватить или проигнорировать сигнал, который нельзя захватывать или игнорировать. В структуре
sigaction
, на которую указывает аргумент act
, sa_handler
— это указатель на функцию, вызываемую при получении сигнала sig
. Она очень похожа на функцию func
, которая, как вы видели раньше, передавалась функции signal
. Вы можете применять специальные значения SIG_IGN
и SIG_DFL
в поле sa_handler
для обозначения того, что сигнал должен игнорироваться или должно быть восстановлено действие по умолчанию, соответственно. Поле
sa_mask
описывает множество сигналов, которые будут добавлены в маску сигналов процесса перед вызовом функции sa_handler
. Это множество сигналов, которые блокируются и не должны доставляться процессу. Такое поведение мешает возникновению ситуации, описанной ранее, в которой сигнал был получен до того, как его обработчик дошел до завершения. Применение поля sa_mask
может устранить это состояние гонок. Однако сигналы, захватываемые обработчиками, заданными в структуре
sigaction
, по умолчанию не восстанавливаются, и нужно задать в поле sa_flags
значение SA_RESETHAND
, если хотите добиться поведения, виденного вами раньше при обсуждении функции signal
. Прежде чем обсуждать подробнее sigaction
, давайте перепишем программу ctrlc.c, применяя sigaction
вместо функции signal
(упражнение 11.9). Упражнение 11.9. Функция
sigaction
Внесите приведенные далее изменения, так чтобы сигнал
SIGINT
перехватывался sigaction
. Назовите новую программу ctrlc2.c.
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void ouch(int sig) {
printf("OUCH!
– I got signal %d\n", sig);
– I got signal %d\n", sig);
}
int main {
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0);
while (1) {
printf("Hello World!\n");
sleep(1);
}
}
Когда вы выполните эту версию программы, то всегда будете получать сообщение при нажатии комбинации клавиш <Ctrl>+<C>, поскольку
SIGINT
обрабатывается неоднократно функцией sigaction
. Для завершения программы следует нажать комбинацию клавиш <Ctrl>+<\>, которая генерирует по умолчанию сигнал SIIGQUIT
.
$ ./ctrlc2
Hello World!
Hello World!
Hello World!
^C
OUCH!
– I got signal 2
– I got signal 2
Hello World!
Hello World!
^C
OUCH!
– I got signal 2
– I got signal 2
Hello World!
Hello World!
^\
Quit
$
Как это работает
Программа вместо функции
signal
вызывает sigaction
для задания функции ouch
как обработчика сигнала, возникающего при нажатии комбинации клавиш <Ctrl>+<C> (SIGINT
). Прежде всего, она должна определить структуру sigaction
, содержащую обработчик, маску сигналов и флаги, В данном случае вам не нужны никакие флаги, и создается пустая маска сигналов с помощью новой функции sigemptyset
. Примечание
После выполнения программы вы можете обнаружить дамп ядра (в файле core). Его можно безбоязненно удалить.
Множества сигналов
В заголовочном файле signal.h определены тип
sigset_t
и функции, применяемые для манипулирования множествами сигналов. Эти множества используются в sigaction
и других функциях для изменения поведения процесса при получении сигналов.
#include <signal.h>
int sigaddset(sigset_t *set, int signo);
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigdelset(sigset_t *set, int signo);
Приведенные функции выполняют операции, соответствующие их названиям,
sigemptyset
инициализирует пустое множество сигналов. Функция sigfillset
инициализирует множество сигналов, заполняя его всеми заданными сигналами, sigaddset
и sigdelset
добавляют заданный сигнал (signo
) в множество сигналов и удаляют его из множества. Они все возвращают 0 в случае успешного завершения и -1 в случае ошибки, заданной в переменной errno
. Единственная определенная ошибка EINVAL
описывает сигнал как некорректный.
Поделиться:
Популярные книги
Эпоха Опустошителя. Том VII
7. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Лейб-хирург
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Газлайтер. Том 21
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Московское золото или нежная попа комсомолки. Часть Вторая
2. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Родословная. Том 2
2. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Наследие Маозари 6
6. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Второгодка. Книга 3. Ученье свет
3. Второгодка
Фантастика:
городское фэнтези
сказочная фантастика
альтернативная история
5.00
рейтинг книги
Родословная. Том 3
3. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Ну привет, заучка...
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Телохранитель Генсека. Том 3
3. Медведев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Паладин
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
История московских кладбищ. Под кровом вечной тишины
Научно-образовательная:
история
культурология
5.75
рейтинг книги
Я уже царь. Книга XXIX
29. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 2
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00