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

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

Жанры

Linux программирование в примерах
Шрифт:

2235 #else

2236 if (signal(sig, SIG_IGN) != SIG_IGN)

2237 signal(sig, sighandler); /* - Та же логика со старым API */

2238 #endif

2239 }

2240 }

Мы заметили, что строки 2216–2219 и 2221 могут быть замещены одним вызовом:

sigfillset(&newact.sa_mask)
;

Мы не знаем, почему код написан именно таким способом.

Интерес представляют также строки 2233–2234 и 2236–2237, которые показывают правильный способ проверки того, игнорируется ли сигнал, и для установки обработчика лишь в том случае, если сигнал не игнорируется.

ЗАМЕЧАНИЕ. Функции API

sigaction
и
signal
не должны использоваться вместе для одного и того же сигнала. Хотя POSIX идет на большие длинноты, чтобы сначала сделать возможным использование
signal
, получить
struct sigaction
, представляющую диспозицию
signal
, и восстановить ее, все равно это плохая мысль. Код будет гораздо проще читать, писать и понимать, если вы используете одну функцию или другую взаимоисключающим образам

10.6.5. Извлечение ожидающих сигналов:

sigpending

Описанный ранее системный вызов

sigpending
позволяет получить набор ожидающих сигналов, т.е тех сигналов, которые появились, но еще не доставлены из-за блокировки:

#include <signal.h> /* POSIX */

int sigpending(sigset_t *set);

Помимо разблокировки ожидающих сигналов, чтобы они могли быть доставлены, вы можете решить их игнорировать. Установка действия сигнала

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

10.6.6. Создание возможности для прерывания функций:

siginterrupt

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

siginterrupt
. Объявление следующее:

#include <signal.h> /* XSI */

int siginterrupt(int sig, int flag);

В соответствии со стандартом POSIX поведение

siginterrupt
эквивалентно следующему коду:

int siginterrupt(int sig, int flag) {

 int ret;

 struct sigaction act;

 (void)sigaction(sig, NULL, &act); /* Получить старые установки */

 if (flag) /* Если flag равен true... */

act.sa_flags &= ~SA_RESTART; /* Запретить повторный запуск */

 else /* В противном случае... */

act.sa_flags |= SA_RESTART; /* Разрешить повторный запуск */

 ret = sigaction(sig, &act, NULL);

/* Поместить новые установки на место */

 return ret; /* Вернуть результат */

}

В случае успеха возвращаемое значение равно 0 и -1 при ошибке.

10.6.7. Передача сигналов:

kill
и
killpg

Традиционная функция Unix для передачи сигналов называется

kill
. Имя несколько неправильное; все, что она делает — отправляет сигнал. (Результатом этого часто является завершение получателя сигнала, но это не обязательно верно. Однако, теперь слишком поздно менять имя.) Функция
killpg
посылает сигнал определенной группе процессов. Объявления следующие:

#include <sys/types.h> /* POSIX */

#include <signal.h>

int kill(pid_t pid, int sig);

int killpg(int pgrp, int sig); /* XSI */

Аргумент

sig
является либо именем сигнала, либо 0. В последнем случае сигнал не посылается, но ядро все равно осуществляет проверку ошибок. В частности, это правильный способ проверки существования данного процесса или группы, а также проверки того, что у вас есть разрешение на передачу сигналов процессу или группе процессов
kill
возвращает 0 в случае успеха и -1 при ошибке;
errno
указывает на проблему.

Правила для значения

pid
несколько запутаны:

pid > 0
pid
является номером процесса, и сигнал посылается этому процессу

pid = 0
Сигнал посылается каждому процессу в группе посылающего процесса.

pid = -1
Сигнал посылается каждому процессу в системе, за исключением специальных системных процессов. Применяется проверка прав доступа. На системах GNU/Linux исключается лишь процесс
init
(PID 1), но у других систем могут быть другие специальные процессы.

pid < -1
Сигнал посылается группе процессов, представленной абсолютным значением
pid
. Таким образом, вы можете отправить сигнал всей группе процессов, дублируя возможности
killpg
. Эта неортогональность обеспечивает историческую совместимость.

Значение

pid
для
kill
сходно со значением для
waitpid
(см. раздел 9.1.6.1 «Использование функций POSIX:
wait
и
waitpid
»).

Стандартная функция С

raise
в сущности эквивалентна

int raise(int sig) {

 return kill(getpid, sig);

}

Комитет по стандартизации С выбрал имя

raise
, поскольку С должен работать также в окружениях, не относящихся к Unix, a
kill
была сочтена специфичной для Unix функцией. Представилась также возможность дать этой функции более описательное имя.

killpg
посылает сигнал группе процессов. Пока значение
pgrp
превышает 1, эта функция эквивалентна '
kill(-pgrp, sig)
'. Справочная страница GNU/Linux killpg(2) утверждает, что если
pgrp
равно 0, сигнал посылается группе отправляющего процесса (Это то же самое, что и
kill
.)

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

Первый среди равных. Книга X

Бор Жорж
10. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Первый среди равных. Книга X

Мастер порталов

Лисина Александра
8. Гибрид
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер порталов

Шайтан Иван 6

Тен Эдуард
6. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
7.00
рейтинг книги
Шайтан Иван 6

Моров. Том 3

Кощеев Владимир
2. Моров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Моров. Том 3

Я до сих пор не князь. Книга XVI

Дрейк Сириус
16. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я до сих пор не князь. Книга XVI

Вернувшийся: Посол. Том IV

Vector
4. Вернувшийся
Фантастика:
космическая фантастика
киберпанк
5.00
рейтинг книги
Вернувшийся: Посол. Том IV

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Хозяин оков V

Матисов Павел
5. Хозяин Оков
Фантастика:
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Хозяин оков V

Петля, Кадетский корпус. Книга первая

Алексеев Евгений Артемович
1. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
6.11
рейтинг книги
Петля, Кадетский корпус. Книга первая

Мое ускорение

Иванов Дмитрий
5. Девяностые
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Мое ускорение

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

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Я царь. Книга XXVIII

Дрейк Сириус
28. Дорогой барон!
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Я царь. Книга XXVIII

Воплощение Похоти

Некрасов Игорь
1. Воплощение Похоти
Фантастика:
юмористическое фэнтези
попаданцы
рпг
аниме
5.00
рейтинг книги
Воплощение Похоти