Системное программирование в UNIX средствами Free Pascal

       

Пример перехват сигнала SIGINT


Этот пример демонстрирует, как можно перехватить сигнал, а также проясняет лежащий в его основе механизм сигналов. Программа sigex просто связывает с сигналом SIGINT функцию catchint, а затем выполняет набор операторов sleep и writeln. В данном примере определена структура act типа sigactionrec как глобальная, поэтому при инициализации структуры все поля, и в частности поле sa_flags обнуляются.

(* Программа sigex - демонстрирует работу sigaction *)

uses linux,stdio;

(* Простая функция для обработки сигнала SIGINT *)

procedure catchint (signo:integer);cdecl;

begin

  writeln (#$a'сигнал CATCHINT: signo=', signo);

  writeln ('сигнал CATCHINT: возврат'#$a);

end;

 

var

  act,oact:sigactionrec;

  mask:sigset_t;



begin

  (* Определение процедуры обработчика сигнала catchint *)

  (* Задание действия при получении сигнала SIGINT *)

  act.handler.sh := @catchint;

  (* Создать маску, включающую все сигналы *)

  sigfillset (@mask);

  act.sa_mask:=mask.__val[0];

  (* До вызова процедуры sigaction сигнал SIGINT

   * приводил к завершению процесса (действие по умолчанию)

   *)

  sigaction (SIGINT, @act, @oact);

  (* При получении сигнала SIGINT управление

   * будет передаваться процедуре catchint

   *)

  writeln ('вызов sleep номер 1');

  sleep (1);

  writeln ('вызов sleep номер 2');

  sleep (1);

  writeln ('вызов sleep номер 3');

  sleep (1);

  writeln ('вызов sleep номер 4');

  sleep (1);

  writeln ('Выход');

  halt(0);

end.

Сеанс обычного запуска sigex будет выглядеть так:

$ sigex

Вызов sleep номер 1

Вызов sleep номер 2

Вызов sleep номер 3

Вызов sleep номер 4

Выход

Пользователь может прервать выполнение программы sigex, нажав клавишу прерывания задания. Если она была нажата до того, как в программе sigex была выполнена процедура sigaction, то процесс просто завершит работу. Если же нажать да клавишу прерывания после вызова sigaction, то управление будет передано функции catchint:

$ sigex

Вызов sleep номер 1

<прерывание> (пользователь нажимает на клавишу прерывания)

Сигнал CATCHINT: signo = 2

Сигнал CATCHINT: возврат

Вызов sleep номер 2

Вызов sleep номер 3

Вызов sleep номер 4

Выход

Обратите внимание на то, как передается управление из тела программы процедуре catchint. После завершения процедуры catchint, управление продолжится с точки, в которой программа была прервана. Можно попробовать прервать программу sigex и в другом месте:

$ sigex

Вызов sleep номер 1

Вызов sleep номер 2

<прерывание> (пользователь нажимает на клавишу прерывания)

Сигнал CATCHINT: signo = 2

Сигнал GATCHINT: возврат

Вызов sleep номер 3

Вызов sleep номер 4

Выход



Содержание раздела