Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сигнал.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
291.33 Кб
Скачать

Соответствие стандартам

SVr4, 4.4BSD (Функция killpg впервые появилась в 4.0BSD).  

Наборы сигналов

Для определения набора сигналов есть специальный тип: sigset_t

#include <signal.h>

int sigemptyset(sigset_t *set);

//инициализирует набор сигналов, и помечает его как //пустой. Возвращает 0

int sigfillset(sigset_t *set);

//инициализирует набор сигналов, и помечает его как //полный(все присутствуют). Возвращает 0

int sigaddset(sigset_t *set, int signo);

//добавить сигнал в набор

int sigdelset(sigset_t *set, int signo);

//удалить сигнал из набора. Возвращает 0 – успешно. //-1 если ошибка.

int sigismember(const sigset_t *set, int signo)

//Возвращает 1 – если проверяемый сигнал находится в //наборе. 0 если сигнал отсутствует в наборе. -1 при //ошибке.

Блокировка сигналов

Для реализации блокировки сигналов используется сигнальная маска. Это набор сигналов, принятие которых будет блокироваться (не обрабатываться) до тех пор, пока они не будут обратно разблокированы. Для управления используется функция

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

Системный вызов sigprocmask используется для того, чтобы изменить список блокированных в данный момент сигналов. Работа этой функции зависит от значения параметра how следующим образом:

SIG_BLOCK

Набор блокируемых сигналов - объединение текущего набора и аргумента set.

SIG_UNBLOCK

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

SIG_SETMASK

Набор блокируемых сигналов приравнивается к аргументу set.

Если значение поля oldset не равно нулю, то предыдущее значение маски сигналов записывается в oldset.

Третий аргумент может быть равен NULL. Если третий аргумент указан явно, то по этому адресу помещается предыдущее значение.

Если второй аргумент равен NULL, то в третий помещается текущий набор.

int sigpending(sigset_t *set);

int sigsuspend(const sigset_t *mask);  

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

Системный вызов sigsuspend временно изменяет значение маски блокировки сигналов процесса на указанное в mask, и затем приостанавливает работу процесса до получения соответствующего сигнала.  

Возвращаемые значения

Функция sigprocmask возвращает 0 при удачном завершении работы функции и -1 при ошибке.

Функция sigsuspend всегда возвращает -1, обычно с кодом ошибки EINTR.

 

Найденные ошибки

EINVAL

Было задано неверное значение сигнала. Эта ошибка также возникает в случае попытки задания сигналов SIGKILL или SIGSTOP, которые не могут быть "перехвачены".

EFAULT

set или mask указывают на адрес, не входящий в адресное пространство процесса.

EINTR

Системный вызов был прерван.

 

Замечания

Невозможно заблокировать сигналы SIGKILL или SIGSTOP при помощи системного вызова sigprocmask. Попытки это сделать будут игнорироваться.

В соответствии с POSIX поведение процесса после игнорирования сигнала SIGFPE, SIGILL или SIGSEGV не определено, если эти сигналы не были посланы при помощи функций kill() или raise(). Деление целого числа на ноль имеет непредсказуемый результат. В некоторых архитектурах это приводит к появлению сигнала SIGFPE. (Более того, деление самого большого по модулю отрицательного числа на -1 приведет к появлению SIGFPE.) Игнорирование этого сигнала может привести к появлению бесконечного цикла.

POSIX (B.3.3.1.3) запрещает установку действия для сигнала SIGCHLD на SIG_IGN. Поведение BSD и SYSV в этом случае различается. Это приводит к тому, что BSD-программы, определяющие поведение SIGCHLD в SIG_IGN, в Linux не работают.

Специфические черты POSIX определяют только SA_NOCLDSTOP. Использование других флагов в sa_flags может быть неэффективно в других системах.

Флаг SA_RESETHAND совместим с одноименным флагом SVr4.

Флаг SA_NODEFER совместим с одноименным флагом SVr4 в ядре версии 1.3.9 и более поздних. В старых выпусках ядра Linux позволяли принимать и обрабатывать любые сигналы, а не только те, обработка которых уже задана (на деле это приводит к игнорированию установок sa_mask).

Названия флагов SA_RESETHAND и SA_NODEFER, необходимые для совместимости с SVr4, присутствуют в библиотеках версии 3.0.9 и более поздних.

Флаг SA_SIGINFO описан в POSIX.1b. Его поддержка была добавлена в Linux 2.2.

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

Подробная информация о работе с наборами сигналов есть на странице sigsetops(3).  

СООТВЕТСТВИЕ СТАНДАРТАМ

POSIX, SVr4. SVr4 не описывает код ошибки EINTR.  

НЕДОКУМЕНТИРОВАННОЕ

До появления SA_SIGINFO существовала возможность получить дополнительную информацию, используя sa_handler со вторым параметром типа struct sigcontext. См. соответствующие исходные тексты ядра. В настоящее время этот механизм устарел.

sigaction, sigprocmask, sigpending, sigsuspend - POSIX-функции обработки сигналов.  

СИНТАКСИС

#include <signal.h>

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

ОПИСАНИЕ

Системный вызов sigaction используется для изменения действий процесса при получении соответствующего сигнала.

Параметр signum задает номер сигнала и может быть равен любому номеру, кроме SIGKILL и SIGSTOP.

Если параметр act не равен нулю, то новое действие, связянное с сигналом signum, устанавливается соответственно act. Если oldact не равен нулю, то предыдущее действие записывается в oldact.

Структура sigaction имеет следующий формат:

struct sigaction

{

void (*sa_handler)(int);

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

}

В некоторых архитектурах используется объединение элементов, но не используйте sa_handler и sa_sigaction вместе.

sa_handler задает тип действий процесса, связанный с сигналом signum, и может быть равен: SIG_DFL для выполнения стандартных действий, SIG_IGN для игнорирования сигнала,- или быть указателем на функцию обработки сигнала.

sa_mask задает маску сигналов, которые должны блокироваться при обработке сигнала. Также будет блокироваться и сигнал, вызвавший запуск функции, если только не были использованы флаги SA_NODEFER или SA_NOMASK.

sa_flags содержит набор флагов, которые могут влиять на поведение процесса при обработке сигнала. Он состоит из следующих флагов:

SA_NOCLDSTOP

Если signum равен SIGCHLD, то уведомление об остановке дочернего процесса не будет получено (т.е., в тех случаях, когда дочерний процесс получает сигнал SIGSTOP, SIGTSTP, SIGTTIN или SIGTTOU).

SA_NOCLDWAITесли значение signo равно SIGCHLD , то флаг предотвращает создание процессов-зомби по завершении дочерних процессов. Если родительский процесс вызовет функцию wait, то он окажется заблокированным до тех пор, пока последний дочерний процесс не завершится, после чего wait вернет значение -1 и код ошибки ECHLD в переменной errnj.

SA_ONESHOT или SA_RESETHAND

Восстановить поведение сигнала после одного вызова обработчика.

SA_ONSTACK

Вызвать обработчик сигнала в дополнительном стеке сигналов, предоставленном sigaltstack(2). Если дополнительный стек недоступен, то будет использован стек по умолчанию.

SA_RESTART

Поведение должно соответствовать семантике сигналов BSD и позволять некоторым системным вызовам работать, в то время как идет обработка сигналов.

SA_NOMASK or SA_NODEFER

Не препятствовать получению сигнала при его обработке.

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

SA_SIGINFO

Обработчик сигнала требует 3-х аргументов, а не одного. В этом случае надо использовать параметр sa_sigaction вместо sa_handler. (Поле sa_sigaction было добавлено в Linux 2.1.86.)

Параметр siginfo_t поля sa_sigaction является структурой, состоящей из следующих элементов:

Прототипы обработчиков.

void my_handler( int signo);

void my_handler(int signo, siginfo_t *si, void *ucontext_t);

struct siginfo_t {

int si_signo; /* Номер сигнала */

int si_errno; /* Значение errno */

int si_code; /* Код сигнала */

pid_t si_pid; /* Идентификатор процесса,

пославшего сигнал */

uid_t si_uid; /* Реальный идентификатор

пользователя процесса, пославшего сигнал */

int si_status; /* Выходное значение или номер сигнала процесса, который завершился*/

clock_t si_utime; /* Занятое пользователем время */

clock_t si_stime; /* Использованное системное

время */

sigval_t si_value; /* Значение сигнала */

int si_int; /* Сигнал POSIX.1b */

void * si_ptr; /* Сигнал POSIX.1b */

void * si_addr; /* Адрес в памяти, приводящий к

ошибке */

int si_band; /* Общее событие */

int si_fd; /* Описатель файла */

}

Поля si_signo, si_errno и si_code определены для всех сигналов. Остальная часть структуры может быть объединением, поэтому Вы должны работать только с теми полями, которые имеют смысл для конкретного сигнала. kill(2), сигналы POSIX.1b и SIGCHLD заполняют поля si_pid и si_uid. SIGCHLD также заполняет поля si_status, si_utime и si_stime. Поля si_int и si_ptr задаются процессом, пославшим сигнал POSIX.1b. Сигналы SIGILL, SIGFPE, SIGSEGV и SIGBUS заполняют поле si_addr адресом в памяти, который привел к ошибке. Сигнал IGPOLL заполняет si_band и si_fd. si_code указывает на причину отправки сигнала. Это значение, а не битовая маска. В следующей таблице приведены значения, которые могут вернуть любые сигналы:

Третий параметр

si_code

Значение

Причина сигнала

SI_USER

kill, sigsend или raise

SI_KERNEL

Ядро

SI_QUEUE

Sigqueue

SI_TIMER

истекло время таймера

SI_MESGQ

изменилось состояние mesq

SI_ASYNCIO

завершился AIO

SI_SIGIO

SIGIO помещен в очередь

SIGILL

ILL_ILLOPC

некорректный код инструкции

ILL_ILLOPN

неверный операнд

ILL_ILLADR

некорректный режим адресации

ILL_ILLTRP

некорректная ловушка

ILL_PRVOPC

привилегированная операция

ILL_PRVREG

привилегированный регистр

ILL_COPROC

ошибка сопроцессора

ILL_BADSTK

внутренняя ошибка стека

SIGFPE

FPE_INTDIV

деление на ноль при работе с целыми числами

FPE_INTOVF

переполнение при работе с целыми числами

FPE_FLTDIV

деление на ноль при работе с числами с плавающей запятой

FPE_FLTOVF

переполнение при работе с числами с плавающей запятой

FPE_FLTUND

нехватка значения при работе с числами с плавающей запятой

FPE_FLTRES

неточный результат при работе с числами с плавающей запятой

FPE_FLTINV

неправильная операция при работе с числами с плавающей запятой

FPE_FLTSUB

индекс вне разрешенных пределов при работе с числами с плавающей запятой

SIGSEGV

SEGV_MAPERR

адрес не соответствует объекту

SEGV_ACCERR

права на отраженный объект неправильны

SIGBUS

BUS_ADRALN

неправильное выравнивание адреса

BUS_ADRERR

несуществующий физический адрес

BUS_OBJERR

аппаратная ошибка, специфичная для объекта

SIGTRAP

TRAP_BRKPT

точка остановки процесса

TRAP_TRACE

ловушка отладки процесса

SIGCHLD

CLD_EXITED

дочерний процесс завершил работу

CLD_KILLED

работа дочернего процесса была прервана

CLD_DUMPED

дочерний процесс завершился некорректно

CLD_TRAPPED

сработала ловушка в отлаживаемом дочернем процессе

CLD_STOPPED

дочерний процесс остановлен

CLD_CONTINUED

остановленный дочерний процесс продолжил работу

SIGPOLL

POLL_IN

есть входные данные

POLL_OUT

освободились выходные буферы

POLL_MSG

есть входное сообщение

POLL_ERR

ошибка ввода/вывода

POLL_PRI

есть входные данные высокого приоритета

POLL_HUP

устройство отключено

Структура типа ucontext_tидентифицирует контекст процесса в момент доставки сигнала;

typedef struct ucontext {

struct ucontext *uc_link;

sigset_t uc_sigmask;

stack_t uc_stack;

mcontext_t uc_mcontext;

...

} ucontext_t;

uc_link указывает на контекст, который будет восстановлен при выходе из текущего контекста, если контекст создан с помощью makecontext (вторичный контекст). uc_sigmask используется для хранения сигналов, заблокированных в контексте, а uc_stack является стеком, используемым контекстом. uc_mcontext используется для хранения состояния исполнения, включая все Регистр процессора центрального процессора, указатель инструкцию и указатель на стек; mcontext_t является непрозрачным (opaque) указателем.

Функции sigaction возвращают 0 при удачном завершении работы функции и -1 при ошибке.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]