Blame


1 9acaad45 2004-10-23 devnull /*
2 fa325e9b 2020-01-10 cross * Signal handling for Plan 9 programs.
3 fa325e9b 2020-01-10 cross * We stubbornly use the strings from Plan 9 instead
4 fa325e9b 2020-01-10 cross * 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 5f8fa947 2004-12-26 devnull * We do not handle SIGABRT or SIGSEGV, mainly because
11 5f8fa947 2004-12-26 devnull * the thread library queues its notes for later, and we want
12 5f8fa947 2004-12-26 devnull * to dump core with the state at time of delivery.
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 f3ecd8ae 2005-02-08 devnull int flags;
35 9acaad45 2004-10-23 devnull };
36 9acaad45 2004-10-23 devnull
37 f3ecd8ae 2005-02-08 devnull enum
38 f3ecd8ae 2005-02-08 devnull {
39 f3ecd8ae 2005-02-08 devnull Restart = 1<<0,
40 d35c1bb2 2008-07-12 rsc Ignore = 1<<1,
41 d35c1bb2 2008-07-12 rsc NoNotify = 1<<2,
42 f3ecd8ae 2005-02-08 devnull };
43 10f14b04 2005-01-16 devnull
44 9acaad45 2004-10-23 devnull static Sig sigs[] = {
45 f3ecd8ae 2005-02-08 devnull SIGHUP, 0,
46 f3ecd8ae 2005-02-08 devnull SIGINT, 0,
47 f3ecd8ae 2005-02-08 devnull SIGQUIT, 0,
48 f3ecd8ae 2005-02-08 devnull SIGILL, 0,
49 f3ecd8ae 2005-02-08 devnull SIGTRAP, 0,
50 f3ecd8ae 2005-02-08 devnull /* SIGABRT, 0, */
51 d2c4ee9e 2003-11-24 devnull #ifdef SIGEMT
52 f3ecd8ae 2005-02-08 devnull SIGEMT, 0,
53 d2c4ee9e 2003-11-24 devnull #endif
54 f3ecd8ae 2005-02-08 devnull SIGFPE, 0,
55 f3ecd8ae 2005-02-08 devnull SIGBUS, 0,
56 f3ecd8ae 2005-02-08 devnull /* SIGSEGV, 0, */
57 f3ecd8ae 2005-02-08 devnull SIGCHLD, Restart|Ignore,
58 f3ecd8ae 2005-02-08 devnull SIGSYS, 0,
59 f3ecd8ae 2005-02-08 devnull SIGPIPE, Ignore,
60 f3ecd8ae 2005-02-08 devnull SIGALRM, 0,
61 f3ecd8ae 2005-02-08 devnull SIGTERM, 0,
62 d35c1bb2 2008-07-12 rsc SIGTSTP, Restart|Ignore|NoNotify,
63 1dd11f59 2005-03-18 devnull /* SIGTTIN, Restart|Ignore, */
64 1dd11f59 2005-03-18 devnull /* SIGTTOU, Restart|Ignore, */
65 f3ecd8ae 2005-02-08 devnull SIGXCPU, 0,
66 f3ecd8ae 2005-02-08 devnull SIGXFSZ, 0,
67 f3ecd8ae 2005-02-08 devnull SIGVTALRM, 0,
68 f3ecd8ae 2005-02-08 devnull SIGUSR1, 0,
69 f3ecd8ae 2005-02-08 devnull SIGUSR2, 0,
70 bc7da029 2005-05-07 devnull #ifdef SIGWINCH
71 d35c1bb2 2008-07-12 rsc SIGWINCH, Restart|Ignore|NoNotify,
72 bc7da029 2005-05-07 devnull #endif
73 d2c4ee9e 2003-11-24 devnull #ifdef SIGINFO
74 d35c1bb2 2008-07-12 rsc SIGINFO, Restart|Ignore|NoNotify,
75 d2c4ee9e 2003-11-24 devnull #endif
76 fd04aace 2003-11-23 devnull };
77 fd04aace 2003-11-23 devnull
78 9acaad45 2004-10-23 devnull static Sig*
79 9acaad45 2004-10-23 devnull findsig(int s)
80 9acaad45 2004-10-23 devnull {
81 9acaad45 2004-10-23 devnull int i;
82 9acaad45 2004-10-23 devnull
83 9acaad45 2004-10-23 devnull for(i=0; i<nelem(sigs); i++)
84 9acaad45 2004-10-23 devnull if(sigs[i].sig == s)
85 9acaad45 2004-10-23 devnull return &sigs[i];
86 9acaad45 2004-10-23 devnull return nil;
87 9acaad45 2004-10-23 devnull }
88 9acaad45 2004-10-23 devnull
89 9acaad45 2004-10-23 devnull /*
90 9acaad45 2004-10-23 devnull * The thread library initializes _notejmpbuf to its own
91 9acaad45 2004-10-23 devnull * routine which provides a per-pthread jump buffer.
92 9acaad45 2004-10-23 devnull * If we're not using the thread library, we assume we are
93 9acaad45 2004-10-23 devnull * single-threaded.
94 9acaad45 2004-10-23 devnull */
95 05d8c6df 2004-09-23 devnull typedef struct Jmp Jmp;
96 05d8c6df 2004-09-23 devnull struct Jmp
97 05d8c6df 2004-09-23 devnull {
98 05d8c6df 2004-09-23 devnull p9jmp_buf b;
99 05d8c6df 2004-09-23 devnull };
100 05d8c6df 2004-09-23 devnull
101 05d8c6df 2004-09-23 devnull static Jmp onejmp;
102 05d8c6df 2004-09-23 devnull
103 05d8c6df 2004-09-23 devnull static Jmp*
104 05d8c6df 2004-09-23 devnull getonejmp(void)
105 05d8c6df 2004-09-23 devnull {
106 05d8c6df 2004-09-23 devnull return &onejmp;
107 05d8c6df 2004-09-23 devnull }
108 05d8c6df 2004-09-23 devnull
109 05d8c6df 2004-09-23 devnull Jmp *(*_notejmpbuf)(void) = getonejmp;
110 9acaad45 2004-10-23 devnull static void noteinit(void);
111 fd04aace 2003-11-23 devnull
112 9acaad45 2004-10-23 devnull /*
113 fa325e9b 2020-01-10 cross * Actual signal handler.
114 9acaad45 2004-10-23 devnull */
115 aa200fe3 2004-10-22 devnull
116 9acaad45 2004-10-23 devnull static void (*notifyf)(void*, char*); /* Plan 9 handler */
117 9acaad45 2004-10-23 devnull
118 aa200fe3 2004-10-22 devnull static void
119 9acaad45 2004-10-23 devnull signotify(int sig)
120 fd04aace 2003-11-23 devnull {
121 fd04aace 2003-11-23 devnull char tmp[64];
122 05d8c6df 2004-09-23 devnull Jmp *j;
123 f3ecd8ae 2005-02-08 devnull Sig *s;
124 fd04aace 2003-11-23 devnull
125 05d8c6df 2004-09-23 devnull j = (*_notejmpbuf)();
126 9acaad45 2004-10-23 devnull switch(p9setjmp(j->b)){
127 9acaad45 2004-10-23 devnull case 0:
128 9acaad45 2004-10-23 devnull if(notifyf)
129 9acaad45 2004-10-23 devnull (*notifyf)(nil, _p9sigstr(sig, tmp));
130 9acaad45 2004-10-23 devnull /* fall through */
131 9acaad45 2004-10-23 devnull case 1: /* noted(NDFLT) */
132 9acaad45 2004-10-23 devnull if(0)print("DEFAULT %d\n", sig);
133 f3ecd8ae 2005-02-08 devnull s = findsig(sig);
134 f3ecd8ae 2005-02-08 devnull if(s && (s->flags&Ignore))
135 f3ecd8ae 2005-02-08 devnull return;
136 9acaad45 2004-10-23 devnull signal(sig, SIG_DFL);
137 9acaad45 2004-10-23 devnull raise(sig);
138 9acaad45 2004-10-23 devnull _exit(1);
139 9acaad45 2004-10-23 devnull case 2: /* noted(NCONT) */
140 05d8c6df 2004-09-23 devnull if(0)print("HANDLED %d\n", sig);
141 fd04aace 2003-11-23 devnull return;
142 fd04aace 2003-11-23 devnull }
143 fd04aace 2003-11-23 devnull }
144 05d8c6df 2004-09-23 devnull
145 9acaad45 2004-10-23 devnull static void
146 9acaad45 2004-10-23 devnull signonotify(int sig)
147 9acaad45 2004-10-23 devnull {
148 9acaad45 2004-10-23 devnull USED(sig);
149 9acaad45 2004-10-23 devnull }
150 9acaad45 2004-10-23 devnull
151 fd04aace 2003-11-23 devnull int
152 05d8c6df 2004-09-23 devnull noted(int v)
153 05d8c6df 2004-09-23 devnull {
154 05d8c6df 2004-09-23 devnull p9longjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1);
155 05d8c6df 2004-09-23 devnull abort();
156 05d8c6df 2004-09-23 devnull return 0;
157 05d8c6df 2004-09-23 devnull }
158 05d8c6df 2004-09-23 devnull
159 9acaad45 2004-10-23 devnull int
160 9acaad45 2004-10-23 devnull notify(void (*f)(void*, char*))
161 9acaad45 2004-10-23 devnull {
162 9acaad45 2004-10-23 devnull static int init;
163 9acaad45 2004-10-23 devnull
164 9acaad45 2004-10-23 devnull notifyf = f;
165 9acaad45 2004-10-23 devnull if(!init){
166 9acaad45 2004-10-23 devnull init = 1;
167 9acaad45 2004-10-23 devnull noteinit();
168 9acaad45 2004-10-23 devnull }
169 9acaad45 2004-10-23 devnull return 0;
170 9acaad45 2004-10-23 devnull }
171 9acaad45 2004-10-23 devnull
172 9acaad45 2004-10-23 devnull /*
173 9acaad45 2004-10-23 devnull * Nonsense about enabling and disabling signals.
174 9acaad45 2004-10-23 devnull */
175 5f8fa947 2004-12-26 devnull typedef void Sighandler(int);
176 5f8fa947 2004-12-26 devnull static Sighandler*
177 9acaad45 2004-10-23 devnull handler(int s)
178 9acaad45 2004-10-23 devnull {
179 9acaad45 2004-10-23 devnull struct sigaction sa;
180 9acaad45 2004-10-23 devnull
181 9acaad45 2004-10-23 devnull sigaction(s, nil, &sa);
182 9acaad45 2004-10-23 devnull return sa.sa_handler;
183 9acaad45 2004-10-23 devnull }
184 9acaad45 2004-10-23 devnull
185 10f14b04 2005-01-16 devnull static int
186 5f8fa947 2004-12-26 devnull notesetenable(int sig, int enabled)
187 fd04aace 2003-11-23 devnull {
188 10f14b04 2005-01-16 devnull sigset_t mask, omask;
189 fd04aace 2003-11-23 devnull
190 9acaad45 2004-10-23 devnull if(sig == 0)
191 10f14b04 2005-01-16 devnull return -1;
192 aa200fe3 2004-10-22 devnull
193 9acaad45 2004-10-23 devnull sigemptyset(&mask);
194 9acaad45 2004-10-23 devnull sigaddset(&mask, sig);
195 10f14b04 2005-01-16 devnull sigprocmask(enabled ? SIG_UNBLOCK : SIG_BLOCK, &mask, &omask);
196 fa325e9b 2020-01-10 cross return !sigismember(&omask, sig);
197 9acaad45 2004-10-23 devnull }
198 9acaad45 2004-10-23 devnull
199 10f14b04 2005-01-16 devnull int
200 5f8fa947 2004-12-26 devnull noteenable(char *msg)
201 9acaad45 2004-10-23 devnull {
202 10f14b04 2005-01-16 devnull return notesetenable(_p9strsig(msg), 1);
203 9acaad45 2004-10-23 devnull }
204 9acaad45 2004-10-23 devnull
205 10f14b04 2005-01-16 devnull int
206 5f8fa947 2004-12-26 devnull notedisable(char *msg)
207 9acaad45 2004-10-23 devnull {
208 10f14b04 2005-01-16 devnull return notesetenable(_p9strsig(msg), 0);
209 9acaad45 2004-10-23 devnull }
210 9acaad45 2004-10-23 devnull
211 10f14b04 2005-01-16 devnull static int
212 9acaad45 2004-10-23 devnull notifyseton(int s, int on)
213 9acaad45 2004-10-23 devnull {
214 9acaad45 2004-10-23 devnull Sig *sig;
215 10f14b04 2005-01-16 devnull struct sigaction sa, osa;
216 9acaad45 2004-10-23 devnull
217 9acaad45 2004-10-23 devnull sig = findsig(s);
218 9acaad45 2004-10-23 devnull if(sig == nil)
219 10f14b04 2005-01-16 devnull return -1;
220 669250d1 2003-12-03 devnull memset(&sa, 0, sizeof sa);
221 9acaad45 2004-10-23 devnull sa.sa_handler = on ? signotify : signonotify;
222 f3ecd8ae 2005-02-08 devnull if(sig->flags&Restart)
223 9acaad45 2004-10-23 devnull sa.sa_flags |= SA_RESTART;
224 aa200fe3 2004-10-22 devnull
225 aa200fe3 2004-10-22 devnull /*
226 9acaad45 2004-10-23 devnull * We can't allow signals within signals because there's
227 9acaad45 2004-10-23 devnull * only one jump buffer.
228 aa200fe3 2004-10-22 devnull */
229 aa200fe3 2004-10-22 devnull sigfillset(&sa.sa_mask);
230 9acaad45 2004-10-23 devnull
231 9acaad45 2004-10-23 devnull /*
232 9acaad45 2004-10-23 devnull * Install handler.
233 9acaad45 2004-10-23 devnull */
234 10f14b04 2005-01-16 devnull sigaction(sig->sig, &sa, &osa);
235 10f14b04 2005-01-16 devnull return osa.sa_handler == signotify;
236 aa200fe3 2004-10-22 devnull }
237 aa200fe3 2004-10-22 devnull
238 10f14b04 2005-01-16 devnull int
239 9acaad45 2004-10-23 devnull notifyon(char *msg)
240 aa200fe3 2004-10-22 devnull {
241 10f14b04 2005-01-16 devnull return notifyseton(_p9strsig(msg), 1);
242 fd04aace 2003-11-23 devnull }
243 aa200fe3 2004-10-22 devnull
244 10f14b04 2005-01-16 devnull int
245 9acaad45 2004-10-23 devnull notifyoff(char *msg)
246 aa200fe3 2004-10-22 devnull {
247 10f14b04 2005-01-16 devnull return notifyseton(_p9strsig(msg), 0);
248 aa200fe3 2004-10-22 devnull }
249 aa200fe3 2004-10-22 devnull
250 9acaad45 2004-10-23 devnull /*
251 9acaad45 2004-10-23 devnull * Initialization follows sigs table.
252 9acaad45 2004-10-23 devnull */
253 9acaad45 2004-10-23 devnull static void
254 9acaad45 2004-10-23 devnull noteinit(void)
255 aa200fe3 2004-10-22 devnull {
256 aa200fe3 2004-10-22 devnull int i;
257 9acaad45 2004-10-23 devnull Sig *sig;
258 aa200fe3 2004-10-22 devnull
259 9acaad45 2004-10-23 devnull for(i=0; i<nelem(sigs); i++){
260 9acaad45 2004-10-23 devnull sig = &sigs[i];
261 9acaad45 2004-10-23 devnull /*
262 9acaad45 2004-10-23 devnull * If someone has already installed a handler,
263 9acaad45 2004-10-23 devnull * It's probably some ld preload nonsense,
264 9acaad45 2004-10-23 devnull * like pct (a SIGVTALRM-based profiler).
265 5f8fa947 2004-12-26 devnull * Or maybe someone has already called notifyon/notifyoff.
266 9acaad45 2004-10-23 devnull * Leave it alone.
267 9acaad45 2004-10-23 devnull */
268 9acaad45 2004-10-23 devnull if(handler(sig->sig) != SIG_DFL)
269 9acaad45 2004-10-23 devnull continue;
270 d35c1bb2 2008-07-12 rsc notifyseton(sig->sig, !(sig->flags&NoNotify));
271 9acaad45 2004-10-23 devnull }
272 aa200fe3 2004-10-22 devnull }