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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

 /* ...оставшаяся логика... */

}

(Обратите внимание, что эта стратегия уменьшает окно уязвимости, но не устраняет его).

Стандарт С вводит специальный тип —

sig_atomic_t
— для использования с такими флаговыми переменными. Идея, скрывающаяся за этим именем, в том, что присвоение значений переменным этого типа является атомарной операцией: т.е. они совершаются как одно делимое действие. Например, на большинстве машин присвоение значения
int
осуществляется атомарно, тогда как инициализация значений в структуре осуществляется либо путем копирования всех байтов в (сгенерированном компилятором) цикле, либо с помощью инструкции «блочного копирования», которая может быть прервана. Поскольку присвоение значения
sig_atomic_t
является атомарным, раз начавшись, оно завершается до того, как может появиться другой сигнал и прервать его.

Наличие особого типа является лишь частью истории. Переменные

sig_atomic_t
должны быть также объявлены как
volatile
:

volatile sig_atomic_t sig_int_flag = 0; /* обработчик сигнала устанавливает в true */

/* ...оставшаяся часть кода
как раньше... */

Ключевое слово

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

Структурирование приложения исключительно вокруг переменных

sig_atomic_t
ненадежно. Правильный способ обращения с сигналами показан далее, в разделе 10.7 «Сигналы для межпроцессного взаимодействия».

10.4.6. Дополнительные предостережения

Стандарт POSIX предусматривает для обработчиков сигналов несколько предостережений:

• Что случается, когда возвращаются обработчики для

SIGFPE
,
SIGILL
,
SIGSEGV
или любых других сигналов, представляющих «вычислительные исключения», не определено.

• Если обработчик был вызван в результате вызова

abort
,
raise
или
kill
, он не может вызвать
raise
.
abort
описана в разделе 12.4 «Совершение самоубийства:
abort
», a
kill
описана далее в этой главе. (Описанная далее функция API
sigaction
с обработчиком сигнала, принимающая три аргумента, дает возможность сообщить об этом, если это имеет место.)

• Обработчики сигналов могут вызвать лишь функции из табл. 10.2. В частности, они должны избегать функций

<stdio.h>
. Проблема в том, что во время работы функции
<stdio.h>
может возникнуть прерывание, когда внутреннее состояние библиотечной функции находится в середине процесса обновления. Дальнейшие вызовы функций
<stdio.h>
могут повредить это внутреннее состояние.

Список в табл. 10.2 происходит из раздела 2.4 тома System Interfaces (Системные интерфейсы) стандарта POSIX 2001. Многие из этих функций относятся к сложному API и больше не рассматриваются в данной книге.

Таблица 10.2. Функции, которые могут быть вызваны из обработчика сигнала

_Exit
fpathconf
raise
sigqueue
_exit
fstat
read
sigset
accept
fsync
readlink
sigsuspend
access
ftruncate
recv
sleep
aio_error
getegid
recvfrom
socket
aio_return
geteuid
recvmsg
socketpair
aio_suspend
getgid
rename
stat
alarm
getgroups
rmdir
sysmlink
bind
getpeername
select
sysconf
cfgetispeed
getpgrp
sem_post
tcdrain
cfgetospeed
getpid
send
tcflow
cfsetispeed
getppid
sendmsg
tcflush
cfsetospeed
getsockname
sendto
tcgetattr
chdir
getsockopt
setgid
tcgetpgrp
chmod
getuid
setpgid
tcsendbreak
chown
kill
setsid
tcsetattr
clock_gettime
link
setsockopt
tcsetpgrp
close
listen
setuid
time
connect
lseek
shutdown
timer_getoverrun
creat
lstat
sigaction
timer_gettime
dup
mkdir
sigaddset
timer_settime
dup2
mkfifo
sigdelset
times
execle
open
sigemptyset
umask
execve
pathconf
sigfillset
uname
fchmod
pause
sigismember
unlink
fchown
pipe
signal
utime
fcntl
poll
sigpause
wait
fdatasync
posix_trace_event
sigpending
waitpid
fork
pselect
sigprocmask
write

10.4.7.

Наша история до настоящего времени, эпизод 1

Сигналы являются сложной темой, и она становится еще более сбивающей с толку. Поэтому давайте на время сделаем остановку, сделаем шаг назад и подведем итог обсужденному до сих пор:

• Сигналы являются указанием того, что произошло некоторое внешнее событие.

• 

raise
является функцией ISO С для отправки сигнала текущему процессу. Как отправлять сигналы другим процессам, нам еще предстоит описать.

• 

signal
контролирует диспозицию сигнала, т.е. реакцию процесса на сигнал, когда он появляется. Сигнал можно оставить системе для обработки по умолчанию, проигнорировать или перехватить.

• Когда сигнал перехватывается, вызывается функция-обработчик. Вот где сложность начинает поднимать свою безобразную голову:

 • ISO С не определяет, восстанавливается ли диспозиция сигнала по умолчанию до вызова обработчика или она остается на месте. Первое является поведением V7 и современных систем System V, таких, как Solaris. Последнее является поведением BSD, используемым также в GNU/Linux. (Для форсирования поведения BSD может использоваться функция POSIX

bsd_signal
.)

• То, что случается при прерывании сигналом системного вызова, также различается в традиционной и BSD линейках. Традиционные системы возвращают -1 с errno, установленным в

EINTR
. BSD системы повторно запускают системный вызов после возвращения из обработчика. Макрос GLIBC
TEMP_FAILURE_RETRY
может помочь вам написать код для обработки системных вызовов, возвращающих -1 с
errno
, установленным в
EINTR
.

POSIX требует, чтобы частично выполненный системный вызов возвращал успешное завершение, указав, сколько работы было выполнено. Системный вызов, который еще не начал выполняться, вызывается повторно.

• Механизм

signal
предоставляет плодотворную почву для появления условий гонки. В этой ситуации помогает тип данных ISO С
sig_atomic_t
, но он не решает проблему, и определенный таким способом механизм не может обезопасить от проявления условий гонки.

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

Несмотря на эти проблемы интерфейса

signal
для простых программ достаточно, и он все еще широко используется.

10.5. API сигналов System V Release 3:

sigset
и др.

BSD 4.0 (примерно с 1980 г.) ввел дополнительные функции API для предоставления «надежных» сигналов. [109] В частности, стало возможным блокировать сигналы. Другими словами, программа могла сообщить ядру: «Зависни на этих конкретных сигналах в течении следующего небольшого промежутка времени, затем доставь их мне, когда я буду готов их принять». Большим преимуществом является то, что эта особенность упрощает обработчики сигналов, которые автоматически запускаются со своим заблокированным сигналом (чтобы избежать проблемы одновременной обработки двух сигналов) и, возможно, также и с другими заблокированными сигналами.

109

Для использования API требуется компоновка с отдельной библиотекой, —

ljobs
Примеч. автора.

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

Геном хищника. Книга девятая

Гарцевич Евгений Александрович
9. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга девятая

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

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

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

Дворянин

Злотников Роман Валерьевич
2. Император и трубочист
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Дворянин

Я князь. Книга XVIII

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

Каратила

Поповский Андрей Владимирович
Детективы:
боевики
6.50
рейтинг книги
Каратила

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

Сильнейший Столп Империи. Книга 4

Ермоленков Алексей
4. Сильнейший Столп Империи
Фантастика:
фэнтези
аниме
фантастика: прочее
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 4

Гримуар темного лорда VII

Грехов Тимофей
7. Гримуар темного лорда
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда VII

Идеальный мир для Лекаря 2

Сапфир Олег
2. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 2

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Глубокий космос

Вайс Александр
9. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Глубокий космос

Я не бог. Книга XXXIV

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

Гнев Пламенных

Дмитриева Ольга Олеговна
5. Пламенная
Фантастика:
фэнтези
4.80
рейтинг книги
Гнев Пламенных