1 /*
2 * Copyright (c) 1995 Scott Bartram
3 * Copyright (c) 1995 Steven Wallace
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: src/sys/i386/ibcs2/ibcs2_signal.c,v 1.6.4.2 1999/09/05 08:11:28 peter Exp $
29 */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/namei.h>
34 #include <sys/proc.h>
35 #include <sys/filedesc.h>
36 #include <sys/ioctl.h>
37 #include <sys/mount.h>
38 #include <sys/kernel.h>
39 #include <sys/signal.h>
40 #include <sys/signalvar.h>
41 #include <sys/malloc.h>
42 #include <sys/sysproto.h>
43
44 #include <i386/ibcs2/ibcs2_types.h>
45 #include <i386/ibcs2/ibcs2_signal.h>
46 #include <i386/ibcs2/ibcs2_proto.h>
47 #include <i386/ibcs2/ibcs2_xenix.h>
48 #include <i386/ibcs2/ibcs2_util.h>
49
50 #define sigemptyset(s) bzero((s), sizeof(*(s)))
51 #define sigismember(s, n) (*(s) & sigmask(n))
52 #define sigaddset(s, n) (*(s) |= sigmask(n))
53
54 #define ibcs2_sigmask(n) (1 << ((n) - 1))
55 #define ibcs2_sigemptyset(s) bzero((s), sizeof(*(s)))
56 #define ibcs2_sigismember(s, n) (*(s) & ibcs2_sigmask(n))
57 #define ibcs2_sigaddset(s, n) (*(s) |= ibcs2_sigmask(n))
58
59 static void ibcs2_to_bsd_sigset __P((const ibcs2_sigset_t *, sigset_t *));
60 static void bsd_to_ibcs2_sigset __P((const sigset_t *, ibcs2_sigset_t *));
61 static void ibcs2_to_bsd_sigaction __P((struct ibcs2_sigaction *,
62 struct sigaction *));
63 static void bsd_to_ibcs2_sigaction __P((struct sigaction *,
64 struct ibcs2_sigaction *));
65
66 int bsd_to_ibcs2_sig[] = {
67 0, /* 0 */
68 IBCS2_SIGHUP, /* 1 */
69 IBCS2_SIGINT, /* 2 */
70 IBCS2_SIGQUIT, /* 3 */
71 IBCS2_SIGILL, /* 4 */
72 IBCS2_SIGTRAP, /* 5 */
73 IBCS2_SIGABRT, /* 6 */
74 IBCS2_SIGEMT, /* 7 */
75 IBCS2_SIGFPE, /* 8 */
76 IBCS2_SIGKILL, /* 9 */
77 IBCS2_SIGBUS, /* 10 */
78 IBCS2_SIGSEGV, /* 11 */
79 IBCS2_SIGSYS, /* 12 */
80 IBCS2_SIGPIPE, /* 13 */
81 IBCS2_SIGALRM, /* 14 */
82 IBCS2_SIGTERM, /* 15 */
83 0, /* 16 - SIGURG */
84 IBCS2_SIGSTOP, /* 17 */
85 IBCS2_SIGTSTP, /* 18 */
86 IBCS2_SIGCONT, /* 19 */
87 IBCS2_SIGCLD, /* 20 */
88 IBCS2_SIGTTIN, /* 21 */
89 IBCS2_SIGTTOU, /* 22 */
90 IBCS2_SIGPOLL, /* 23 */
91 0, /* 24 - SIGXCPU */
92 0, /* 25 - SIGXFSZ */
93 IBCS2_SIGVTALRM, /* 26 */
94 IBCS2_SIGPROF, /* 27 */
95 IBCS2_SIGWINCH, /* 28 */
96 0, /* 29 */
97 IBCS2_SIGUSR1, /* 30 */
98 IBCS2_SIGUSR2, /* 31 */
99 };
100
101 static int ibcs2_to_bsd_sig[] = {
102 0, /* 0 */
103 SIGHUP, /* 1 */
104 SIGINT, /* 2 */
105 SIGQUIT, /* 3 */
106 SIGILL, /* 4 */
107 SIGTRAP, /* 5 */
108 SIGABRT, /* 6 */
109 SIGEMT, /* 7 */
110 SIGFPE, /* 8 */
111 SIGKILL, /* 9 */
112 SIGBUS, /* 10 */
113 SIGSEGV, /* 11 */
114 SIGSYS, /* 12 */
115 SIGPIPE, /* 13 */
116 SIGALRM, /* 14 */
117 SIGTERM, /* 15 */
118 SIGUSR1, /* 16 */
119 SIGUSR2, /* 17 */
120 SIGCHLD, /* 18 */
121 0, /* 19 - SIGPWR */
122 SIGWINCH, /* 20 */
123 0, /* 21 */
124 SIGIO, /* 22 */
125 SIGSTOP, /* 23 */
126 SIGTSTP, /* 24 */
127 SIGCONT, /* 25 */
128 SIGTTIN, /* 26 */
129 SIGTTOU, /* 27 */
130 SIGVTALRM, /* 28 */
131 SIGPROF, /* 29 */
132 0, /* 30 */
133 0, /* 31 */
134 };
135
136 void
137 ibcs2_to_bsd_sigset(iss, bss)
138 const ibcs2_sigset_t *iss;
139 sigset_t *bss;
140 {
141 int i, newsig;
142
143 sigemptyset(bss);
144 for (i = 1; i < IBCS2_NSIG; i++) {
145 if (ibcs2_sigismember(iss, i)) {
146 newsig = ibcs2_to_bsd_sig[i];
147 if (newsig)
148 sigaddset(bss, newsig);
149 }
150 }
151 }
152
153 static void
154 bsd_to_ibcs2_sigset(bss, iss)
155 const sigset_t *bss;
156 ibcs2_sigset_t *iss;
157 {
158 int i, newsig;
159
160 ibcs2_sigemptyset(iss);
161 for (i = 1; i < NSIG; i++) {
162 if (sigismember(bss, i)) {
163 newsig = bsd_to_ibcs2_sig[i];
164 if (newsig)
165 ibcs2_sigaddset(iss, newsig);
166 }
167 }
168 }
169
170 static void
171 ibcs2_to_bsd_sigaction(isa, bsa)
172 struct ibcs2_sigaction *isa;
173 struct sigaction *bsa;
174 {
175
176 bsa->sa_handler = isa->sa_handler;
177 ibcs2_to_bsd_sigset(&isa->sa_mask, &bsa->sa_mask);
178 bsa->sa_flags = 0; /* ??? SA_NODEFER */
179 if ((isa->sa_flags & IBCS2_SA_NOCLDSTOP) != 0)
180 bsa->sa_flags |= SA_NOCLDSTOP;
181 }
182
183 static void
184 bsd_to_ibcs2_sigaction(bsa, isa)
185 struct sigaction *bsa;
186 struct ibcs2_sigaction *isa;
187 {
188
189 isa->sa_handler = bsa->sa_handler;
190 bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->sa_mask);
191 isa->sa_flags = 0;
192 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
193 isa->sa_flags |= IBCS2_SA_NOCLDSTOP;
194 }
195
196 int
197 ibcs2_sigaction(p, uap, retval)
198 register struct proc *p;
199 struct ibcs2_sigaction_args *uap;
200 int *retval;
201 {
202 struct ibcs2_sigaction *nisa, *oisa, tmpisa;
203 struct sigaction *nbsa, *obsa, tmpbsa;
204 struct sigaction_args sa;
205 caddr_t sg;
206 int error;
207
208 sg = stackgap_init();
209 nisa = SCARG(uap, act);
210 oisa = SCARG(uap, oact);
211
212 if (oisa != NULL)
213 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
214 else
215 obsa = NULL;
216
217 if (nisa != NULL) {
218 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
219 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
220 return error;
221 ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
222 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
223 return error;
224 } else
225 nbsa = NULL;
226
227 SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, sig)];
228 SCARG(&sa, nsa) = nbsa;
229 SCARG(&sa, osa) = obsa;
230
231 if ((error = sigaction(p, &sa, retval)) != 0)
232 return error;
233
234 if (oisa != NULL) {
235 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
236 return error;
237 bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
238 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
239 return error;
240 }
241
242 return 0;
243 }
244
245 int
246 ibcs2_sigsys(p, uap, retval)
247 register struct proc *p;
248 struct ibcs2_sigsys_args *uap;
249 int *retval;
250 {
251 struct sigaction sa;
252 int signum = ibcs2_to_bsd_sig[IBCS2_SIGNO(SCARG(uap, sig))];
253 int error;
254 caddr_t sg = stackgap_init();
255
256 if (signum <= 0 || signum >= IBCS2_NSIG) {
257 if (IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGNAL_MASK ||
258 IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
259 *retval = (int)IBCS2_SIG_ERR;
260 return EINVAL;
261 }
262
263 switch (IBCS2_SIGCALL(SCARG(uap, sig))) {
264 case IBCS2_SIGSET_MASK:
265 /*
266 * Check for SIG_HOLD action.
267 * Otherwise, perform signal() except with different sa_flags.
268 */
269 if (SCARG(uap, fp) != IBCS2_SIG_HOLD) {
270 /* add sig to mask before exececuting signal handler */
271 sa.sa_flags = 0;
272 goto ibcs2_sigset;
273 }
274 /* else fallthrough to sighold */
275
276 case IBCS2_SIGHOLD_MASK:
277 {
278 struct sigprocmask_args sa;
279
280 SCARG(&sa, how) = SIG_BLOCK;
281 SCARG(&sa, mask) = sigmask(signum);
282 return sigprocmask(p, &sa, retval);
283 }
284
285 case IBCS2_SIGNAL_MASK:
286 {
287 struct sigaction_args sa_args;
288 struct sigaction *nbsa, *obsa;
289
290 /* do not automatically block signal */
291 sa.sa_flags = SA_NODEFER;
292 #ifdef SA_RESETHAND
293 if((signum != IBCS2_SIGILL) &&
294 (signum != IBCS2_SIGTRAP) &&
295 (signum != IBCS2_SIGPWR))
296 /* set to SIG_DFL before executing handler */
297 sa.sa_flags |= SA_RESETHAND;
298 #endif
299 ibcs2_sigset:
300 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
301 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
302 SCARG(&sa_args, signum) = signum;
303 SCARG(&sa_args, nsa) = nbsa;
304 SCARG(&sa_args, osa) = obsa;
305
306 sa.sa_handler = SCARG(uap, fp);
307 sigemptyset(&sa.sa_mask);
308 #if 0
309 if (signum != SIGALRM)
310 sa.sa_flags |= SA_RESTART;
311 #endif
312 *retval = (int)IBCS2_SIG_ERR; /* init error return */
313
314 /* perform native sigaction() */
315 if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
316 return error;
317 if ((error = sigaction(p, &sa_args, retval)) != 0) {
318 DPRINTF(("signal: sigaction failed: %d\n",
319 error));
320 return error;
321 }
322 if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
323 return error;
324 *retval = (int)sa.sa_handler;
325
326 /* special sigset() check */
327 if(IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
328 /* check to make sure signal is not blocked */
329 if(sigismember(&p->p_sigmask, signum)) {
330 /* return SIG_HOLD and unblock signal*/
331 *retval = (int)IBCS2_SIG_HOLD;
332 p->p_sigmask &= ~sigmask(signum);
333 }
334
335 return 0;
336 }
337
338 case IBCS2_SIGRELSE_MASK:
339 {
340 struct sigprocmask_args sa;
341
342 SCARG(&sa, how) = SIG_UNBLOCK;
343 SCARG(&sa, mask) = sigmask(signum);
344 return sigprocmask(p, &sa, retval);
345 }
346
347 case IBCS2_SIGIGNORE_MASK:
348 {
349 struct sigaction_args sa_args;
350 struct sigaction *bsa;
351
352 bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
353 SCARG(&sa_args, signum) = signum;
354 SCARG(&sa_args, nsa) = bsa;
355 SCARG(&sa_args, osa) = NULL;
356
357 sa.sa_handler = SIG_IGN;
358 sigemptyset(&sa.sa_mask);
359 sa.sa_flags = 0;
360 if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
361 return error;
362 if ((error = sigaction(p, &sa_args, retval)) != 0) {
363 DPRINTF(("sigignore: sigaction failed\n"));
364 return error;
365 }
366 return 0;
367 }
368
369 case IBCS2_SIGPAUSE_MASK:
370 {
371 struct sigsuspend_args sa;
372
373 SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum);
374 return sigsuspend(p, &sa, retval);
375 }
376
377 default:
378 return ENOSYS;
379 }
380 }
381
382 int
383 ibcs2_sigprocmask(p, uap, retval)
384 register struct proc *p;
385 struct ibcs2_sigprocmask_args *uap;
386 int *retval;
387 {
388 ibcs2_sigset_t iss;
389 sigset_t bss;
390 int error = 0;
391
392 if (SCARG(uap, oset) != NULL) {
393 /* Fix the return value first if needed */
394 bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
395 if ((error = copyout(&iss, SCARG(uap, oset), sizeof(iss))) != 0)
396 return error;
397 }
398
399 if (SCARG(uap, set) == NULL)
400 /* Just examine */
401 return 0;
402
403 if ((error = copyin(SCARG(uap, set), &iss, sizeof(iss))) != 0)
404 return error;
405
406 ibcs2_to_bsd_sigset(&iss, &bss);
407
408 (void) splhigh();
409
410 switch (SCARG(uap, how)) {
411 case IBCS2_SIG_BLOCK:
412 p->p_sigmask |= bss & ~sigcantmask;
413 break;
414
415 case IBCS2_SIG_UNBLOCK:
416 p->p_sigmask &= ~bss;
417 break;
418
419 case IBCS2_SIG_SETMASK:
420 p->p_sigmask = bss & ~sigcantmask;
421 break;
422
423 default:
424 error = EINVAL;
425 break;
426 }
427
428 (void) spl0();
429
430 return error;
431 }
432
433 int
434 ibcs2_sigpending(p, uap, retval)
435 register struct proc *p;
436 struct ibcs2_sigpending_args *uap;
437 int *retval;
438 {
439 sigset_t bss;
440 ibcs2_sigset_t iss;
441
442 bss = p->p_siglist & p->p_sigmask;
443 bsd_to_ibcs2_sigset(&bss, &iss);
444
445 return copyout(&iss, SCARG(uap, mask), sizeof(iss));
446 }
447
448 int
449 ibcs2_sigsuspend(p, uap, retval)
450 register struct proc *p;
451 struct ibcs2_sigsuspend_args *uap;
452 int *retval;
453 {
454 ibcs2_sigset_t sss;
455 sigset_t bss;
456 struct sigsuspend_args sa;
457 int error;
458
459 if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0)
460 return error;
461
462 ibcs2_to_bsd_sigset(&sss, &bss);
463
464 SCARG(&sa, mask) = bss;
465 return sigsuspend(p, &sa, retval);
466 }
467
468 int
469 ibcs2_pause(p, uap, retval)
470 register struct proc *p;
471 struct ibcs2_pause_args *uap;
472 int *retval;
473 {
474 struct sigsuspend_args bsa;
475
476 SCARG(&bsa, mask) = p->p_sigmask;
477 return sigsuspend(p, &bsa, retval);
478 }
479
480 int
481 ibcs2_kill(p, uap, retval)
482 register struct proc *p;
483 struct ibcs2_kill_args *uap;
484 int *retval;
485 {
486 struct kill_args ka;
487
488 SCARG(&ka, pid) = SCARG(uap, pid);
489 SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)];
490 return kill(p, &ka, retval);
491 }
Cache object: 1115413f6983b7b6bffc170554c5513d
|