Троан Эрик В.
Шрифт:
FPE_FLTDIV
FPE_FLTOVF
FPE_FLTUND
FPE_FLTRES
FPE_FLTINV
FPE_FLTSUB
SIGSEGV
SEGV_MAPPER
SEGV_ACCERR
SIGBUS
BUS_ADRALN
BUS_ADRERR
BUS_OBJERR
SIGCHLD
CLD_EXITED
CLD_KILLED
CLD_DUMPED
CLD_TRAPPED
CLD_STOPPED
Чтобы помочь прояснить разные значения, которые может принимать
si_code
, рассмотрим пример, в котором SIGCHLD
генерируется четырьмя разными способами: kill
, sigqueue
, raise
(использует системный вызов tkill
) и созданием дочернего процесса, который немедленно прерывается. 1: /* sicode.с */
2:
3: #include <sys/signal.h>
4: #include <stdlib.h>
5: #include <stdio.h>
6: #include <unistd.h>
7:
8: #ifndef SI_TKILL
9: #define SI_TKILL -6
10: #endif
11:
12: void handler(int signo, siginfo_t *info, void *f ) {
13: static int count = 0;
14:
15: printf("перехвачен сигнал, отправленный ");
16: switch(info->si_code) {
17: case SI_USER:
18: printf("kill\n"); break;
19: case SI_QUEUE:
20: printf("sigqueue\n"); break;
21: case SI_TKILL:
22: printf("tkill или raise\n"); break;
23: case CLD_EXITED:
24: printf ("ядро сообщает, что дочерний процесс завершен\n"); exit(0);
25: }
26:
27: if (++count == 4) exit(1);
28: }
29:
30: int main {
31: struct sigaction act;
32: union sigval val;
33: pid_t pid = getpid;
34:
35: val.sival_int = 1234;
36:
37: act.sa_sigaction = handler;
38: sigemptyset(&act.sa_mask);
39: act.sa_flags = SA_SIGINFO;
40: sigaction(SIGCHLD, &act, NULL);
41:
42: kill(pid, SIGCHLD);
43: sigqueue(pid, SIGCHLD, val);
44: raise(SIGCHLD);
45:
46: /* Чтобы получить SIGCHLD от ядра, мы создаем дочерний процесс
47: и немедленно завершаем его. Обработчик сигнала выйдет после
48: получения сигнала от ядра, поэтому мы просто засыпаем
49: на время и позволяем программе прерваться подобным образом. */