Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

12.7.1. Получение контекста сигнала

Информация о том, как и почему был сгенерирован сигнал, называется контекстом [68] сигнала. Приложения, которые должны видеть этот контекст, используют обработчики сигналов, отличающиеся от нормальных. Они включают два дополнительных параметра — указатель на

siginfo_t
, предоставляющий контекст сигнала, и указатель на
void*
, который может быть использован некоторыми низкоуровневыми системными библиотеками [69] . Вот как выглядит полный прототип такого обработчика.

68

До появления стандарта POSIX приложение могло обращаться к

struct sigcontext
за информацией того же рода, что теперь представляет
siginfo_t
, и термин "контекст" остался от этой старой реализации.

69

Этот третий параметр на самом деле указывает на структуру

struct ucontext
, которая позволяет процессам выполнять полное переключение контекстов в пользовательском пространстве. Данные вопросы выходят за пределы тем, рассматриваемых в настоящей книге, но это хорошо документировано в Single Unix Specification.

void handler(int signum, siginfo_t *siginfo, void *context);

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

SA_SIGINFO
члена
sa_mask
структуры
struct sigaction
, применяемой для регистрации обработчика сигнала. Член
sa_handler
также не используется, потому что он является указателем на функцию с другим прототипом. Вместо этого новый член,
sa_sigaction
, указывает на обработчик сигнала с правильным прототипом. Чтобы снизить потребление памяти,
sa_handler
и
sa_sigaction
разрешено использовать один и тот же участок памяти, поэтому только один из двух должен применяться в одно и то же время. Чтобы сделать это прозрачным, библиотека С определяет
struct sigaction
следующим образом.

#include <signal.h>

struct sigaction {

 union {

__sighandler_t sa_handler;

__sigaction_t sa_sigaction;

 } __sigaction_handler;

 sigset_t sa_mask;

 unsigned long sa_flags;

};

#define sa_handler __sigaction_handler.sa_handler

#define sa_sigaction __sigaction_handler.sa_sigaction

Использование представленной комбинации объединений и макросов позволяет этим двум членам разделять одну и ту же память без необходимости усложнения с точки зрения приложений.

Структура

siginfo_t
содержит информацию о том, где и почему был сгенерирован сигнал. Всем сигналам доступны два члена:
sa_signo
и
si_code
. Какие другие члены доступны — зависит от конкретного сигнала, и эти члены разделяют память подобно тому, как это делают члены
sa_handler
и
sa_sigaction
структуры
struct sigaction
. Член
sa_signo
содержит номер доставленного сигнала и всегда равен значению первого параметра, переданного обработчику сигнала, в то время как
si_code
указывает, почему сигнал был сгенерирован, и изменяется в зависимости от номера сигнала. Для большинства сигналов он может принимать перечисленные ниже значения. [70]

70

Существует гораздо больше значений

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

SI_USER

Приложение пространства пользователя вызвало

kill
для отправки сигнала. Примечание. Функция
sigsend
, включенная в Linux для совместимости с некоторыми системами Unix, также выдает
SI_USER
.

SI_QUEUE

Приложение пространства пользователя вызвало

sigqueue
для от правки сигнала, что обсуждается в самом конце этой главы.

SI_TKILL

Приложение пространства пользователя вызвало

tkill
. В то время как ядро Linux использует
SI_TKILL
, его значение не специфицировано в текущей версии библиотеки С.

Если вам нужно проверить

SI_TKILL
, используйте следующий сегмент кода для определения этого значения:

#ifndef SI_TKILL

#define SI_TKILL -6

#endif

SI_TKILL
не специфицирован ни в каком стандарте (хотя допускается ими), поэтому его следует применять осторожно в переносимых программах.

SI_KERNEL

Сигнал сгенерирован ядром.

Когда

SIGILL
,
SIGFPE
,
SIGSEGV
,
SIGBUS
и
SIGCHLD
посылаются ядром, то si_
code
вместо
si_kernel
принимает значения, перечисленные в табл. 12.3 [71] .

71

Он также принимает специальное значение

SIGTRAP
, которое используется отладчиками, и
SIGPOLL
, применяемое механизмом ненадежного асинхронного ввода-вывода. Ни один из них не описан в настоящей книге, поэтому подробности об этих сигналах не включены в табл. 12.3.

Таблица 12.3. Значения

si_code
для специальных сигналов

  • Читать дальше
  • 1
  • ...
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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

Сигнал si_code Описание
SIGILL
ILL_ILLOPC
Неправильный код операции (opcode).
ILL_ILLOPC
Неправильный операнд.
ILL_ILLOPC
Неправильный режим адресации.
ILL_ILLOPC
Неправильная ловушка (trap).
ILL_ILLOPC
Привилегированный код операции.
ILL_ILLOPC
Привилегированный регистр.
ILL_ILLOPC
Внутренняя ошибка стека.
ILL_ILLOPC
Ошибка сопроцессора.
SIGFPE
FPE_INTDIV
Деление целого на ноль.
FPE_INTOVF
Переполнение целого.