Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

50:

51: if (!fork) exit(0);

52: sleep(60);

53:

54: return 0;

55: }

Если

si_code
равно
SI_USER
,
SI_QUEUE
или
SI_TKILL
, то доступны два дополнительных члена
siginfo_t
:
si_pid
и
si_uid
, которые представляют идентификатор процесса, пославшего сигнал и действительный идентификатор пользователя этого процесса.

Когда ядром посылается

SIGCHLD
, доступны члены
si_pid
,
si_status
,
si_utime
и
si_stime
. Первый из них,
si_pid
, задает идентификатор процесса, состояние которого изменилось [72] . Информация о новом состоянии доступна как в
si_code
(как показано в табл. 12.3) и в
si_status
, что идентично целому значению состояния, возвращаемому семейством функций
wait
.

72

Вспомните, что

SIGCHLD
посылается не только при завершении дочернего процесса, но и при его приостановке или возобновлении работы.

Последние два члена,

si_utime
и
si_stime
, определяют период времени, которое потрачено дочерним приложением на работу в пользовательском режиме и в режиме ядра, соответственно (это подобно тому, что возвращают вызовы
wait3
и
wait4
в структуре
struct rusage
). Это время измеряется в тиках часов, заданных целым числом. Количество тиков в секунду задает макрос
_SC_CLK_TCK
, определенный в
<sysconf.h>
.

SIGSEGV
,
SIGBUS
,
SIGILL
и
SIGFPE
— все они представляют
si_addr
, специфицирующий адрес, который вызвал сбой, описанный
si code
.

Ниже приведен простой пример проверки контекста сигнала. Он устанавливает обработчик сигнала для

SIGSEGV
, который печатает контекст сигнала и прерывает процесс. Нарушение сегментации генерируется попыткой обращения к
NULL
.

 1: /* catch-segv.c */

 2:

 3: #include <sys/signal.h>

 4: #include <stdlib.h>

 5: #include <stdio.h>

 6:

 7: void handler(int signo, siginfo_t *info, void *f) {

 8: printf("перехват");

 9: if (info->si_signo == SIGSEGV)

10: printf("segv accessing %p", info->si_addr);

11: if (info->si_code == SEGV_MAPERR)

12: printf("SEGV_MAPERR");

13: printf("\n");

14:

15: exit(1);

16: }

17:

18: int main {

19: struct sigactin act;

20:

21: act.sa_sigaction = handler;

22: sigemptyset(&act.sa_mask);

23: act.sa_flags = SA_SIGINFO;

24: sigaction(SIGSEGV, &act, NULL);

25:

26: *((int *)NULL) = 1 ;

27:

28: return 0;

29: }

12.7.2. Отправка данных с сигналом

Механизм

siginfo_t
также позволяет сигналам, которые посылают программы, присоединять к себе один элемент данных (этот элемент может быть указателем, что позволяет неявно передавать любой необходимый объем данных). Чтобы отправить данные, используется
union sigval
.

#include <signal.h>

union sigval {

 int sival_int;

 void *sival_ptr;

};

Любой из членов объединения —

sival_int
или
sival_ptr
— может быть установлен в требуемое значение, которое включается в
siginfo_t
, доставляемое вместе с сигналом. Чтобы сгенерировать сигнал с
union sigval
, должна использоваться функция
sigqueue
.

  • Читать дальше
  • 1
  • ...
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: