Чтение онлайн

на главную - закладки

Жанры

Основы программирования в 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);

}

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

Hello World!

Hello World!

^C

OUCH!
– 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
описывает сигнал как некорректный.

Поделиться:
Популярные книги

Память

Буджолд Лоис Макмастер
10. Сага о Форкосиганах
Фантастика:
научная фантастика
9.41
рейтинг книги
Память

Месть Паладина

Юллем Евгений
5. Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Месть Паладина

Бояръ-Аниме. Газлайтер. Том 34

Володин Григорий Григорьевич
34. История Телепата
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 34

Лихие. Авторитет

Вязовский Алексей
3. Бригадир
Фантастика:
альтернативная история
попаданцы
5.00
рейтинг книги
Лихие. Авторитет

Кодекс Охотника. Книга XXXIX

Сапфир Олег
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIX

Диалоги

Платон Аристокл
Научно-образовательная:
психология
история
философия
культурология
7.80
рейтинг книги
Диалоги

Вперед в прошлое 5

Ратманов Денис
5. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 5

Эволюционер из трущоб. Том 5

Панарин Антон
5. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб. Том 5

Снайпер

Поселягин Владимир Геннадьевич
3. Жнец
Фантастика:
боевая фантастика
попаданцы
5.60
рейтинг книги
Снайпер

Хозяин Стужи 2

Петров Максим Николаевич
2. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.75
рейтинг книги
Хозяин Стужи 2

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья

Призыватель нулевого ранга

Дубов Дмитрий
1. Эпоха Гардара
Фантастика:
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга

Как я строил магическую империю 7

Зубов Константин
7. Как я строил магическую империю
Фантастика:
попаданцы
постапокалипсис
аниме
фантастика: прочее
5.00
рейтинг книги
Как я строил магическую империю 7

Целитель 2

Романович Роман
2. Целитель
Фантастика:
городское фэнтези
аниме
5.00
рейтинг книги
Целитель 2