Пример перехват сигнала 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
Выход