Вход/Регистрация
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 требует, чтобы частично выполненный системный вызов возвращал успешное завершение, указав, сколько работы было выполнено. Системный вызов, который еще не начал выполняться, вызывается повторно.

  • Читать дальше
  • 1
  • ...
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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