Commit | Line | Data |
---|---|---|
7baad5ae C |
1 | /* signal.c: a Hugh-approved signal handler. */ |
2 | ||
3 | #include <signal.h> | |
4 | #include <setjmp.h> | |
5 | #include "rc.h" | |
6 | #include "sigmsgs.h" | |
7 | #include "jbwrap.h" | |
8 | ||
9 | Jbwrap slowbuf; | |
10 | volatile SIG_ATOMIC_T slow, interrupt_happened; | |
11 | void (*sighandlers[NUMOFSIGNALS])(int); | |
12 | ||
13 | static volatile SIG_ATOMIC_T sigcount, caught[NUMOFSIGNALS]; | |
14 | ||
15 | extern void catcher(int s) { | |
16 | if (forked) | |
17 | exit(1); /* exit unconditionally on a signal in a child process */ | |
18 | if (caught[s] == 0) { | |
19 | sigcount++; | |
20 | caught[s] = 1; | |
21 | } | |
22 | signal(s, catcher); | |
23 | interrupt_happened = TRUE; | |
24 | if (slow) | |
25 | longjmp(slowbuf.j, 1); | |
26 | } | |
27 | ||
28 | extern void sigchk() { | |
29 | void (*h)(int); | |
30 | int s, i; | |
31 | if (sigcount == 0) | |
32 | return; /* ho hum; life as usual */ | |
33 | if (forked) | |
34 | exit(1); /* exit unconditionally on a signal in a child process */ | |
35 | for (i = 0, s = -1; i < NUMOFSIGNALS; i++) | |
36 | if (caught[i] != 0) { | |
37 | s = i; | |
38 | --sigcount; | |
39 | caught[s] = 0; | |
40 | break; | |
41 | } | |
42 | if (s == -1) | |
43 | panic("all-zero sig vector with nonzero sigcount"); | |
44 | if ((h = sighandlers[s]) == SIG_DFL) | |
45 | panic("caught signal set to SIG_DFL"); | |
46 | if (h == SIG_IGN) | |
47 | panic("caught signal set to SIG_IGN"); | |
48 | (*h)(s); | |
49 | } | |
50 | ||
51 | extern void (*rc_signal(int s, void (*h)(int)))(int) { | |
52 | void (*old)(int); | |
53 | SIGCHK; | |
54 | old = sighandlers[s]; | |
55 | if (h == SIG_DFL || h == SIG_IGN) { | |
56 | signal(s, h); | |
57 | sighandlers[s] = h; | |
58 | } else { | |
59 | sighandlers[s] = h; | |
60 | signal(s, catcher); | |
61 | } | |
62 | return old; | |
63 | } | |
64 | ||
65 | extern void initsignal() { | |
66 | void (*h)(int); | |
67 | int i; | |
68 | for (i = 1; i < NUMOFSIGNALS; i++) { | |
69 | if ((h = signal(i, SIG_DFL)) != SIG_DFL) | |
70 | signal(i, h); | |
71 | sighandlers[i] = h; | |
72 | } | |
73 | } |