
- •Синтаксис
- •Описание
- •Возвращаемые значения
- •Найденные ошибки
- •Соответствие стандартам
- •Описание
- •Возвращаемое значение
- •Замечания
- •История linux
- •Соответствие стандартам
- •Синтаксис
- •Описание
- •Возвращаемые значения
- •Найденные ошибки
- •Соответствие стандартам
- •Наборы сигналов
- •Блокировка сигналов
- •Возвращаемые значения
- •Найденные ошибки
- •Замечания
- •Найденные ошибки
- •Синтаксис
- •Описание
Соответствие стандартам
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 при ошибке.