Blame


1 9acaad45 2004-10-23 devnull /*
2 9acaad45 2004-10-23 devnull * Signal handling for Plan 9 programs.
3 9acaad45 2004-10-23 devnull * We stubbornly use the strings from Plan 9 instead
4 9acaad45 2004-10-23 devnull * of the enumerated Unix constants.
5 9acaad45 2004-10-23 devnull * There are some weird translations. In particular,
6 9acaad45 2004-10-23 devnull * a "kill" note is the same as SIGTERM in Unix.
7 9acaad45 2004-10-23 devnull * There is no equivalent note to Unix's SIGKILL, since
8 9acaad45 2004-10-23 devnull * it's not a deliverable signal anyway.
9 9acaad45 2004-10-23 devnull *
10 9acaad45 2004-10-23 devnull * We do not handle SIGABRT or SIGSEGV, mainly so that
11 9acaad45 2004-10-23 devnull * stack traces show the original source of the signal instead
12 9acaad45 2004-10-23 devnull * of notifysigf.
13 9acaad45 2004-10-23 devnull *
14 9acaad45 2004-10-23 devnull * We have to add some extra entry points to provide the
15 9acaad45 2004-10-23 devnull * ability to tweak which signals are deliverable and which
16 9acaad45 2004-10-23 devnull * are acted upon. Notifydisable and notifyenable play with
17 9acaad45 2004-10-23 devnull * the process signal mask. Notifyignore enables the signal
18 9acaad45 2004-10-23 devnull * but will not call notifyf when it comes in. This is occasionally
19 9acaad45 2004-10-23 devnull * useful.
20 9acaad45 2004-10-23 devnull */
21 9acaad45 2004-10-23 devnull
22 fd04aace 2003-11-23 devnull #include <u.h>
23 8ad51794 2004-03-25 devnull #include <signal.h>
24 fd04aace 2003-11-23 devnull #define NOPLAN9DEFINES
25 fd04aace 2003-11-23 devnull #include <libc.h>
26 fd04aace 2003-11-23 devnull
27 fd04aace 2003-11-23 devnull extern char *_p9sigstr(int, char*);
28 9acaad45 2004-10-23 devnull extern int _p9strsig(char*);
29 fd04aace 2003-11-23 devnull
30 9acaad45 2004-10-23 devnull typedef struct Sig Sig;
31 9acaad45 2004-10-23 devnull struct Sig
32 9acaad45 2004-10-23 devnull {
33 9acaad45 2004-10-23 devnull int sig; /* signal number */
34 9acaad45 2004-10-23 devnull int restart; /* do we restart the system call after this signal is handled? */
35 9acaad45 2004-10-23 devnull int enabled; /* is this signal enabled (not masked)? */
36 9acaad45 2004-10-23 devnull int notified; /* do we call the notify function for this signal? */
37 9acaad45 2004-10-23 devnull };
38 9acaad45 2004-10-23 devnull
39 9acaad45 2004-10-23 devnull /* initial settings; for current status, ask the kernel */
40 9acaad45 2004-10-23 devnull static Sig sigs[] = {
41 9acaad45 2004-10-23 devnull SIGHUP, 0, 1, 1,
42 9acaad45 2004-10-23 devnull SIGINT, 0, 1, 1,
43 9acaad45 2004-10-23 devnull SIGQUIT, 0, 1, 1,
44 9acaad45 2004-10-23 devnull SIGILL, 0, 1, 1,
45 9acaad45 2004-10-23 devnull SIGTRAP, 0, 1, 1,
46 9acaad45 2004-10-23 devnull /* SIGABRT, 0, 1, 1, */
47 d2c4ee9e 2003-11-24 devnull #ifdef SIGEMT
48 9acaad45 2004-10-23 devnull SIGEMT, 0, 1, 1,
49 d2c4ee9e 2003-11-24 devnull #endif
50 9acaad45 2004-10-23 devnull SIGFPE, 0, 1, 1,
51 9acaad45 2004-10-23 devnull SIGBUS, 0, 1, 1,
52 9acaad45 2004-10-23 devnull /* SIGSEGV, 0, 1, 1, */
53 9acaad45 2004-10-23 devnull SIGCHLD, 1, 0, 1,
54 9acaad45 2004-10-23 devnull SIGSYS, 0, 1, 1,
55 9acaad45 2004-10-23 devnull SIGPIPE, 0, 0, 1,
56 9acaad45 2004-10-23 devnull SIGALRM, 0, 1, 1,
57 9acaad45 2004-10-23 devnull SIGTERM, 0, 1, 1,
58 9acaad45 2004-10-23 devnull SIGTSTP, 1, 0, 1,
59 9acaad45 2004-10-23 devnull SIGTTIN, 1, 0, 1,
60 9acaad45 2004-10-23 devnull SIGTTOU, 1, 0, 1,
61 9acaad45 2004-10-23 devnull SIGXCPU, 0, 1, 1,
62 9acaad45 2004-10-23 devnull SIGXFSZ, 0, 1, 1,
63 9acaad45 2004-10-23 devnull SIGVTALRM, 0, 1, 1,
64 9acaad45 2004-10-23 devnull SIGUSR1, 0, 1, 1,
65 9acaad45 2004-10-23 devnull SIGUSR2, 0, 1, 1,
66 9acaad45 2004-10-23 devnull SIGWINCH, 1, 0, 1,
67 d2c4ee9e 2003-11-24 devnull #ifdef SIGINFO
68 9acaad45 2004-10-23 devnull SIGINFO, 1, 1, 1,
69 d2c4ee9e 2003-11-24 devnull #endif
70 fd04aace 2003-11-23 devnull };
71 fd04aace 2003-11-23 devnull
72 9acaad45 2004-10-23 devnull static Sig*
73 9acaad45 2004-10-23 devnull findsig(int s)
74 9acaad45 2004-10-23 devnull {
75 9acaad45 2004-10-23 devnull int i;
76 9acaad45 2004-10-23 devnull
77 9acaad45 2004-10-23 devnull for(i=0; i<nelem(sigs); i++)
78 9acaad45 2004-10-23 devnull if(sigs[i].sig == s)
79 9acaad45 2004-10-23 devnull return &sigs[i];
80 9acaad45 2004-10-23 devnull return nil;
81 9acaad45 2004-10-23 devnull }
82 9acaad45 2004-10-23 devnull
83 9acaad45 2004-10-23 devnull /*
84 9acaad45 2004-10-23 devnull * The thread library initializes _notejmpbuf to its own
85 9acaad45 2004-10-23 devnull * routine which provides a per-pthread jump buffer.
86 9acaad45 2004-10-23 devnull * If we're not using the thread library, we assume we are
87 9acaad45 2004-10-23 devnull * single-threaded.
88 9acaad45 2004-10-23 devnull */
89 05d8c6df 2004-09-23 devnull typedef struct Jmp Jmp;
90 05d8c6df 2004-09-23 devnull struct Jmp
91 05d8c6df 2004-09-23 devnull {
92 05d8c6df 2004-09-23 devnull p9jmp_buf b;
93 05d8c6df 2004-09-23 devnull };
94 05d8c6df 2004-09-23 devnull
95 05d8c6df 2004-09-23 devnull static Jmp onejmp;
96 05d8c6df 2004-09-23 devnull
97 05d8c6df 2004-09-23 devnull static Jmp*
98 05d8c6df 2004-09-23 devnull getonejmp(void)
99 05d8c6df 2004-09-23 devnull {
100 05d8c6df 2004-09-23 devnull return &onejmp;
101 05d8c6df 2004-09-23 devnull }
102 05d8c6df 2004-09-23 devnull
103 05d8c6df 2004-09-23 devnull Jmp *(*_notejmpbuf)(void) = getonejmp;
104 9acaad45 2004-10-23 devnull static void noteinit(void);
105 fd04aace 2003-11-23 devnull
106 9acaad45 2004-10-23 devnull /*
107 9acaad45 2004-10-23 devnull * Actual signal handler.
108 9acaad45 2004-10-23 devnull */
109 aa200fe3 2004-10-22 devnull
110 9acaad45 2004-10-23 devnull static void (*notifyf)(void*, char*); /* Plan 9 handler */
111 9acaad45 2004-10-23 devnull
112 aa200fe3 2004-10-22 devnull static void
113 9acaad45 2004-10-23 devnull signotify(int sig)
114 fd04aace 2003-11-23 devnull {
115 fd04aace 2003-11-23 devnull int v;
116 fd04aace 2003-11-23 devnull char tmp[64];
117 05d8c6df 2004-09-23 devnull Jmp *j;
118 fd04aace 2003-11-23 devnull
119 05d8c6df 2004-09-23 devnull j = (*_notejmpbuf)();
120 9acaad45 2004-10-23 devnull switch(p9setjmp(j->b)){
121 9acaad45 2004-10-23 devnull case 0:
122 9acaad45 2004-10-23 devnull if(notifyf)
123 9acaad45 2004-10-23 devnull (*notifyf)(nil, _p9sigstr(sig, tmp));
124 9acaad45 2004-10-23 devnull /* fall through */
125 9acaad45 2004-10-23 devnull case 1: /* noted(NDFLT) */
126 9acaad45 2004-10-23 devnull if(0)print("DEFAULT %d\n", sig);
127 9acaad45 2004-10-23 devnull signal(sig, SIG_DFL);
128 9acaad45 2004-10-23 devnull raise(sig);
129 9acaad45 2004-10-23 devnull _exit(1);
130 9acaad45 2004-10-23 devnull case 2: /* noted(NCONT) */
131 05d8c6df 2004-09-23 devnull if(0)print("HANDLED %d\n", sig);
132 fd04aace 2003-11-23 devnull return;
133 fd04aace 2003-11-23 devnull }
134 fd04aace 2003-11-23 devnull }
135 05d8c6df 2004-09-23 devnull
136 9acaad45 2004-10-23 devnull static void
137 9acaad45 2004-10-23 devnull signonotify(int sig)
138 9acaad45 2004-10-23 devnull {
139 9acaad45 2004-10-23 devnull USED(sig);
140 9acaad45 2004-10-23 devnull }
141 9acaad45 2004-10-23 devnull
142 fd04aace 2003-11-23 devnull int
143 05d8c6df 2004-09-23 devnull noted(int v)
144 05d8c6df 2004-09-23 devnull {
145 05d8c6df 2004-09-23 devnull p9longjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1);
146 05d8c6df 2004-09-23 devnull abort();
147 05d8c6df 2004-09-23 devnull return 0;
148 05d8c6df 2004-09-23 devnull }
149 05d8c6df 2004-09-23 devnull
150 9acaad45 2004-10-23 devnull int
151 9acaad45 2004-10-23 devnull notify(void (*f)(void*, char*))
152 9acaad45 2004-10-23 devnull {
153 9acaad45 2004-10-23 devnull int i;
154 9acaad45 2004-10-23 devnull static int init;
155 9acaad45 2004-10-23 devnull
156 9acaad45 2004-10-23 devnull notifyf = f;
157 9acaad45 2004-10-23 devnull if(!init){
158 9acaad45 2004-10-23 devnull init = 1;
159 9acaad45 2004-10-23 devnull noteinit();
160 9acaad45 2004-10-23 devnull }
161 9acaad45 2004-10-23 devnull return 0;
162 9acaad45 2004-10-23 devnull }
163 9acaad45 2004-10-23 devnull
164 9acaad45 2004-10-23 devnull /*
165 9acaad45 2004-10-23 devnull * Nonsense about enabling and disabling signals.
166 9acaad45 2004-10-23 devnull */
167 9acaad45 2004-10-23 devnull static void(*)(int)
168 9acaad45 2004-10-23 devnull handler(int s)
169 9acaad45 2004-10-23 devnull {
170 9acaad45 2004-10-23 devnull struct sigaction sa;
171 9acaad45 2004-10-23 devnull
172 9acaad45 2004-10-23 devnull sigaction(s, nil, &sa);
173 9acaad45 2004-10-23 devnull return sa.sa_handler;
174 9acaad45 2004-10-23 devnull }
175 9acaad45 2004-10-23 devnull
176 aa200fe3 2004-10-22 devnull static void
177 9acaad45 2004-10-23 devnull notifysetenable(int sig, int enabled)
178 fd04aace 2003-11-23 devnull {
179 9acaad45 2004-10-23 devnull sigset_t mask;
180 fd04aace 2003-11-23 devnull
181 9acaad45 2004-10-23 devnull if(sig == 0)
182 aa200fe3 2004-10-22 devnull return;
183 aa200fe3 2004-10-22 devnull
184 9acaad45 2004-10-23 devnull sigemptyset(&mask);
185 9acaad45 2004-10-23 devnull sigaddset(&mask, sig);
186 9acaad45 2004-10-23 devnull sigprocmask(enabled ? SIG_UNBLOCK : SIG_BLOCK, &mask, nil);
187 9acaad45 2004-10-23 devnull }
188 9acaad45 2004-10-23 devnull
189 9acaad45 2004-10-23 devnull void
190 9acaad45 2004-10-23 devnull notifyenable(char *msg)
191 9acaad45 2004-10-23 devnull {
192 9acaad45 2004-10-23 devnull notifyenablex(_p9strsig(msg), 1);
193 9acaad45 2004-10-23 devnull }
194 9acaad45 2004-10-23 devnull
195 9acaad45 2004-10-23 devnull void
196 9acaad45 2004-10-23 devnull notifydisable(char *msg)
197 9acaad45 2004-10-23 devnull {
198 9acaad45 2004-10-23 devnull notifyenablex(_p9strsig(msg), 0);
199 9acaad45 2004-10-23 devnull }
200 9acaad45 2004-10-23 devnull
201 9acaad45 2004-10-23 devnull static void
202 9acaad45 2004-10-23 devnull notifyseton(int s, int on)
203 9acaad45 2004-10-23 devnull {
204 9acaad45 2004-10-23 devnull Sig *sig;
205 9acaad45 2004-10-23 devnull struct sigaction sa;
206 9acaad45 2004-10-23 devnull
207 9acaad45 2004-10-23 devnull sig = findsig(s);
208 9acaad45 2004-10-23 devnull if(sig == nil)
209 9acaad45 2004-10-23 devnull return;
210 9acaad45 2004-10-23 devnull notifyenable(msg);
211 669250d1 2003-12-03 devnull memset(&sa, 0, sizeof sa);
212 9acaad45 2004-10-23 devnull sa.sa_handler = on ? signotify : signonotify;
213 9acaad45 2004-10-23 devnull if(sig->restart)
214 9acaad45 2004-10-23 devnull sa.sa_flags |= SA_RESTART;
215 aa200fe3 2004-10-22 devnull
216 aa200fe3 2004-10-22 devnull /*
217 9acaad45 2004-10-23 devnull * We can't allow signals within signals because there's
218 9acaad45 2004-10-23 devnull * only one jump buffer.
219 aa200fe3 2004-10-22 devnull */
220 aa200fe3 2004-10-22 devnull sigfillset(&sa.sa_mask);
221 9acaad45 2004-10-23 devnull
222 9acaad45 2004-10-23 devnull /*
223 9acaad45 2004-10-23 devnull * Install handler.
224 9acaad45 2004-10-23 devnull */
225 9acaad45 2004-10-23 devnull sigaction(sig->sig, &sa, nil);
226 aa200fe3 2004-10-22 devnull }
227 aa200fe3 2004-10-22 devnull
228 9acaad45 2004-10-23 devnull void
229 9acaad45 2004-10-23 devnull notifyon(char *msg)
230 aa200fe3 2004-10-22 devnull {
231 9acaad45 2004-10-23 devnull notifyseton(_p9strsig(msg), 1);
232 fd04aace 2003-11-23 devnull }
233 aa200fe3 2004-10-22 devnull
234 aa200fe3 2004-10-22 devnull void
235 9acaad45 2004-10-23 devnull notifyoff(char *msg)
236 aa200fe3 2004-10-22 devnull {
237 9acaad45 2004-10-23 devnull notifysetoff(_p9strsig(msg), 0);
238 aa200fe3 2004-10-22 devnull }
239 aa200fe3 2004-10-22 devnull
240 9acaad45 2004-10-23 devnull /*
241 9acaad45 2004-10-23 devnull * Initialization follows sigs table.
242 9acaad45 2004-10-23 devnull */
243 9acaad45 2004-10-23 devnull static void
244 9acaad45 2004-10-23 devnull noteinit(void)
245 aa200fe3 2004-10-22 devnull {
246 aa200fe3 2004-10-22 devnull int i;
247 9acaad45 2004-10-23 devnull Sig *sig;
248 aa200fe3 2004-10-22 devnull
249 9acaad45 2004-10-23 devnull for(i=0; i<nelem(sigs); i++){
250 9acaad45 2004-10-23 devnull sig = &sigs[i];
251 9acaad45 2004-10-23 devnull /*
252 9acaad45 2004-10-23 devnull * If someone has already installed a handler,
253 9acaad45 2004-10-23 devnull * It's probably some ld preload nonsense,
254 9acaad45 2004-10-23 devnull * like pct (a SIGVTALRM-based profiler).
255 9acaad45 2004-10-23 devnull * Leave it alone.
256 9acaad45 2004-10-23 devnull */
257 9acaad45 2004-10-23 devnull if(handler(sig->sig) != SIG_DFL)
258 9acaad45 2004-10-23 devnull continue;
259 9acaad45 2004-10-23 devnull /*
260 9acaad45 2004-10-23 devnull * Should we only disable and not enable signals?
261 9acaad45 2004-10-23 devnull * (I.e. if parent has disabled for us, should we still enable?)
262 9acaad45 2004-10-23 devnull * Right now we always initialize to the state we want.
263 9acaad45 2004-10-23 devnull */
264 9acaad45 2004-10-23 devnull notifysetenable(sig->sig, sig->enabled);
265 9acaad45 2004-10-23 devnull notifyseton(sig->sig, sig->notified);
266 9acaad45 2004-10-23 devnull }
267 aa200fe3 2004-10-22 devnull }
268 aa200fe3 2004-10-22 devnull