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