sigreturn, rt_sigreturn -
выполняет
возврат из
обработчика
сигнала и
очищает
кадр стека
Standard C library (
libc,
-lc)
int sigreturn(...);
Если ядро Linux
обнаруживает,
что
неблокированный
сигнал
ожидает
обработки
процессом,
то при
следующем
переключении
в
пользовательский
режим в
этом
процессе
(например,
при
возврате
из
системного
вызова или
когда
процесс
перепланируется
на ЦП), оно
создаёт
новый кадр
в стеке
пользовательского
пространства,
где
сохраняет
различные
части
контекста
процесса
(состояние
слова
процессора,
регистры,
маску
сигналов и
настройки
стека
сигналов).
Также ядро
делает так,
что при
переходе в
пользовательский
режим
вызывается
обработчик
сигналов и
при
возврате
из
обработчика
управление
передаётся
части кода
пользовательского
пространства,
называемого
«сигнальным
батутом»(signal
trampoline). Код
сигнального
батута, в
свою
очередь,
вызывает
sigreturn().
This
sigreturn() call undoes everything that was done—changing the
process's signal mask, switching signal stacks (see
sigaltstack(2))—in order to invoke the signal handler. Using the
information that was earlier saved on the user-space stack
sigreturn()
restores the process's signal mask, switches stacks, and restores the
process's context (processor flags and registers, including the stack pointer
and instruction pointer), so that the process resumes execution at the point
where it was interrupted by the signal.
Вызов
sigreturn() не
возвращает
значений.
Во многих
системах UNIX
есть
системный
вызов
sigreturn()
или его
эквивалент.
Однако
этот вызов
отсутствует
в POSIX, и в
разных
системах
он
работает
по-разному.
Вызов
sigreturn()
существует
только для
реализации
обработчиков
сигналов.
Никогда
не
вызывайте
его
напрямую
(на самом
деле,
простая
обёртка
sigreturn()
в
библиотеке
GNU C просто
вернёт -1 и
присвоит
errno
значение
ENOSYS).
Содержимое
аргументов
(если есть),
передаваемое
sigreturn(), для
каждой
архитектуры
своё (на
некоторых
архитектурах,
например x86-64,
у
sigreturn() нет
аргументов,
так как вся
требуемая
информация
доступна
из кадра
стека,
который
был создан
ядром
ранее в
стеке
пользовательского
пространства).
Когда-то
системы UNIX
помещали
код
сигнального
перехода в
пользовательский
стек. В
настоящее
время
страницы
пользовательского
стека
защищены и
в них
невозможно
выполнить
код.
Поэтому в
современных
системах Linux,
в
зависимости
от
архитектуры,
код
хранится в
vdso(7) или в
библиотеке
C. В
последнем
случае
обёрточная
функция
sigaction(2)
библиотеки
C
информирует
ядро о
расположении
кода
помещая
его адрес в
поле
sa_restorer
структуры
sigaction и
устанавливает
флаг
SA_RESTORER в
поле
sa_flags.
Сохранённая
информация
контекста
процесса
помещается
в
структуру
ucontext_t
(смотрите
<sys/ucontext.h>). Эта
структура
видима
внутри
обработчика
сигнала
как третий
аргумент
обработчика,
установленного
sigaction(2) с флагом
SA_SIGINFO.
В
некоторых
других
системах UNIX
работа
сигнального
батута
несколько
отличается.
В
частности,
в
некоторых
системах
при
переходе в
пользовательский
режим ядро
передаёт
управление
батуту (а не
обработчику
сигнала) и
код батута
вызывает
обработчик
сигнала (и
затем
вызывает
sigreturn() после
завершения
работы
обработчика).
Первоначальное
название
системного
вызова в Linux
было
sigreturn().
Однако с
добавлением
сигналов
реального
времени в Linux 2.2
для
поддержки
увеличенного
типа
sigset_t был
добавлен
новый
системный
вызов
rt_sigreturn().
Библиотека
GNU C скрывает
это от нас,
прозрачно
используя
rt_sigreturn(), если он
есть в ядре.
kill(2),
restart_syscall(2),
sigaltstack(2),
signal(2),
getcontext(3),
signal(7),
vdso(7)
Русский
перевод
этой
страницы
руководства
был сделан
Alexander Golubev <
[email protected]>, Azamat Hackimov
<
[email protected]>, Hotellook, Nikita
<
[email protected]>, Spiros Georgaras <
[email protected]>, Vladislav
<
[email protected]>, Yuri Kozlov <
[email protected]>
и Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]