BSD 4_4_Lite1 development
[unix-history] / usr / src / contrib / rc-1.4 / signal.c
CommitLineData
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
9Jbwrap slowbuf;
10volatile SIG_ATOMIC_T slow, interrupt_happened;
11void (*sighandlers[NUMOFSIGNALS])(int);
12
13static volatile SIG_ATOMIC_T sigcount, caught[NUMOFSIGNALS];
14
15extern 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
28extern 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
51extern 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
65extern 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}