русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

SIGACTION


Дата добавления: 2014-11-28; просмотров: 2156; Нарушение авторских прав


sigaction, sigprocmask, sigpending, sigsuspend - POSIX-функции обработки сигналов.

 



СИНТАКСИС

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

int sigpending(sigset_t *set);

int sigsuspend(const sigset_t *mask);

 



ОПИСАНИЕ

Системный вызов sigaction используется для изменения действий процесса при получении соответствующего сигнала.

Параметр signum задает номер сигнала и может быть равен любому номеру, кроме SIGKILL и SIGSTOP.

Если параметр act не равен нулю, то новое действие, связянное с сигналом signum, устанавливается соответственно act. Если oldact не равен нулю, то предыдущее действие записывается в oldact.

Структура sigaction имеет следующий формат:

 



struct sigaction {

void (*sa_handler)(int);

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

sigset_t sa_mask;

int sa_flags;

void (*sa_restorer)(void);

}

 



В некоторых архитектурах используется объединение элементов, но не используйте sa_handler и sa_sigaction вместе.

Элемент sa_restorer устарел, поэтому не должен использоваться. POSIX не описывает элемент sa_restorer.

sa_handler задает тип действий процесса, связанный с сигналом signum, и может быть равен: SIG_DFL для выполнения стандартных действий, SIG_IGN для игнорирования сигнала,- или быть указателем на функцию обработки сигнала.

sa_mask задает маску сигналов, которые должны блокироваться при обработке сигнала. Также будет блокироваться и сигнал, вызвавший запуск функции, если только не были использованы флаги SA_NODEFER или SA_NOMASK.

sa_flags содержит набор флагов, которые могут влиять на поведение процесса при обработке сигнала. Он состоит из следующих флагов:

 



  • SA_NOCLDSTOP - Если signum равен SIGCHLD, то уведомление об остановке дочернего процесса не будет получено (т.е., в тех случаях, когда дочерний процесс получает сигнал SIGSTOP, SIGTSTP, SIGTTIN или SIGTTOU).
  • SA_ONESHOT или SA_RESETHAND - Восстановить поведение сигнала после одного вызова обработчика.
  • SA_ONSTACK - Вызвать обработчик сигнала в дополнительном стеке сигналов, предоставленном sigaltstack(). Если дополнительный стек недоступен, то будет использован стек по умолчанию.
  • SA_RESTART - Поведение должно соответствовать семантике сигналов BSD и позволять некоторым системным вызовам работать, в то время как идет обработка сигналов.
  • SA_NOMASK or SA_NODEFER - Не препятствовать получению сигнала при его обработке.
  • SA_SIGINFO - Обработчик сигнала требует 3-х аргументов, а не одного. В этом случае надо использовать параметр sa_sigaction вместо sa_handler. (Поле sa_sigaction было добавлено в Linux 2.1.86.)

 

Параметр siginfo_t поля sa_sigaction является структурой, состоящей из следующих элементов:

 



siginfo_t {

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

int si_errno; /* Значение errno */

int si_code; /* Код сигнала */

pid_t si_pid; /* Идентификатор процесса, пославшего сигнал */

uid_t si_uid; /* Реальный идентификатор пользователя процесса, пославшего сигнал */

int si_status; /* Выходное значение или номер сигнала */

clock_t si_utime; /* Занятое пользователем время */

clock_t si_stime; /* Использованное системное время */

sigval_t si_value; /* Значение сигнала */

int si_int; /* Сигнал POSIX.1b */

void * si_ptr; /* Сигнал POSIX.1b */

void * si_addr; /* Адрес в памяти, приводящий к ошибке */

int si_band; /* Общее событие */

int si_fd; /* Описатель файла */

}

 



Поля si_signo, si_errno и si_code определены для всех сигналов. Остальная часть структуры может быть объединением, поэтому Вы должны работать только с теми полями, которые имеют смысл для конкретного сигнала. kill(), сигналы POSIX.1b и SIGCHLD заполняют поля si_pid и si_uid. SIGCHLD также заполняет поля si_status, si_utime и si_stime. Поля si_int и si_ptr задаются процессом, пославшим сигнал POSIX.1b. Сигналы SIGILL, SIGFPE, SIGSEGV и SIGBUS заполняют поле si_addr адресом в памяти, который привел к ошибке. Сигнал IGPOLL заполняет si_band и si_fd. si_code указывает на причину отправки сигнала. Это значение, а не битовая маска. В следующей таблице приведены значения, которые могут вернуть любые сигналы:

 



  • SI_USER - kill, sigsend или raise
  • SI_KERNEL - ядро
  • SI_QUEUE - sigqueue
  • SI_TIMER - истекло время таймера
  • SI_MESGQ - изменилось состояние mesq
  • SI_ASYNCIO - завершился AIO
  • SI_SIGIO - SIGIO помещен в очередь

 

SIGILL

  • ILL_ILLOPC - некорректный код инструкции
  • ILL_ILLOPN - неверный операнд
  • ILL_ILLADR - некорректный режим адресации
  • ILL_ILLTRP - некорректная ловушка
  • ILL_PRVOPC - привилегированная операция
  • ILL_PRVREG - привилегированный регистр
  • ILL_COPROC - ошибка сопроцессора
  • ILL_BADSTK - внутренняя ошибка стека

SIGFPE

  • FPE_INTDIV - деление на ноль при работе с целыми числами
  • FPE_INTOVF - переполнение при работе с целыми числами
  • FPE_FLTDIV - деление на ноль при работе с числами с плавающей запятой
  • FPE_FLTOVF - переполнение при работе с числами с плавающей запятой
  • FPE_FLTUND - нехватка значения при работе с числами с плавающей запятой
  • FPE_FLTRES - неточный результат при работе с числами с плавающей запятой
  • FPE_FLTINV - неправильная операция при работе с числами с плавающей запятой
  • FPE_FLTSUB - индекс вне разрешенных пределов при работе с числами с плавающей запятой

SIGSEGV

  • SEGV_MAPERR - адрес не соответствует объекту
  • SEGV_ACCERR - права на отраженный объект неправильны

SIGBUS

  • BUS_ADRALN - неправильное выравнивание адреса
  • BUS_ADRERR - несуществующий физический адрес
  • BUS_OBJERR - аппаратная ошибка, специфичная для объекта

SIGTRAP

  • TRAP_BRKPT - точка остановки процесса
  • TRAP_TRACE - ловушка отладки процесса

SIGCHLD

  • CLD_EXITED - дочерний процесс завершил работу
  • CLD_KILLED - работа дочернего процесса была прервана
  • CLD_DUMPED - дочерний процесс завершился некорректно
  • CLD_TRAPPED - сработала ловушка в отлаживаемом дочернем процессе
  • CLD_STOPPED - дочерний процесс остановлен
  • CLD_CONTINUED - остановленный дочерний процесс продолжил работу

SIGPOLL

  • POLL_IN - есть входные данные
  • POLL_OUT - освободились выходные буферы
  • POLL_MSG - есть входное сообщение
  • POLL_ERR - ошибка ввода/вывода
  • POLL_PRI - есть входные данные высокого приоритета
  • POLL_HUP - устройство отключено

 

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

 



SIG_BLOCK - Набор блокируемых сигналов - объединение текущего набора и аргумента set.

SIG_UNBLOCK - Сигналы, устанавливаемое значение битов которых равно set, удаляются из списка блокируемых сигналов. Допускается разблокировать незаблокированные сигналы.

SIG_SETMASK - Набор блокируемых сигналов приравнивается к аргументу set.

Если значение поля oldset не равно нулю, то предыдущее значение маски сигналов записывается в oldset.

Системный вызов sigpending позволяет определить наличие ожидающих сигналов (полученных заблокированных сигналов). Маска ожидающих сигналов помещается в set.

Системный вызов sigsuspend временно изменяет значение маски блокировки сигналов процесса на указанное в mask, и затем приостанавливает работу процесса до получения соответствующего сигнала.

 



ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

Функции sigaction, sigprocmask и sigpending возвращают 0 при удачном завершении работы функции и -1 при ошибке. Функция sigsuspend всегда возвращает -1, обычно с кодом ошибки EINTR.

 



ЗАМЕЧАНИЯ

Невозможно заблокировать сигналы SIGKILL или SIGSTOP при помощи системного вызова sigprocmask. Попытки это сделать будут игнорироваться.

В соответствии с POSIX поведение процесса после игнорирования сигнала SIGFPE, SIGILL или SIGSEGV не определено, если эти сигналы не были посланы при помощи функций kill() или raise(). Деление целого числа на ноль имеет непредсказуемый результат. В некоторых архитектурах это приводит к появлению сигнала SIGFPE. (Более того, деление самого большого по модулю отрицательного числа на -1 приведет к появлению SIGFPE.) Игнорирование этого сигнала может привести к появлению бесконечного цикла.

POSIX (B.3.3.1.3) запрещает установку действия для сигнала SIGCHLD на SIG_IGN. Поведение BSD и SYSV в этом случае различается. Это приводит к тому, что BSD-программы, определяющие поведение SIGCHLD в SIG_IGN, в Linux не работают.

Специфические черты POSIX определяют только SA_NOCLDSTOP. Использование других флагов в sa_flags может быть неэффективно в других системах.

Флаг SA_RESETHAND совместим с одноименным флагом SVr4.

Флаг SA_NODEFER совместим с одноименным флагом SVr4 в ядре версии 1.3.9 и более поздних. В старых выпусках ядра Linux позволяли принимать и обрабатывать любые сигналы, а не только те, обработка которых уже задана (на деле это приводит к игнорированию установок sa_mask).

Названия флагов SA_RESETHAND и SA_NODEFER, необходимые для совместимости с SVr4, присутствуют в библиотеках версии 3.0.9 и более поздних.

Флаг SA_SIGINFO описан в POSIX.1b. Его поддержка была добавлена в Linux 2.2.

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

 



KILL

kill - функция, с помощью которой посылается сигнал процессу

 



СИНТАКСИС

#include <sys/types.h>

#include <signal.h>

int kill(pid_t pid, int sig);

 



ОПИСАНИЕ

Системный вызов kill используется для того, чтобы послать любой сигнал любому процессу или группе процессов.

Если pid больше 0, то сигнал sig посылается процессу pid.

Если pid равен 0, то сигнал sig посылается всем процессам текущей группы.

Если pid равен -1, то сигнал sig посылается всем процессам, кроме процесса 1 (init).

Если pid меньше -1, то сигнал sig посылается всем процессам группы -pid.

Если sig равен 0, то сигнал не посылается, но выполняется проверка на возникновение ошибок в процессе.

 



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При удачном завершении вызова возвращаемое значение равно 0. При ошибке оно равно -1, а переменной errno присваивается соответствующее значение.

 



ЗАМЕЧАНИЯ

Невозможно послать сигнал процессу номер 1 (init), потому что у него нет обработчика сигналов. Это сделано для того, чтобы не было случайных сбоев системы.

POSIX 1003.1-2001 требует, чтобы kill(-1,sig) посылал sig всем процессам, которым текущий процесс может послать сигнал, кроме, возможно, системных процессов, специфичных для текущей реализации. Linux позволяет процессу послать сигнал самому себе, однако kill(-1,sig) не посылает сигнал текущему процессу.

 



KILLPG

killpg - функция, с помощью которой отсылается сигнал группе процессов

 



СИНТАКСИС

#include <signal.h>

int killpg(int pgrp, int sig);

 



ОПИСАНИЕ

Killpg посылает сигнал sig группе процессов pgrp. Если значение pgrp равно 0, то killpg посылает сигнал текущей группе процессов. Процессы группы и процесс, посылающий сигнал, должны иметь один и тот же эффективный идентификатор пользователя, или процесс-отправитель должен иметь права суперпользователя. Единственное исключение из этого - сигнал продолжения SIGCONT может быть послан любому процессу-потомку текущего процесса.

 



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При удачном завершении возвращается 0. При ошибке возвращается -1, а переменной errno присваивается соответствующее значение.

 



Пример программ, работающих с сигналами.

Программа №1 выводит на экран строку до тех пор, пока пользователь не нажмёт комбинацию клавиш CTRL+C. При этом возникнет сигнал SIGINT, действие на который описано в функции confirmation(), которая завершит программу.

Программа №2 выполняет копирование файла (см. лр №6). При окончании копирования дочерний процесс посылает родителю сигнал с которым ассоциирована функция, выводящая сообщение об окончании копирования.

Для копирования введите в командной строке:

<имя программы> <файл источник> <файл приёмник>.

 



Текст программы №1:

 



#include <stdio.h>

#include <signal.h>

 



void confirmation(void);

 



int main(void)

{

if(signal(SIGINT,confirmation)<0) /*Назначаем обработчиком сигнала*/

{ /*функцию confirmation()*/

perror("Set signal error ");

exit(1);

}

while(1) /*В бесконечном цикле выводим строку*/

{

printf("\n\tPress [Ctrl]+[C] for stop");

sleep(1); /*Задержка в 1 секунду*/

}

return(0);

}

void confirmation(void)

{

char conf;

printf("\n\n\tContinue ?( N/n - no ): "); /*Запрашиваем подтверждение*/

conf=getchar(); /*на завершение программы*/

if((conf=='N')||(conf=='n')) exit(0); /*если да, то завершаем программу*/

else return;

}

 



Текст программы №2:

 



#include <fcntl.h>

#include <signal.h>

#define PERM 0666 /*Права доступа к создаваемому файлу*/

#define MAXLENGTH 2048 /*Размер буфера для копирования файлов*/

 



void copy(int fold,int fnew); /*Объявление функции*/

void notifyoncopy(void);

pid_t ppid;

int main(int argc,char *argv[])

{

int fdold,fdnew; /*Дескрипторы файлов*/

pid_t pid; /*Дескриптор процесса-потомка*/

if(argc!=3) /*Неправильно указаны источник*/

{ /*или приёмник*/

printf("\n\tNeed 2 arguments!\n");

exit(1);

}

if(signal(SIGINT,notifyoncopy)<0)

{

printf("\n\tError redefine signal\n");

exit(1);

}

if((fdold=open(argv[1],O_RDONLY))<0) /*Открываем файл*/

{ /*для чтения*/

printf("\n\tError open file %s\n",argv[1]);

exit(1);

}

if((fdnew=creat(argv[2],PERM))<0) /*Создаём новый файл*/

{ /*с правами PERM*/

printf("\n\tError creat file %s\n",argv[2]);

exit(1);

}

pid=fork(); /*Порождаем новый (дочерний) процесс*/

wait(); /*Ожидаем завершение дочернего процесса*/

switch(pid)

{

case -1 : /*Если pid=-1, то процесс создать нельзя */

{

printf("Error create process");

exit(1);

}

case 0 : /*pid=0 - находимся в дочернем процессе*/

{

ppid=getppid();

printf("\n\tDaughter process\n");

printf("\tFile %s content:\n",argv[1]);

copy(fdold,fdnew); /*Вызов функции копирования файлов*/

break;

}

default : /*Находимся в процессе-родителе*/

{

printf("\tParent process\n");

close(fdold); /*Закрываем дескрипторы файлов*/

close(fdnew);

}

}

return(0); /*Возвращаем управление в BASH*/

}

 



void copy(fold,fnew) /*Функция копирует содержимое первого*/

{ /*файла(fold) в созданный второй(fnew)*/

char buff[MAXLENGTH]; /*Буфер для копирования*/

ssize_t size; /*Количество прочитаных байт*/

while((size=read(fold,buff,sizeof(buff)))>0) /*Чтение*/

{ /*данных из источника*/

write(fnew,buff,size); /*Запись данных в приёмник*/

printf("%s",buff); /*Вывод данных на экран*/

}

kill(ppid,SIGINT);

return;

}

void notifyoncopy(void) /*Функция выводит сообщение на экран*/

{

char conf;

printf("\n\tCopy complete succsesful\n");

conf=getchar(); /*Ждём нажатия любой клавиши*/

return;

}

 






<== предыдущая лекция | следующая лекция ==>
Список всех возможных системных сигналов | Лабораторная работа №9


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.724 сек.