Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект 58 страниц 2002.doc
Скачиваний:
91
Добавлен:
15.06.2014
Размер:
4.07 Mб
Скачать

Набор сигналов.

Набор сигналов определяется при помощи переменной типа sigset_t, которая определна в файле <signal.h>. Набор сигналов определяет те типы сигналов, которые передаются системным вызовом. Размер типа определяется таким образом, чтобы в нём можно было определить все имеющиеся в системе сигналы.

Выбрать определённый набор сигналов можно двумя путями.

  1. Определить полный набор сигналов и удалить из него ненужные сигналы.

Взять пустой набор сигналов и добавить те сигналы, которые нужны. Каждый бит этой переменной отвечает за один

#include <signal.h>

int sigemptyset (sigset_t *set);

int sigfillset (sigset_t *set);

int sigaddset (sigset_t *set, int signo);

int sigdelset (sigset_t *set, int signo);

sigset_t mask1, mask2;

sigemptyset (& mask1);

sigaddset (& mask1, SIGINT);

sigaddset (& mask1, SIGQUIT);

sigfillset (& mask2);

sigdelset (& mask2, GIGUSR2);

Иногда такой подход называется моделью надёжных сигналов.

#include <signal.h>

int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);

struct sigaction

{

void (*sa_handler)();

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

}

  1. Функция sigemptyset инициализирует набор, очищая все биты.

  2. Функция sigfillset устанавливает в набор все сигналы, известные системе.

  3. Функции sigaddset добавляет сигнал в набор.

  4. Функции sigdelset удаляет сигнал из набора.

  5. Функция sigismember проверяет, входит ли сигнал signo в набор.

Стандартом также определён системный вызов

int sigaction(int sig struct sigaction *act, struct sigaction *oact);

который позволяет установить диспозицию сигнала, узнать её текущее значение или выполнить то и другое одновременно. В этой функции вся необходимая информация передаётся через указатель на структуру типа sigaction, которая имеет следующие поля:

struct sigaction

{

void (*sa_handler)();

void (*sa_sigaction)(int, siginfo_t *, void *);

sigset_t sa_mask;

int sa_flags;

}

sa_handler – определяет на какой сигнал необходимо установить обработчик.

sa_mask – определяет набор сигналов системы. Сигналы, заданные в этом поле будут блокироваться на время выполнения обработки. Это значит, что их обработка будет отложена до завершения функции-обработчика.

При входе в функцию – обработчик перехваченный сигнал также будет добавлен к текущей маске сигналов.

Блокируются сигналы, соответствующие биты sa_mask которых установлены в 1.

Поле sa_flags определяет флаги, которые модифицируют порядок обработки и получения сигналов.

Флаги:

SA_RESETHAND  если определена функция-обработчик, то диспозиция сигнала будет изменена на действие по умолчанию и сигнал не будет блокироваться при запуске обработчика. Если флаг не установлен, то действие по обработке сигналов не изменяется.

SA_RESTART  если определена функция-обработчик, системные вызовы типа чтение/записи для медленных устройств, выполнение которых было прервано полученным сигналом, будут автоматически перезапущены после обработки сигнала. Т. е. этот флаг позволяет продлевать операции обмена медленных устройств.

SA_SIGINFO  если этот флаг установлен, то для обработки вызывается функция обработчик, определенная sa_sigaction. Если флаг не установлен, то вызывается функция обработчик определенная полем sa_handler.

#include<signal.h>

void catchint (int signo)

{

printf (“Сигнал %d получен \n”, signo);

printf (“Сигнал обработки”);

}

main ()

{

static struct sigaction act;

act.sa_handler = catchint;

sigfillset ( &(act.sa_mask));

printf (“Вызов sleep1 \n”);

sleep (1);

printf (“Вызов sleep2 \n”);

sleep (1);

printf (“Выход”);

exit (0);

}

siginfo_tпередаёт информацию обработчику о причинах получения сигнала.

Структура включает:

  • Номер сигнала.

  • Номер ошибки.

  • Причину отправления сигнала.

struct siginfo_t

{

int si_signo ; // номер сигнала

int si_errno ; // номер ошибки

int si_code ; // причина отправления сигнала

  • - - - - - -

pid_t si_pid;

uid_t si_uid;

}

Если значение si_code > 0, то оно указывает на причину отправления сигнала.

si_signo

si_code

SIGILL

(попытка выполнить недопустимую операцию)

ILL_ILLOPC (недопустимый код операции)

ILL_ILLOPN (едопустимый операнд)

ILL_COPROC (ошибка сопроцессора)

SIGFPE

(особая ситуация при выполнении операций с плавающей точкой)

FPE_FLIDIX (ошибка деления на 0 с плав. точкой)

FPE_INTOVF (целочисленное переполнение)

SIGCLD

(сигнал завершения выполнения дочернего процесса)

CLD_EXITED (дочерний процесс завершает выполнение)

CLD_KILLED (дочерний процесс был остановлен с помощью KILL)

Если si_code <= 0, то значит, что сигнал был отправлен прикладным процессом (в этом случае структура, содержащая поле с идентификатором процесса и идентификатор пользователя).

Если si_code > 0, то указывает на причину отправления сигнала.

#include <stdio.h>

#include <signal.h>

#define TIMEOUT 5

#define MAXTRIES 5

#define LINESIZE 10

void catch (int sig)

{

time_out = TRUE;

putchar (‘\007’);

}

static int time_out;

static char answer[LINESIZE];

char *quickreply (char *promt); // функция отслеживает время ввода строки

{

int ntries;

static struct sigaction (act, oact);

act.sa_handler = catch;

sigaction (SIGALARM, &act, &oact);

for (ntries = 0; ntries < MAXTRIES; ntries++)

{

time_out = FALSE;

printf (“\n %s = ”, promt);

alarm (TIMEOUT);

gets (answer);

alarm (0);

if (!time_out) break;

}

sigaction (SIGALARM, &oact, NULL);

return (ntries = = MAXTRIES ? ((char *) 0): answer);

}