Deleted Added
full compact
svr4_signal.c (51793) svr4_signal.c (52140)
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
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 *
1/*
2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
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: head/sys/compat/svr4/svr4_signal.c 51793 1999-09-29 15:12:18Z marcel $
28 * $FreeBSD: head/sys/compat/svr4/svr4_signal.c 52140 1999-10-11 20:33:17Z luoqi $
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/mount.h>
37#include <sys/kernel.h>
38#include <sys/signal.h>
39#include <sys/signalvar.h>
40#include <sys/malloc.h>
41#include <sys/sysproto.h>
42
43#include <svr4/svr4.h>
44#include <svr4/svr4_types.h>
45#include <svr4/svr4_signal.h>
46#include <svr4/svr4_proto.h>
47#include <svr4/svr4_util.h>
48#include <svr4/svr4_ucontext.h>
49
50#define svr4_sigmask(n) (1 << (((n) - 1) & 31))
51#define svr4_sigword(n) (((n) - 1) >> 5)
52#define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
53#define svr4_sigfillset(s) memset((s), 0xffffffff, sizeof(*(s)))
54#define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
55#define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
56
57void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *,
58 struct sigaction *));
59void bsd_to_svr4_sigaction __P((const struct sigaction *,
60 struct svr4_sigaction *));
61
62int bsd_to_svr4_sig[SVR4_SIGTBLSZ] = {
63 SVR4_SIGHUP,
64 SVR4_SIGINT,
65 SVR4_SIGQUIT,
66 SVR4_SIGILL,
67 SVR4_SIGTRAP,
68 SVR4_SIGABRT,
69 SVR4_SIGEMT,
70 SVR4_SIGFPE,
71 SVR4_SIGKILL,
72 SVR4_SIGBUS,
73 SVR4_SIGSEGV,
74 SVR4_SIGSYS,
75 SVR4_SIGPIPE,
76 SVR4_SIGALRM,
77 SVR4_SIGTERM,
78 SVR4_SIGURG,
79 SVR4_SIGSTOP,
80 SVR4_SIGTSTP,
81 SVR4_SIGCONT,
82 SVR4_SIGCHLD,
83 SVR4_SIGTTIN,
84 SVR4_SIGTTOU,
85 SVR4_SIGIO,
86 SVR4_SIGXCPU,
87 SVR4_SIGXFSZ,
88 SVR4_SIGVTALRM,
89 SVR4_SIGPROF,
90 SVR4_SIGWINCH,
91 0, /* SIGINFO */
92 SVR4_SIGUSR1,
93 SVR4_SIGUSR2,
94};
95
96int svr4_to_bsd_sig[SVR4_SIGTBLSZ] = {
97 SIGHUP,
98 SIGINT,
99 SIGQUIT,
100 SIGILL,
101 SIGTRAP,
102 SIGABRT,
103 SIGEMT,
104 SIGFPE,
105 SIGKILL,
106 SIGBUS,
107 SIGSEGV,
108 SIGSYS,
109 SIGPIPE,
110 SIGALRM,
111 SIGTERM,
112 SIGUSR1,
113 SIGUSR2,
114 SIGCHLD,
115 0, /* XXX NetBSD uses SIGPWR here, but we don't seem to have one */
116 SIGWINCH,
117 SIGURG,
118 SIGIO,
119 SIGSTOP,
120 SIGTSTP,
121 SIGCONT,
122 SIGTTIN,
123 SIGTTOU,
124 SIGVTALRM,
125 SIGPROF,
126 SIGXCPU,
127 SIGXFSZ,
128};
129
130void
131svr4_to_bsd_sigset(sss, bss)
132 const svr4_sigset_t *sss;
133 sigset_t *bss;
134{
135 int i, newsig;
136
137 SIGEMPTYSET(*bss);
138 bss->__bits[0] = sss->bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
139 bss->__bits[1] = sss->bits[1];
140 bss->__bits[2] = sss->bits[2];
141 bss->__bits[3] = sss->bits[3];
142 for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
143 if (svr4_sigismember(sss, i)) {
144 newsig = svr4_to_bsd_sig[_SIG_IDX(i)];
145 if (newsig)
146 SIGADDSET(*bss, newsig);
147 }
148 }
149}
150
151void
152bsd_to_svr4_sigset(bss, sss)
153 const sigset_t *bss;
154 svr4_sigset_t *sss;
155{
156 int i, newsig;
157
158 svr4_sigemptyset(sss);
159 sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
160 sss->bits[1] = bss->__bits[1];
161 sss->bits[2] = bss->__bits[2];
162 sss->bits[3] = bss->__bits[3];
163 for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
164 if (SIGISMEMBER(*bss, i)) {
165 newsig = bsd_to_svr4_sig[_SIG_IDX(i)];
166 if (newsig)
167 svr4_sigaddset(sss, newsig);
168 }
169 }
170}
171
172/*
173 * XXX: Only a subset of the flags is currently implemented.
174 */
175void
176svr4_to_bsd_sigaction(ssa, bsa)
177 const struct svr4_sigaction *ssa;
178 struct sigaction *bsa;
179{
180
181 bsa->sa_handler = (sig_t) ssa->ssa_handler;
182 svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
183 bsa->sa_flags = 0;
184 if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
185 bsa->sa_flags |= SA_ONSTACK;
186 if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
187 bsa->sa_flags |= SA_RESETHAND;
188 if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
189 bsa->sa_flags |= SA_RESTART;
190 if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
191 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
192 if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
193 bsa->sa_flags |= SA_NOCLDSTOP;
194 if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
195 bsa->sa_flags |= SA_NODEFER;
196 if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
197 bsa->sa_flags |= SA_NOCLDWAIT;
198 if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
199 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
200}
201
202void
203bsd_to_svr4_sigaction(bsa, ssa)
204 const struct sigaction *bsa;
205 struct svr4_sigaction *ssa;
206{
207
208 ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
209 bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
210 ssa->ssa_flags = 0;
211 if ((bsa->sa_flags & SA_ONSTACK) != 0)
212 ssa->ssa_flags |= SVR4_SA_ONSTACK;
213 if ((bsa->sa_flags & SA_RESETHAND) != 0)
214 ssa->ssa_flags |= SVR4_SA_RESETHAND;
215 if ((bsa->sa_flags & SA_RESTART) != 0)
216 ssa->ssa_flags |= SVR4_SA_RESTART;
217 if ((bsa->sa_flags & SA_NODEFER) != 0)
218 ssa->ssa_flags |= SVR4_SA_NODEFER;
219 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
220 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
221}
222
223void
224svr4_to_bsd_sigaltstack(sss, bss)
225 const struct svr4_sigaltstack *sss;
226 struct sigaltstack *bss;
227{
228
229 bss->ss_sp = sss->ss_sp;
230 bss->ss_size = sss->ss_size;
231 bss->ss_flags = 0;
232 if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
233 bss->ss_flags |= SS_DISABLE;
234 if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
235 bss->ss_flags |= SS_ONSTACK;
236 if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
237 /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
238}
239
240void
241bsd_to_svr4_sigaltstack(bss, sss)
242 const struct sigaltstack *bss;
243 struct svr4_sigaltstack *sss;
244{
245
246 sss->ss_sp = bss->ss_sp;
247 sss->ss_size = bss->ss_size;
248 sss->ss_flags = 0;
249 if ((bss->ss_flags & SS_DISABLE) != 0)
250 sss->ss_flags |= SVR4_SS_DISABLE;
251 if ((bss->ss_flags & SS_ONSTACK) != 0)
252 sss->ss_flags |= SVR4_SS_ONSTACK;
253}
254
255int
256svr4_sys_sigaction(p, uap)
257 register struct proc *p;
258 struct svr4_sys_sigaction_args *uap;
259{
260 struct svr4_sigaction *nisa, *oisa, tmpisa;
261 struct sigaction *nbsa, *obsa, tmpbsa;
262 struct sigaction_args sa;
263 caddr_t sg;
264 int error;
265
266 sg = stackgap_init();
267 nisa = SCARG(uap, nsa);
268 oisa = SCARG(uap, osa);
269
270 if (oisa != NULL)
271 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
272 else
273 obsa = NULL;
274
275 if (nisa != NULL) {
276 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
277 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
278 return error;
279 svr4_to_bsd_sigaction(&tmpisa, &tmpbsa);
280 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
281 return error;
282 } else
283 nbsa = NULL;
284
285 SCARG(&sa, sig) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
286 SCARG(&sa, act) = nbsa;
287 SCARG(&sa, oact) = obsa;
288
289 if ((error = sigaction(p, &sa)) != 0)
290 return error;
291
292 if (oisa != NULL) {
293 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
294 return error;
295 bsd_to_svr4_sigaction(&tmpbsa, &tmpisa);
296 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
297 return error;
298 }
299
300 return 0;
301}
302
303int
304svr4_sys_sigaltstack(p, uap)
305 register struct proc *p;
306 struct svr4_sys_sigaltstack_args *uap;
307{
308 struct svr4_sigaltstack *nsss, *osss, tmpsss;
309 struct sigaltstack *nbss, *obss, tmpbss;
310 struct sigaltstack_args sa;
311 caddr_t sg;
312 int error, *retval;
313
314 retval = p->p_retval;
315 sg = stackgap_init();
316 nsss = SCARG(uap, nss);
317 osss = SCARG(uap, oss);
318
319 if (osss != NULL)
320 obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
321 else
322 obss = NULL;
323
324 if (nsss != NULL) {
325 nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
326 if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0)
327 return error;
328 svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss);
329 if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
330 return error;
331 } else
332 nbss = NULL;
333
334 SCARG(&sa, ss) = nbss;
335 SCARG(&sa, oss) = obss;
336
337 if ((error = sigaltstack(p, &sa)) != 0)
338 return error;
339
340 if (obss != NULL) {
341 if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
342 return error;
343 bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss);
344 if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0)
345 return error;
346 }
347
348 return 0;
349}
350
351/*
352 * Stolen from the ibcs2 one
353 */
354int
355svr4_sys_signal(p, uap)
356 register struct proc *p;
357 struct svr4_sys_signal_args *uap;
358{
359 int signum;
360 int error, *retval;
361 caddr_t sg = stackgap_init();
362
363 signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(SCARG(uap, signum)));
364 retval = p->p_retval;
365 if (signum <= 0 || signum > SVR4_NSIG)
366 return (EINVAL);
367
368 switch (SVR4_SIGCALL(SCARG(uap, signum))) {
369 case SVR4_SIGDEFER_MASK:
370 if (SCARG(uap, handler) == SVR4_SIG_HOLD)
371 goto sighold;
372 /* FALLTHROUGH */
373
374 case SVR4_SIGNAL_MASK:
375 {
376 struct sigaction_args sa_args;
377 struct sigaction *nbsa, *obsa, sa;
378
379 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
380 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
381 SCARG(&sa_args, sig) = signum;
382 SCARG(&sa_args, act) = nbsa;
383 SCARG(&sa_args, oact) = obsa;
384
385 sa.sa_handler = (sig_t) SCARG(uap, handler);
386 SIGEMPTYSET(sa.sa_mask);
387 sa.sa_flags = 0;
388
389 if (signum != SIGALRM)
390 sa.sa_flags = SA_RESTART;
391
392 if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
393 return error;
394 if ((error = sigaction(p, &sa_args)) != 0) {
395 DPRINTF(("signal: sigaction failed: %d\n",
396 error));
397 *retval = (int)SVR4_SIG_ERR;
398 return error;
399 }
400 if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
401 return error;
402 *retval = (int)sa.sa_handler;
403 return 0;
404 }
405
406 case SVR4_SIGHOLD_MASK:
407sighold:
408 {
409 struct sigprocmask_args sa;
410 sigset_t *set;
411
412 set = stackgap_alloc(&sg, sizeof(sigset_t));
413 SIGEMPTYSET(*set);
414 SIGADDSET(*set, signum);
415 SCARG(&sa, how) = SIG_BLOCK;
416 SCARG(&sa, set) = set;
417 SCARG(&sa, oset) = NULL;
418 return sigprocmask(p, &sa);
419 }
420
421 case SVR4_SIGRELSE_MASK:
422 {
423 struct sigprocmask_args sa;
424 sigset_t *set;
425
426 set = stackgap_alloc(&sg, sizeof(sigset_t));
427 SIGEMPTYSET(*set);
428 SIGADDSET(*set, signum);
429 SCARG(&sa, how) = SIG_UNBLOCK;
430 SCARG(&sa, set) = set;
431 SCARG(&sa, oset) = NULL;
432 return sigprocmask(p, &sa);
433 }
434
435 case SVR4_SIGIGNORE_MASK:
436 {
437 struct sigaction_args sa_args;
438 struct sigaction *bsa, sa;
439
440 bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
441 SCARG(&sa_args, sig) = signum;
442 SCARG(&sa_args, act) = bsa;
443 SCARG(&sa_args, oact) = NULL;
444
445 sa.sa_handler = SIG_IGN;
446 SIGEMPTYSET(sa.sa_mask);
447 sa.sa_flags = 0;
448 if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
449 return error;
450 if ((error = sigaction(p, &sa_args)) != 0) {
451 DPRINTF(("sigignore: sigaction failed\n"));
452 return error;
453 }
454 return 0;
455 }
456
457 case SVR4_SIGPAUSE_MASK:
458 {
459 struct sigsuspend_args sa;
460 sigset_t *set;
461
462 set = stackgap_alloc(&sg, sizeof(sigset_t));
463 *set = p->p_sigmask;
464 SIGDELSET(*set, signum);
465 SCARG(&sa, sigmask) = set;
466 return sigsuspend(p, &sa);
467 }
468
469 default:
470 return (ENOSYS);
471 }
472}
473
474
475int
476svr4_sys_sigprocmask(p, uap)
477 struct proc *p;
478 struct svr4_sys_sigprocmask_args *uap;
479{
480 svr4_sigset_t sss;
481 sigset_t bss;
482 int error = 0, *retval;
483
484 retval = p->p_retval;
485 if (SCARG(uap, oset) != NULL) {
486 /* Fix the return value first if needed */
487 bsd_to_svr4_sigset(&p->p_sigmask, &sss);
488 if ((error = copyout(&sss, SCARG(uap, oset), sizeof(sss))) != 0)
489 return error;
490 }
491
492 if (SCARG(uap, set) == NULL)
493 /* Just examine */
494 return 0;
495
496 if ((error = copyin(SCARG(uap, set), &sss, sizeof(sss))) != 0)
497 return error;
498
499 svr4_to_bsd_sigset(&sss, &bss);
500
501 (void) splhigh();
502
503 switch (SCARG(uap, how)) {
504 case SVR4_SIG_BLOCK:
505 SIGSETOR(p->p_sigmask, bss);
506 SIG_CANTMASK(p->p_sigmask);
507 break;
508
509 case SVR4_SIG_UNBLOCK:
510 SIGSETNAND(p->p_sigmask, bss);
511 break;
512
513 case SVR4_SIG_SETMASK:
514 p->p_sigmask = bss;
515 SIG_CANTMASK(p->p_sigmask);
516 break;
517
518 default:
519 error = EINVAL;
520 break;
521 }
522
523 (void) spl0();
524
525 return error;
526}
527
528int
529svr4_sys_sigpending(p, uap)
530 struct proc *p;
531 struct svr4_sys_sigpending_args *uap;
532{
533 sigset_t bss;
534 int *retval;
535 svr4_sigset_t sss;
536
537 retval = p->p_retval;
538 switch (SCARG(uap, what)) {
539 case 1: /* sigpending */
540 if (SCARG(uap, mask) == NULL)
541 return 0;
542 bss = p->p_siglist;
543 SIGSETAND(bss, p->p_sigmask);
544 bsd_to_svr4_sigset(&bss, &sss);
545 break;
546
547 case 2: /* sigfillset */
548 svr4_sigfillset(&sss);
549 break;
550
551 default:
552 return EINVAL;
553 }
554
555 return copyout(&sss, SCARG(uap, mask), sizeof(sss));
556}
557
558int
559svr4_sys_sigsuspend(p, uap)
560 register struct proc *p;
561 struct svr4_sys_sigsuspend_args *uap;
562{
563 svr4_sigset_t sss;
564 sigset_t *bss;
565 struct sigsuspend_args sa;
566 int error;
567 caddr_t sg = stackgap_init();
568
569 if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0)
570 return error;
571
572 bss = stackgap_alloc(&sg, sizeof(sigset_t));
573 svr4_to_bsd_sigset(&sss, bss);
574
575 SCARG(&sa, sigmask) = bss;
576 return sigsuspend(p, &sa);
577}
578
579
580int
581svr4_sys_kill(p, uap)
582 register struct proc *p;
583 struct svr4_sys_kill_args *uap;
584{
585 struct kill_args ka;
586
587 SCARG(&ka, pid) = SCARG(uap, pid);
588 SCARG(&ka, signum) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
589 return kill(p, &ka);
590}
591
592
593int
594svr4_sys_context(p, uap)
595 register struct proc *p;
596 struct svr4_sys_context_args *uap;
597{
598 struct svr4_ucontext uc;
599 int error;
600
601 switch (uap->func) {
602 case 0:
603 DPRINTF(("getcontext(%p)\n", uap->uc));
604 svr4_getcontext(p, &uc, &p->p_sigmask,
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/mount.h>
37#include <sys/kernel.h>
38#include <sys/signal.h>
39#include <sys/signalvar.h>
40#include <sys/malloc.h>
41#include <sys/sysproto.h>
42
43#include <svr4/svr4.h>
44#include <svr4/svr4_types.h>
45#include <svr4/svr4_signal.h>
46#include <svr4/svr4_proto.h>
47#include <svr4/svr4_util.h>
48#include <svr4/svr4_ucontext.h>
49
50#define svr4_sigmask(n) (1 << (((n) - 1) & 31))
51#define svr4_sigword(n) (((n) - 1) >> 5)
52#define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
53#define svr4_sigfillset(s) memset((s), 0xffffffff, sizeof(*(s)))
54#define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
55#define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
56
57void svr4_to_bsd_sigaction __P((const struct svr4_sigaction *,
58 struct sigaction *));
59void bsd_to_svr4_sigaction __P((const struct sigaction *,
60 struct svr4_sigaction *));
61
62int bsd_to_svr4_sig[SVR4_SIGTBLSZ] = {
63 SVR4_SIGHUP,
64 SVR4_SIGINT,
65 SVR4_SIGQUIT,
66 SVR4_SIGILL,
67 SVR4_SIGTRAP,
68 SVR4_SIGABRT,
69 SVR4_SIGEMT,
70 SVR4_SIGFPE,
71 SVR4_SIGKILL,
72 SVR4_SIGBUS,
73 SVR4_SIGSEGV,
74 SVR4_SIGSYS,
75 SVR4_SIGPIPE,
76 SVR4_SIGALRM,
77 SVR4_SIGTERM,
78 SVR4_SIGURG,
79 SVR4_SIGSTOP,
80 SVR4_SIGTSTP,
81 SVR4_SIGCONT,
82 SVR4_SIGCHLD,
83 SVR4_SIGTTIN,
84 SVR4_SIGTTOU,
85 SVR4_SIGIO,
86 SVR4_SIGXCPU,
87 SVR4_SIGXFSZ,
88 SVR4_SIGVTALRM,
89 SVR4_SIGPROF,
90 SVR4_SIGWINCH,
91 0, /* SIGINFO */
92 SVR4_SIGUSR1,
93 SVR4_SIGUSR2,
94};
95
96int svr4_to_bsd_sig[SVR4_SIGTBLSZ] = {
97 SIGHUP,
98 SIGINT,
99 SIGQUIT,
100 SIGILL,
101 SIGTRAP,
102 SIGABRT,
103 SIGEMT,
104 SIGFPE,
105 SIGKILL,
106 SIGBUS,
107 SIGSEGV,
108 SIGSYS,
109 SIGPIPE,
110 SIGALRM,
111 SIGTERM,
112 SIGUSR1,
113 SIGUSR2,
114 SIGCHLD,
115 0, /* XXX NetBSD uses SIGPWR here, but we don't seem to have one */
116 SIGWINCH,
117 SIGURG,
118 SIGIO,
119 SIGSTOP,
120 SIGTSTP,
121 SIGCONT,
122 SIGTTIN,
123 SIGTTOU,
124 SIGVTALRM,
125 SIGPROF,
126 SIGXCPU,
127 SIGXFSZ,
128};
129
130void
131svr4_to_bsd_sigset(sss, bss)
132 const svr4_sigset_t *sss;
133 sigset_t *bss;
134{
135 int i, newsig;
136
137 SIGEMPTYSET(*bss);
138 bss->__bits[0] = sss->bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
139 bss->__bits[1] = sss->bits[1];
140 bss->__bits[2] = sss->bits[2];
141 bss->__bits[3] = sss->bits[3];
142 for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
143 if (svr4_sigismember(sss, i)) {
144 newsig = svr4_to_bsd_sig[_SIG_IDX(i)];
145 if (newsig)
146 SIGADDSET(*bss, newsig);
147 }
148 }
149}
150
151void
152bsd_to_svr4_sigset(bss, sss)
153 const sigset_t *bss;
154 svr4_sigset_t *sss;
155{
156 int i, newsig;
157
158 svr4_sigemptyset(sss);
159 sss->bits[0] = bss->__bits[0] & ~((1U << SVR4_SIGTBLSZ) - 1);
160 sss->bits[1] = bss->__bits[1];
161 sss->bits[2] = bss->__bits[2];
162 sss->bits[3] = bss->__bits[3];
163 for (i = 1; i <= SVR4_SIGTBLSZ; i++) {
164 if (SIGISMEMBER(*bss, i)) {
165 newsig = bsd_to_svr4_sig[_SIG_IDX(i)];
166 if (newsig)
167 svr4_sigaddset(sss, newsig);
168 }
169 }
170}
171
172/*
173 * XXX: Only a subset of the flags is currently implemented.
174 */
175void
176svr4_to_bsd_sigaction(ssa, bsa)
177 const struct svr4_sigaction *ssa;
178 struct sigaction *bsa;
179{
180
181 bsa->sa_handler = (sig_t) ssa->ssa_handler;
182 svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
183 bsa->sa_flags = 0;
184 if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
185 bsa->sa_flags |= SA_ONSTACK;
186 if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
187 bsa->sa_flags |= SA_RESETHAND;
188 if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
189 bsa->sa_flags |= SA_RESTART;
190 if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
191 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
192 if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
193 bsa->sa_flags |= SA_NOCLDSTOP;
194 if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
195 bsa->sa_flags |= SA_NODEFER;
196 if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
197 bsa->sa_flags |= SA_NOCLDWAIT;
198 if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
199 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
200}
201
202void
203bsd_to_svr4_sigaction(bsa, ssa)
204 const struct sigaction *bsa;
205 struct svr4_sigaction *ssa;
206{
207
208 ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
209 bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
210 ssa->ssa_flags = 0;
211 if ((bsa->sa_flags & SA_ONSTACK) != 0)
212 ssa->ssa_flags |= SVR4_SA_ONSTACK;
213 if ((bsa->sa_flags & SA_RESETHAND) != 0)
214 ssa->ssa_flags |= SVR4_SA_RESETHAND;
215 if ((bsa->sa_flags & SA_RESTART) != 0)
216 ssa->ssa_flags |= SVR4_SA_RESTART;
217 if ((bsa->sa_flags & SA_NODEFER) != 0)
218 ssa->ssa_flags |= SVR4_SA_NODEFER;
219 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
220 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
221}
222
223void
224svr4_to_bsd_sigaltstack(sss, bss)
225 const struct svr4_sigaltstack *sss;
226 struct sigaltstack *bss;
227{
228
229 bss->ss_sp = sss->ss_sp;
230 bss->ss_size = sss->ss_size;
231 bss->ss_flags = 0;
232 if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
233 bss->ss_flags |= SS_DISABLE;
234 if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
235 bss->ss_flags |= SS_ONSTACK;
236 if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
237 /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
238}
239
240void
241bsd_to_svr4_sigaltstack(bss, sss)
242 const struct sigaltstack *bss;
243 struct svr4_sigaltstack *sss;
244{
245
246 sss->ss_sp = bss->ss_sp;
247 sss->ss_size = bss->ss_size;
248 sss->ss_flags = 0;
249 if ((bss->ss_flags & SS_DISABLE) != 0)
250 sss->ss_flags |= SVR4_SS_DISABLE;
251 if ((bss->ss_flags & SS_ONSTACK) != 0)
252 sss->ss_flags |= SVR4_SS_ONSTACK;
253}
254
255int
256svr4_sys_sigaction(p, uap)
257 register struct proc *p;
258 struct svr4_sys_sigaction_args *uap;
259{
260 struct svr4_sigaction *nisa, *oisa, tmpisa;
261 struct sigaction *nbsa, *obsa, tmpbsa;
262 struct sigaction_args sa;
263 caddr_t sg;
264 int error;
265
266 sg = stackgap_init();
267 nisa = SCARG(uap, nsa);
268 oisa = SCARG(uap, osa);
269
270 if (oisa != NULL)
271 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
272 else
273 obsa = NULL;
274
275 if (nisa != NULL) {
276 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
277 if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
278 return error;
279 svr4_to_bsd_sigaction(&tmpisa, &tmpbsa);
280 if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
281 return error;
282 } else
283 nbsa = NULL;
284
285 SCARG(&sa, sig) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
286 SCARG(&sa, act) = nbsa;
287 SCARG(&sa, oact) = obsa;
288
289 if ((error = sigaction(p, &sa)) != 0)
290 return error;
291
292 if (oisa != NULL) {
293 if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
294 return error;
295 bsd_to_svr4_sigaction(&tmpbsa, &tmpisa);
296 if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
297 return error;
298 }
299
300 return 0;
301}
302
303int
304svr4_sys_sigaltstack(p, uap)
305 register struct proc *p;
306 struct svr4_sys_sigaltstack_args *uap;
307{
308 struct svr4_sigaltstack *nsss, *osss, tmpsss;
309 struct sigaltstack *nbss, *obss, tmpbss;
310 struct sigaltstack_args sa;
311 caddr_t sg;
312 int error, *retval;
313
314 retval = p->p_retval;
315 sg = stackgap_init();
316 nsss = SCARG(uap, nss);
317 osss = SCARG(uap, oss);
318
319 if (osss != NULL)
320 obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
321 else
322 obss = NULL;
323
324 if (nsss != NULL) {
325 nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
326 if ((error = copyin(nsss, &tmpsss, sizeof(tmpsss))) != 0)
327 return error;
328 svr4_to_bsd_sigaltstack(&tmpsss, &tmpbss);
329 if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
330 return error;
331 } else
332 nbss = NULL;
333
334 SCARG(&sa, ss) = nbss;
335 SCARG(&sa, oss) = obss;
336
337 if ((error = sigaltstack(p, &sa)) != 0)
338 return error;
339
340 if (obss != NULL) {
341 if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
342 return error;
343 bsd_to_svr4_sigaltstack(&tmpbss, &tmpsss);
344 if ((error = copyout(&tmpsss, osss, sizeof(tmpsss))) != 0)
345 return error;
346 }
347
348 return 0;
349}
350
351/*
352 * Stolen from the ibcs2 one
353 */
354int
355svr4_sys_signal(p, uap)
356 register struct proc *p;
357 struct svr4_sys_signal_args *uap;
358{
359 int signum;
360 int error, *retval;
361 caddr_t sg = stackgap_init();
362
363 signum = SVR4_SVR42BSD_SIG(SVR4_SIGNO(SCARG(uap, signum)));
364 retval = p->p_retval;
365 if (signum <= 0 || signum > SVR4_NSIG)
366 return (EINVAL);
367
368 switch (SVR4_SIGCALL(SCARG(uap, signum))) {
369 case SVR4_SIGDEFER_MASK:
370 if (SCARG(uap, handler) == SVR4_SIG_HOLD)
371 goto sighold;
372 /* FALLTHROUGH */
373
374 case SVR4_SIGNAL_MASK:
375 {
376 struct sigaction_args sa_args;
377 struct sigaction *nbsa, *obsa, sa;
378
379 nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
380 obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
381 SCARG(&sa_args, sig) = signum;
382 SCARG(&sa_args, act) = nbsa;
383 SCARG(&sa_args, oact) = obsa;
384
385 sa.sa_handler = (sig_t) SCARG(uap, handler);
386 SIGEMPTYSET(sa.sa_mask);
387 sa.sa_flags = 0;
388
389 if (signum != SIGALRM)
390 sa.sa_flags = SA_RESTART;
391
392 if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
393 return error;
394 if ((error = sigaction(p, &sa_args)) != 0) {
395 DPRINTF(("signal: sigaction failed: %d\n",
396 error));
397 *retval = (int)SVR4_SIG_ERR;
398 return error;
399 }
400 if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
401 return error;
402 *retval = (int)sa.sa_handler;
403 return 0;
404 }
405
406 case SVR4_SIGHOLD_MASK:
407sighold:
408 {
409 struct sigprocmask_args sa;
410 sigset_t *set;
411
412 set = stackgap_alloc(&sg, sizeof(sigset_t));
413 SIGEMPTYSET(*set);
414 SIGADDSET(*set, signum);
415 SCARG(&sa, how) = SIG_BLOCK;
416 SCARG(&sa, set) = set;
417 SCARG(&sa, oset) = NULL;
418 return sigprocmask(p, &sa);
419 }
420
421 case SVR4_SIGRELSE_MASK:
422 {
423 struct sigprocmask_args sa;
424 sigset_t *set;
425
426 set = stackgap_alloc(&sg, sizeof(sigset_t));
427 SIGEMPTYSET(*set);
428 SIGADDSET(*set, signum);
429 SCARG(&sa, how) = SIG_UNBLOCK;
430 SCARG(&sa, set) = set;
431 SCARG(&sa, oset) = NULL;
432 return sigprocmask(p, &sa);
433 }
434
435 case SVR4_SIGIGNORE_MASK:
436 {
437 struct sigaction_args sa_args;
438 struct sigaction *bsa, sa;
439
440 bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
441 SCARG(&sa_args, sig) = signum;
442 SCARG(&sa_args, act) = bsa;
443 SCARG(&sa_args, oact) = NULL;
444
445 sa.sa_handler = SIG_IGN;
446 SIGEMPTYSET(sa.sa_mask);
447 sa.sa_flags = 0;
448 if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
449 return error;
450 if ((error = sigaction(p, &sa_args)) != 0) {
451 DPRINTF(("sigignore: sigaction failed\n"));
452 return error;
453 }
454 return 0;
455 }
456
457 case SVR4_SIGPAUSE_MASK:
458 {
459 struct sigsuspend_args sa;
460 sigset_t *set;
461
462 set = stackgap_alloc(&sg, sizeof(sigset_t));
463 *set = p->p_sigmask;
464 SIGDELSET(*set, signum);
465 SCARG(&sa, sigmask) = set;
466 return sigsuspend(p, &sa);
467 }
468
469 default:
470 return (ENOSYS);
471 }
472}
473
474
475int
476svr4_sys_sigprocmask(p, uap)
477 struct proc *p;
478 struct svr4_sys_sigprocmask_args *uap;
479{
480 svr4_sigset_t sss;
481 sigset_t bss;
482 int error = 0, *retval;
483
484 retval = p->p_retval;
485 if (SCARG(uap, oset) != NULL) {
486 /* Fix the return value first if needed */
487 bsd_to_svr4_sigset(&p->p_sigmask, &sss);
488 if ((error = copyout(&sss, SCARG(uap, oset), sizeof(sss))) != 0)
489 return error;
490 }
491
492 if (SCARG(uap, set) == NULL)
493 /* Just examine */
494 return 0;
495
496 if ((error = copyin(SCARG(uap, set), &sss, sizeof(sss))) != 0)
497 return error;
498
499 svr4_to_bsd_sigset(&sss, &bss);
500
501 (void) splhigh();
502
503 switch (SCARG(uap, how)) {
504 case SVR4_SIG_BLOCK:
505 SIGSETOR(p->p_sigmask, bss);
506 SIG_CANTMASK(p->p_sigmask);
507 break;
508
509 case SVR4_SIG_UNBLOCK:
510 SIGSETNAND(p->p_sigmask, bss);
511 break;
512
513 case SVR4_SIG_SETMASK:
514 p->p_sigmask = bss;
515 SIG_CANTMASK(p->p_sigmask);
516 break;
517
518 default:
519 error = EINVAL;
520 break;
521 }
522
523 (void) spl0();
524
525 return error;
526}
527
528int
529svr4_sys_sigpending(p, uap)
530 struct proc *p;
531 struct svr4_sys_sigpending_args *uap;
532{
533 sigset_t bss;
534 int *retval;
535 svr4_sigset_t sss;
536
537 retval = p->p_retval;
538 switch (SCARG(uap, what)) {
539 case 1: /* sigpending */
540 if (SCARG(uap, mask) == NULL)
541 return 0;
542 bss = p->p_siglist;
543 SIGSETAND(bss, p->p_sigmask);
544 bsd_to_svr4_sigset(&bss, &sss);
545 break;
546
547 case 2: /* sigfillset */
548 svr4_sigfillset(&sss);
549 break;
550
551 default:
552 return EINVAL;
553 }
554
555 return copyout(&sss, SCARG(uap, mask), sizeof(sss));
556}
557
558int
559svr4_sys_sigsuspend(p, uap)
560 register struct proc *p;
561 struct svr4_sys_sigsuspend_args *uap;
562{
563 svr4_sigset_t sss;
564 sigset_t *bss;
565 struct sigsuspend_args sa;
566 int error;
567 caddr_t sg = stackgap_init();
568
569 if ((error = copyin(SCARG(uap, ss), &sss, sizeof(sss))) != 0)
570 return error;
571
572 bss = stackgap_alloc(&sg, sizeof(sigset_t));
573 svr4_to_bsd_sigset(&sss, bss);
574
575 SCARG(&sa, sigmask) = bss;
576 return sigsuspend(p, &sa);
577}
578
579
580int
581svr4_sys_kill(p, uap)
582 register struct proc *p;
583 struct svr4_sys_kill_args *uap;
584{
585 struct kill_args ka;
586
587 SCARG(&ka, pid) = SCARG(uap, pid);
588 SCARG(&ka, signum) = SVR4_SVR42BSD_SIG(SCARG(uap, signum));
589 return kill(p, &ka);
590}
591
592
593int
594svr4_sys_context(p, uap)
595 register struct proc *p;
596 struct svr4_sys_context_args *uap;
597{
598 struct svr4_ucontext uc;
599 int error;
600
601 switch (uap->func) {
602 case 0:
603 DPRINTF(("getcontext(%p)\n", uap->uc));
604 svr4_getcontext(p, &uc, &p->p_sigmask,
605 p->p_sigacts->ps_sigstk.ss_flags & SS_ONSTACK);
605 p->p_sigstk.ss_flags & SS_ONSTACK);
606 return copyout(&uc, uap->uc, sizeof(uc));
607
608 case 1:
609 DPRINTF(("setcontext(%p)\n", uap->uc));
610 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
611 return error;
612 DPRINTF(("uc_flags = %x\n", uc.uc_flags));
613 DPRINTF(("uc_sigmask = %x\n", uc.uc_sigmask));
614
615 return svr4_setcontext(p, &uc);
616
617 default:
618 DPRINTF(("context(%d, %p)\n", uap->func,
619 uap->uc));
620 return ENOSYS;
621 }
622 return 0;
623}
624
625int
626svr4_sys_pause(p, uap)
627 register struct proc *p;
628 struct svr4_sys_pause_args *uap;
629{
630 struct sigsuspend_args bsa;
631
632 SCARG(&bsa, sigmask) = &p->p_sigmask;
633 return sigsuspend(p, &bsa);
634}
606 return copyout(&uc, uap->uc, sizeof(uc));
607
608 case 1:
609 DPRINTF(("setcontext(%p)\n", uap->uc));
610 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
611 return error;
612 DPRINTF(("uc_flags = %x\n", uc.uc_flags));
613 DPRINTF(("uc_sigmask = %x\n", uc.uc_sigmask));
614
615 return svr4_setcontext(p, &uc);
616
617 default:
618 DPRINTF(("context(%d, %p)\n", uap->func,
619 uap->uc));
620 return ENOSYS;
621 }
622 return 0;
623}
624
625int
626svr4_sys_pause(p, uap)
627 register struct proc *p;
628 struct svr4_sys_pause_args *uap;
629{
630 struct sigsuspend_args bsa;
631
632 SCARG(&bsa, sigmask) = &p->p_sigmask;
633 return sigsuspend(p, &bsa);
634}