signal

Функция            Определяет действия по обработке сигналов.

Синтаксис          #include
                   void (*signal(int sig, void (*func)
                                 (int sig [, int subcode])))(int);

Файл, содержащий   signal.h
прототип

Описание           signal определяет как реагировать на сигнал, с но-
                   мером sig. Вы можете загрузить свою программу об-
                   работки сигнала или использовать две предопреде-
                   ленные подпрограммы, описанные в signal.h.
                   Это следующие:
                   --------------------------------------------------
                   Номер ф-ции         Значение
                   --------------------------------------------------
                   SIG_DFG             Завершить выполнение программы
                   SIG_IGN             Игнорировать сигнал этого типа
                   SIG_ERR             Определяет ошибку, возвращае-
                                       мую signal
                   --------------------------------------------------
                   Имеются предопределенные типы сигналов:
                   --------------------------------------------------
                   Тип сигнала       Значение
                   --------------------------------------------------
                   SIGABRT           Ненормальное завершение. Действие
                                     по умолчанию эквивалентно
                                     _exit(3).
                   SIGFPE            Арифметическая ошибка, возникаю-
                                     щая при делении на 0, неверной
                                     операции и т.п. Действие по
                                     умолчанию эквивалентно _exit(1).
                   SIGILL            Неверная операция. Действие
                                     по умолчанию эквивалентно
                                     _exit(1).
                   SIGINT            Прерывание по Ctrl-C. Действие
                                     по умолчанию INT 23H.
                   SIGSEGV           Неверное обращение к памяти.
                                     Действие по умолчанию экви-
                                     валентно _exit(1).
                   SIGTERM           Требование завершения программы.
                                     Действие по умолчанию экви-
                                     валентно _exit(1).
                   --------------------------------------------------

                   В signal.h определен тип, названный sig_atomic_t,
                   максимальный целый тип, который процессор может
                   автоматически запоминать при асинхронном прерыва-
                   нии (для семейства 8086 это 16-ти битовое слово,
                   целое значение для Turbo C++).

                   Когда функцией raise генерируется сигнал и в слу-
                   чае внешнего события, то присходит следующее:

                   1. Если загружена программа пользователя для об-
                      работки этого сигнала, то действие для сигнала
                      устанавливается в SIG_DFL.
                   2. Вызывается подпрограмма пользователя для обра-
                      ботки этого сигнала.

                   Подпрограмма пользователя может завершаться прос-
                   тым return или abort, _exit, exit или longjmp.

                   В Turbo C++ введено расширение стандарта ANSI C,
                   для сигналов типов SIGFPE, SIGSEGV и SIGILL.
                   Пользовательская функция обработки сигнала вызы-
                   вается с двумя или одним дополнительными парамет-
                   рами. Если с помощью raise был выдан сигнал
                   SIGFPE, SIGSEGV или SIGILL, то функция вызывается
                   с одним дополнительным параметром, целым, опреде-
                   ляющим что программа обработки сигнала вызвана.
                   Точные активизационные значения для этих сигналов
                   следующие (определены в float.h):
                   --------------------------------------------------
                   Тип сигнала        Активизационное значение
                   --------------------------------------------------
                   SIGFPE             FPE_EXPLICITGEN
                   SIGSEGV            SEGV_EXPLICITGEN
                   SIGILL             ILL__EXPLICITGEN
                   --------------------------------------------------

                   Если вызывается SIGSPE при появлении исключитель-
                   ной ситуации связанной с операциями над числами с
                   плавающей точкой, то подпрограмма пользователя
                   вызывается с дополнительным параметром определяю-
                   щим FPE_xxx тип сигнала. Если вызываеются сигналы
                   SIGILL, SIGSEGV или целочисленный вариант SIGFPE
                   (FPE_INTOVFLOW или FPE_INTDIV0), в результате ис-
                   ключительной ситуации процессора, то программа
                   обработки сигнала, определнная пользователем, вы-
                   зывается с двумя параметрами:

                   1. Тип исключительной ситуации SIGFPE, SIGSEGV
                      или SIGILL (смотри float.h, в котором приве-
                      денв все типы). Первый параметр это обычный
                      тип сигнала, определенный в ANSI C.

                   2. Целый указатель на программы обработки преры-
                      вания, которая вызвала эту программу обработки
                      сигналов. Он указывает на список регистров
                      процессора, которые были сохранены при возник-
                      новении исключительной ситуации. Регистры сох-
                      раняют в том же порядке, что и параметры прог-
                      рамм обработки прерываний: BP, DI, SI, DS, ES,
                      DX, CX, BX, AX, IP, CS, FLAGS. Для изменения
                      содержимого регистра при возврате управления,
                      измените значение в этом списке. К примеру,
                      для получения нового значения SI сделайте при-
                      мерно следующее:

                            *((int*)list_pointer+2) = new_SI_value

                      Таким образом вы получаете доступ к регистрам.
                      (Смотри пример 2).

                   Могут возникнуть или быть сгенерированы следующие
                   типы сигналов. Они соответствуют исключительным
                   ситуациям, которые может распознавать 8087, типа
                   "Деление целого на 0" и "переполнение при преры-
                   вании". Они объявлены в файле float.h
                   --------------------------------------------------
                   Сигнал SIGFPE      Значение
                   --------------------------------------------------
                   FPE_INTOVFLOW      Запущен INTO с установленным
                                      флагом OF
                   FPE_INTDIV0        Деление целого на 0
                   FPE_INVALID        Неверная операция
                   FPE_ZERODIVADE     Деление на 0
                   FPE_UNDERFLOW      Выход за нижнюю границу
                   FPE_OVERFLOW       Переполнение
                   FPE_INEXACT        Точность
                   FPE_EXPLICITGEN    Запускается программа пользова-
                                      теля raise(SIGFPE)
                   --------------------------------------------------

                   Замечание: сигналы FPE_INTOVFLOW и FPE_INTDIV0
                   генерируются при целочисленных операциях, а ос-
                   тальные при операциях над числами с плавающей
                   точкой. Исключительные ситуации при работе с чис-
                   лами с плавающей точкой генерируются в зависимос-
                   ти от слова управления сопроцессором, которое
                   можно изменить с помощью _control87. Ненормальные
                   ситуации обрабатываются Turbo C++ и не передаются
                   программе обработки сигналов.

                   Могут появиться следующие сигналы SIGSEGV:
                   --------------------------------------------------
                   Сигнал SIGSEGV     Значение
                   --------------------------------------------------
                   SEGV_BOUND         Выход за границы
                   SEGV_EXPLICITGEN   вызвана raise(SIGSEGV)
                   --------------------------------------------------

                   Замечание: Процессоры 8088 и 8086 не имеют коман-
                   ды bound. 186, 286, 386 и NEC V серии имеют эту
                   команду. Т.о. при работе с 8088 и 8086 сигнал
                   SEGV_BOUND возникнуть не может. Turbo C++ не ис-
                   пользует эти команды, однако они могут появиться
                   во встроенном коде или в ассемблерных подпрограм-
                   мах, с которыми ваша программа компонуется.

                   Могут возникнуть следующие сигналы SIGILL:

                   --------------------------------------------------
                   Сигнал SIGILL      Значение
                   --------------------------------------------------
                   ILL_EXECUTION      Попытка неверной операции
                   ILL_EXPLICITGEN    вызов raise(SIGILL)
                   --------------------------------------------------

                   Замечание: 8088, 8086, NEC V20 и NEC V30 не имеют
                   исключительной ситуации по неверной инструкции.
                   186, 286, 386, NEC V40 и NEC V50 имеют эту ситуа-
                   цию. Т.о. при работе с процессорами 8088, 8086,
                   NEC V20 и NEC V30 сигнал типа ILL_EXECUTION воз-
                   никнуть не может.

                   Замечание. Если тип сигнала SIGFPE, SIGSEGV или
                   SIGILL, то возврат из программы обработки сигнала
                   не желателен, т.к. состояние 8087 нарушено, ре-
                   зультат целочисленного деления неверен, возникло
                   переполнение, граничная операция ошибочна, или
                   была попытка выполнить несуществующую операцию.
                   Возврат может происходить только в том случае,
                   если программа обработки сигналов изменила регис-
                   тры так, что существует корректный контекст возв-
                   рата, или если сигнал был генерирован с помощью
                   raise, напрмер FPE_EXPLICITGEN, SEGV_EXPLICITGEN
                   или ILL_EXPLICITGEN. В основном, в этом случае
                   нужно печатать сообщение и завершать выполнение
                   программы с помощью _exit, exit или abort. Если
                   возврат осуществляется при другом состоянии, то в
                   этом случае результаты дальнейшей работы програм-
                   мы непредсказуемы.

Возвращаемое       При успешном завершении signal возвращае указатель
значение           на старую программу обработки сигнала для данного
                   типа сигналов. При ошибке signal возвращает
                   SIG_ERR и присваивает переменной errno значение
                   EINVAR.

Переносимость      signal поддерживается стандартом ANSI C.

Смотрите также      abort _control7, ctrlbrk exit longjmp raise
                    setjmp

Пример:

/* В этом примере загружается программа обработки
   сигнала, возникающего при нажатии Ctrl-Break */

#include
#include
#include

void Cather(int sig)
{
   printf("\n Теперь программа обработки Break");
   exit(1);
}

int main(void)
{
   signal(SIGINT,Cather);
   for(;;)
     printf("\n Сейчас основная программа \n");
}


Пример 2:

/* В этом примере загружается программа обработки
   сигналов SIGFPE, которая отлавливает состояние
   переполнения при выполнении целочисленных опе-
   раций, восстанавливает нормальное значение в
   АХ и возвращает управление */

#pragma inline
#include
#include

void Catcher(int sig, int type, int *reglist)
{
   printf("Поймал!\n");
   *(reglist+8)=3; /* AX = 3 */
}

int main(void)
{
signal(SIGFPE,Catcher);
asm    mov   ax,07FFFH         /* AX = 32767 */
asm    inc   ax                /* вызвать перепол-
                                  нение */
asm    into                     /* активизировать
                                   программу */

/* при возврате управления программа обработки
   сигнала заносит в AX значение 3. Если этого не
   сделать, то в следующей операции опять вызовет
   into (после dec) */

asm    dec   ax                  /* нет перепол. */
asm    into                      /* не активизир. */
}