Blob


1 #include <u.h>
2 #include <signal.h>
3 #define NOPLAN9DEFINES
4 #include <libc.h>
6 extern char *_p9sigstr(int, char*);
8 static struct {
9 int sig;
10 int restart;
11 int dumb;
12 } sigs[] = {
13 SIGHUP, 0, 0,
14 SIGINT, 0, 0,
15 SIGQUIT, 0, 0,
16 SIGILL, 0, 0,
17 SIGTRAP, 0, 0,
18 /* SIGABRT, */
19 #ifdef SIGEMT
20 SIGEMT, 0, 0,
21 #endif
22 SIGFPE, 0, 0,
23 SIGBUS, 0, 0,
24 /* SIGSEGV, */
25 SIGCHLD, 1, 1,
26 SIGSYS, 0, 0,
27 SIGPIPE, 0, 1,
28 SIGALRM, 0, 0,
29 SIGTERM, 0, 0,
30 SIGTSTP, 1, 1,
31 SIGTTIN, 1, 1,
32 SIGTTOU, 1, 1,
33 SIGXCPU, 0, 0,
34 SIGXFSZ, 0, 0,
35 SIGVTALRM, 0, 0,
36 SIGUSR1, 0, 0,
37 SIGUSR2, 0, 0,
38 SIGWINCH, 1, 1,
39 #ifdef SIGINFO
40 SIGINFO, 0, 0,
41 #endif
42 };
44 typedef struct Jmp Jmp;
45 struct Jmp
46 {
47 p9jmp_buf b;
48 };
50 static Jmp onejmp;
52 static Jmp*
53 getonejmp(void)
54 {
55 return &onejmp;
56 }
58 Jmp *(*_notejmpbuf)(void) = getonejmp;
59 static void (*notifyf)(void*, char*);
60 static int alldumb;
62 static void
63 nop(int sig)
64 {
65 USED(sig);
66 }
68 static void
69 notifysigf(int sig)
70 {
71 int v;
72 char tmp[64];
73 Jmp *j;
75 j = (*_notejmpbuf)();
76 v = p9setjmp(j->b);
77 if(v == 0 && notifyf)
78 (*notifyf)(nil, _p9sigstr(sig, tmp));
79 else if(v == 2){
80 if(0)print("HANDLED %d\n", sig);
81 return;
82 }
83 if(0)print("DEFAULT %d\n", sig);
84 signal(sig, SIG_DFL);
85 raise(sig);
86 }
88 int
89 noted(int v)
90 {
91 p9longjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1);
92 abort();
93 return 0;
94 }
96 static void
97 handlesig(int s, int r, int skip)
98 {
99 struct sigaction sa, osa;
101 /*
102 * If someone has already installed a handler,
103 * It's probably some ld preload nonsense,
104 * like pct (a SIGVTALRM-based profiler).
105 * Leave it alone.
106 */
107 sigaction(s, nil, &osa);
108 if(osa.sa_handler != SIG_DFL && osa.sa_handler != notifysigf && osa.sa_handler != nop)
109 return;
111 memset(&sa, 0, sizeof sa);
112 if(skip)
113 sa.sa_handler = nop;
114 else if(notifyf == 0)
115 sa.sa_handler = SIG_DFL;
116 else
117 sa.sa_handler = notifysigf;
119 /*
120 * We assume that one jump buffer per thread
121 * is okay, which means that we can't deal with
122 * signal handlers called during signal handlers.
123 */
124 sigfillset(&sa.sa_mask);
125 if(r)
126 sa.sa_flags |= SA_RESTART;
127 else
128 sa.sa_flags &= ~SA_RESTART;
129 sigaction(s, &sa, nil);
132 int
133 notify(void (*f)(void*, char*))
135 int i;
137 notifyf = f;
138 for(i=0; i<nelem(sigs); i++)
139 handlesig(sigs[i].sig, sigs[i].restart, sigs[i].dumb && !alldumb);
140 return 0;
143 void
144 notifyall(int all)
146 int i;
148 alldumb = all;
149 for(i=0; i<nelem(sigs); i++)
150 if(sigs[i].dumb)
151 handlesig(sigs[i].sig, sigs[i].restart, !all);
154 void
155 notifyatsig(int sig, int use)
157 int i;
159 for(i=0; i<nelem(sigs); i++)
160 if(sigs[i].sig == sig)
161 handlesig(sigs[i].sig, sigs[i].restart, 0);