
- •Синтаксис
- •Описание
- •Возвращаемые значения
- •Найденные ошибки
- •Соответствие стандартам
- •Описание
- •Возвращаемое значение
- •Замечания
- •История linux
- •Соответствие стандартам
- •Синтаксис
- •Описание
- •Возвращаемые значения
- •Найденные ошибки
- •Соответствие стандартам
- •Наборы сигналов
- •Блокировка сигналов
- •Возвращаемые значения
- •Найденные ошибки
- •Замечания
- •Найденные ошибки
- •Синтаксис
- •Описание
Сигналы
Сигнал
1) генерируется(generate), отправляется (send), поднимается (raise);
2) ядро хранит (store) сигнал;
3) ядро обрабатывает (handle) сигнал.
Действия обработки:
Игнорировать сигнал
Захватить и обработать сигнал
Выполнить действие по умолчанию.
Название Действие по умолчанию Комментарии 1 SIGABRT Завершить +core Сигнал отправляется, если процесс вызывает системный вызов abort. 2 SIGALRM Завершить Сигнал отправляется, когда срабатывает таймер, ранее установленный с помощью системного вызова alarm. 3 SIGBUS Завершить +core Сигнал свидетельствует о некоторой аппаратной ошибке. Обычно отправляется при обращении к допустимому виртуальному адресу, для которого отсутствует соответствующая физическая страница. 4 SIGCHLD Игнор Сигнал, посылаемый родительскому процессу при завершении выполнения его потомка. 5 SIGEVG Завершить +core Сигнал свидетельствует о попытке обращения к недопустимому адресу или к области памяти, для которой у процесса недостаточно привилегий. 6 SIGFPE Завершить +core Сигнал свидетельствует о возникновении особых ситуаций, таких, как деление на ноль или переполнение операций с плавающей точкой. 7 SIGHUP Завершить Сигнал шлётся лидеру сеанса, связанному с управляющим терминалом, когда ядро обнаруживает, что терминал отсоединился. Сигнал также шлётся всем процессам группы при завершении работы лидера. Этот сигнал может быть использован при необходимости передачи сообщений процессам-демонам. 8 SIGILL Завершить +core Сигнал шлётся ядром, если процесс попытался выполнить недопустимую операцию. 9 SIGINT Завершить Сигнал шлётся всем процессам данной группы при нажатии клавиш Ctrl-C или Del. 10 SIGKILL Завершить Сигнал, при получении которого выполнение процесса завершается. Его нельзя ни перехватывать, ни игнорить. 11 SIGPIPE Завершить Сигнал шлётся при попытке записи в канал, получатель данных которого закрыл дескриптор (завершил свое выполнение). 12 SIGPOLL Завершить Сигнал отправляется при наступлении определенного события для гаджеты, которое является опрашиваемым. 13 SIGPWR Игнор Сигнал генерится при угрозе потери питания. Обычно отправляется, когда питание системы переключается на источник бесперебойного питания. 14 SIGQUIT Завершить +core Сигнал шлётся ядром всем процессам группы при нажатии клавиш Ctrl-\. 15 SIGSTOP Остановка Сигнал отправляется всем процессам группы при нажатии клавиш Ctrl-Z. Получение сигнала вызывает остановку выполнения процесса. 16 SIGSYS Завершить +core Сигнал отправляется ядром при попытке недопустимого системного вызова. 17 SIGTERM Завершить Сигнал представляет собой предупреждение о том, что процесс вскоре будет уничтожен, что даёт возможность процессу подготовиться к своему завершению. Kill (1) посылает такой сигнал. 18 SIGTTIN Остановка Сигнал генерится ядром при попытке процесса фоновой группы осуществить чтение с управляющего терминала. 19 SIGTTOU Остановка Сигнал генерится ядром при попытке процессов фоновой группы осуществить запись на управляющий терминал. 20 SIGUSR1 Завершить Сигнал, предназначенный для прикладных задач, как средство межпроцессорного взаимодействия. 21 SIGUSR2 Завершить Сигнал, предназначенный для прикладных задач, как средство межпроцессорного взаимодействия.
signal - спецификация действий по обработке сигнала
СИНТАКСИС
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,
sighandler_t handler);
#include <signal.h>
void (*signal (int sig, void (*func)(int))) (int );
ОПИСАНИЕ Системный вызов signal позволяет вызывающему процессу выбрать один из трех возможных способов реакции на получение определенного сигнала. Аргументы sig и func специфицируют, соответственно, сигнал и выбор.
Аргумент sig может иметь одно из следующих значений, за исключением SIGKILL:
SIGHUP |
01 |
|
Освобождение линии (hangup). |
SIGINT |
02 |
|
Прерывание (interrupt). |
SIGQUIT |
03 |
[1] |
Выход (quit). |
SIGILL |
04 |
[1] |
Некорректная команда (illegal instruction). Не переустанавливается при перехвате. |
SIGTRAP |
05 |
[1] |
Трассировочное прерывание (trace trap). Не переустанавливается при перехвате. |
SIGIOT |
06 |
[1] |
Машинная команда IOT. |
SIGABRT |
06 |
[1] |
Рекомендуемый синоним предыдущего. |
SIGEMT |
07 |
[1] |
Машинная команда EMT. |
SIGFPE |
08 |
[1] |
Исключительная ситуация при выполнении операции с вещественными числами (floating-point exception). |
SIGKILL |
09 |
|
Уничтожение процесса (kill). Не перехватывается и не игнорируется. |
SIGBUS |
10 |
[1] |
Ошибка шины (bus error). |
SIGSEGV |
11 |
[1] |
Некорректное обращение к сегменту памяти (segmentation violation). |
SIGSYS |
12 |
[1] |
Некорректный параметр системного вызова (bad argument to system call). |
SIGPIPE |
13 |
|
Запись в канал, из которого некому читать (write on a pipe with no one to read it). |
SIGALRM |
14 |
|
Будильник (alarm clock). |
SIGTERM |
15 |
|
Программный сигнал завершения (software termination signal). |
SIGUSR1 |
16 |
|
Определяемый пользователем сигнал 1 (user-defined signal 1). |
SIGUSR2 |
17 |
|
Определяемый пользователем сигнал 2 (user-defined signal 2). |
SIGCHLD |
18 |
[2] |
Завершение порожденного процесса (death of a child). |
SIGPWR |
19 |
[2] |
Ошибка питания (power fail). |
SIGPOLL |
22 |
[3] |
Регистрация выборочного события (selectable event pending). |
Аргумент func может иметь одно из трех значений: SIG_DFL, SIG_IGN или адрес_функции. Макросы SIG_DFL и SIG_IGN определены во включаемом файле <signal.h>. Каждый из макросов порождает уникальную константу типа "указатель на функцию типа void", заведомо не соответствующую определяемой функции.
Действия, предписываемые аргументом func, состоят в следующем:
SIG_DFL - стандартная реакция на сигнал
При получении сигнала sig терминировать процесс со всеми завершающими действиями, описанными в exit(2); см. замечание [1] ниже.
SIG_IGN - игнорирование сигнала
Игнорировать сигнал sig. Сигнал SIGKILL не может игнорироваться.
адрес_функции - перехват сигнала
При получении сигнала sig выполнить функцию обработки сигнала func; в качестве единственного аргумента функции func передается номер сигнала sig; дополнительные аргументы передаются для сигналов, вырабатываемых аппаратурой. Перед выполнением функции func устанавливается стандартная реакция на полученный сигнал, если только этот сигнал не есть SIGILL или SIGTRAP. Таким образом, чтобы перехватить следующий сигнал sig, нужно вновь обратиться к signal, задав в качестве аргумента func адрес_функции.
После завершения функции обработки сигнала процесс, получивший сигнал, возобновляет выполнение с точки прерывания.
Если сигнал, который должен быть перехвачен, поступил во время выполнения системных вызовов read(2), write(2), open(2) или ioctl(2) для медленных устройств (таких, как терминал, но не дисковый файл), pause(2) или системного вызова wait(2), который не возвращает немедленно управление из-за того, что порожденный процесс остановлен или терминирован, то функция обработки сигнала выполняется, а затем прерванный системный вызов, скорее всего, возвращает вызывающему процессу значение -1 и присваивает переменной errno значение EINTR.
Системный вызов signal не проверяет корректность аргумента func. Последствия выполнения функции обработки сигнала, заданной некорректным адресом, непредсказуемы.
Сигнал SIGKILL перехватить нельзя.
Выполнение системного вызова signal отменяет полученный, но еще не обработанный сигнал sig, если только этот сигнал не есть SIGKILL.
Системный вызов signal завершается неудачей, если:
[EINVAL]
Значение аргумента sig является недопустимым номером сигнала, включая SIGKILL.
ПРИМЕЧАНИЯ [1]
Если для сигналов, помеченных
[1], назначается стандартная реакция (SIG_DFL), то в дополнение к тому, что процесс терминируется, в текущем рабочем каталоге создается файл с образом памяти, если выполняются следующие условия:
Действующий и реальный идентификаторы пользователя процесса, получившего сигнал, совпадают.
Обычный файл с именем core существует и в него можно писать, или файл core может быть создан; создаваемый файл core будет обладать следующими характеристиками:
Режим доступа 0666, модифицированный маской режима создания файлов [см. umask(2)].
Идентификатор владельца файла равен действующему идентификатору пользователя процесса, получившего сигнал.
Идентификатор группы файла равен действующему идентификатору группы процесса, получившего сигнал.
[2]
Для сигналов SIGCHLD и SIGPWR, как и для других, в качестве func может использоваться одно из трех значений: SIG_DFL, SIG_IGN или адрес функции обработки сигнала. Однако действия, предписываемые этими значениями, отличаются от описанных выше:
SIG_DFL - игнорирование сигнала SIG_IGN - игнорирование сигнала
Если значение sig равно SIGCHLD, то процессы, порожденные вызывающим процессом, не перейдут в состояние зомби при своем завершении [см. exit(2)].
адрес_функции - перехват сигнала Если получен сигнал SIGCHLD, то на время выполнения функции обработки сигнала любой другой сигнал SIGCHLD игнорируется.
Сигнал SIGCHLD взаимодействует с системными вызовами wait и exit следующим образом:
wait
Если значение func для сигнала SIGCHLD установлено равным SIG_IGN и выполняется системный вызов wait, то после получения сигнала SIGCHLD wait блокируется до завершения всех процессов, порожденных вызывающим процессом; затем wait возвращает -1, а переменной errno присваивается значение ECHILD.
exit
Если процесс, родительский по отношению к процессу, выполняющему exit, установил для сигнала SIGCHLD действие SIG_IGN, то завершающийся процесс не переходит в состояние зомби.
При использовании конвейера следует иметь в виду, что интерпретатор команд shell делает последний процесс конвейера родительским для предшествующих процессов. Процесс, который входит в конвейер (и таким образом может стать родительским процессом), не должен перехватывать сигнал SIGCHLD.
[3]
Сигнал SIGPOLL посылается, когда для дескриптора файла, соответствующего псевдоустройству [см. intro(2)], установлена регистрация выборочных событий. Процесс должен специально запрашивать посылку этого сигнала посредством системного вызова ioctl с аргументом I_SETSIG, иначе сигнал SIGPOLL никогда не будет получен.
ДИАГНОСТИКА При успешном завершении системного вызова signal возвращается предыдущее значение func для указанного сигнала sig. В противном случае возвращается значение SIG_ERR, а переменной errno функция не присваивает код ошибки. Значение SIG_ERR определено во включаемом файле <sys/signal.h>.
СЮРПРИЗЫ При попытке изменить стандартную реакцию на сигнал SIGKILL возвращается значение SIG_DFL (а не SIG_ERR, как должно быть), а переменная errno получает значение EINVAL.
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static void sig_hand(int signo)
{
signal (signo, sig_hand);
if (signo == SIGINT)
printf(“получен сигнал SIGINT ”);
else if (signo == SIGTERM)
printf(“ получен сигнал SIGTERM”);
else {
printf(“неописанный сигнал”); exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);}
int main()
{
if (signal (SIGINT, sig_hand) == SIG_ERR)
{
printf(“ошибка SIGINT”);
exit(-1);
}
if (signal(SIGTERM, sig_hand) == SIR_ERR)
{
printf(“ошибка SIGTERM”);
exit(-2);
}
if (signal(SIGHUP, SIG_IGN) == SIR_ERR)
{
printf(“невозможно игнорировать SIGHUP”);
exit(-3);
}
for (;;) pause();
exit (0);
}
pause - ожидает сигнал
Синтаксис
#include <unistd.h>
int pause(void);
Описание
После вызова функции pause вызывающий процесс (или подзадача) приостанавливается до тех пор, пока не получит сигнал. Данный сигнал либо остановит процесс, либо заставит его вызвать функцию обработки этого сигнала. Сигнал должен отличаться от тех сигналов, которые игнорируются вызывающим процессом. Если сигнал привел к завершению выполнения вызывающего процесса, то возврата из pause не будет.
Возвращаемые значения
Функция pause возвращается только тогда, когда сигнал был перехвачен и произошел возврат из функции обработки сигнала. В этом случае она возвращает -1, а значение переменной errno становится равным EINTR.
Найденные ошибки
EINTR
сигнал был перехвачен и произошел возврат из функции обработки сигнала.
Соответствие стандартам
SVr4, SVID, POSIX, X/OPEN, BSD 4.3
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static void sig_hand(int signo)
{
signal (signo, sig_hand);
if (signo == SIGINT) printf(“\nПолучен сигнал SIGINT ”);
else
if (signo == SIGTERM) printf(“\nПолучен сигнал SIGTERM”)
else {
printf(“\nНеописанный сигнал”);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
int main()
{
if (signal (SIGINT, sig_hand) == SIG_ERR)
{
printf(“Ошибка SIGINT”);
exit(-1);}
if (signal(SIGTERM, sig_hand) == SIG_ERR)
{printf(“Ошибка SIGTERM”);
exit(-2);}
if (signal(SIGHUP, SIG_IGN) == SIG_ERR)
{printf(“невозможно игнорировать SIGHUP”);
exit(-3);}
for (;;) pause();
}
Проверка игнорирования сигнала
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
{if (signal(SIGINT, sigint_handler) == SIG_ERR) {…}}
extern const char * const sys_siglist[];
#define _GNU_SOURCE
#include <string.h>
char *strsignal(int signo);
kill - посылает сигнал процессу
ОБЗОР
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Описание
Системный вызов kill может быть использован для посылки какого-либо сигнала какому-либо процессу или группе процесса.
Если значение pid является положительным, сигнал sig посылается процессу с идентификатором pid.
Если pid равен 0, то sig посылается каждому процессу, который входит в группу текущего процесса.
Если pid равен -1, то sig посылается каждому процессу, за исключением процесса с номером 1 (init), но есть нюансы, которые описываются ниже.
Если pid меньше чем -1, то sig посылается каждому процессу, который входит в группу процесса -pid.
Если sig равен 0, то никакой сигнал не посылается, а только выполняется проверка на ошибку.
Возвращаемое значение
В случае успеха, возвращается ноль. При ошибке, возвращается -1 и значение errno устанавливается соответствующим образом.
ОШИБКИ
EINVAL
Задан неправильный сигнал.
ESRCH
Идентификатор процесса pid или группа процесса не существуют. Заметим, что существующий процесс может быть зомби - процессом, который уже находится в состоянии завершения, но пока в котором пока ещё не выполнился wait().
EPERM
Текущий процесс не имеет прав на посылку сигнала к любому из указанных процессов. Процессы, которые имеют права на посылку сигнала процессу с номером pid должны иметь привилегии суперпользователя или, реальный или эффективный идентификатор пользователя процесса, посылающего сигнал, должен быть таким же как реальный или эффективный идентификатор пользователя процесса, принимающего сигнал. В случае, когда посылающий и принимающий процессы относятся к одной сессии, становится доступным сигнал SIGCONT.