2 * Copyright (c) 1998 Mark Newton
3 * Copyright (c) 1994 Christos Zoulas
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/filedesc.h>
36 #include <sys/mutex.h>
38 #include <sys/signal.h>
39 #include <sys/signalvar.h>
40 #include <sys/syscallsubr.h>
41 #include <sys/sysproto.h>
43 #include <machine/cpu.h>
45 #include <compat/svr4/svr4.h>
46 #include <compat/svr4/svr4_types.h>
47 #include <compat/svr4/svr4_signal.h>
48 #include <compat/svr4/svr4_proto.h>
49 #include <compat/svr4/svr4_util.h>
50 #include <compat/svr4/svr4_ucontext.h>
52 #define svr4_sigmask(n) (1 << (((n) - 1) & 31))
53 #define svr4_sigword(n) (((n) - 1) >> 5)
54 #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
55 #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
56 #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
58 void svr4_to_bsd_sigaction(const struct svr4_sigaction *, struct sigaction *);
59 void bsd_to_svr4_sigaction(const struct sigaction *, struct svr4_sigaction *);
60 void svr4_sigfillset(svr4_sigset_t *);
62 int bsd_to_svr4_sig[SVR4_NSIG] = {
97 int svr4_to_bsd_sig[SVR4_NSIG] = {
117 0, /* XXX NetBSD uses SIGPWR here, but we don't seem to have one */
139 for (i = 1; i < SVR4_NSIG; i++)
140 if (svr4_to_bsd_sig[i] != 0)
141 svr4_sigaddset(s, i);
145 svr4_to_bsd_sigset(sss, bss)
146 const svr4_sigset_t *sss;
152 for (i = 1; i < SVR4_NSIG; i++)
153 if (svr4_sigismember(sss, i)) {
154 newsig = svr4_to_bsd_sig[i];
156 SIGADDSET(*bss, newsig);
161 bsd_to_svr4_sigset(bss, sss)
167 svr4_sigemptyset(sss);
168 for (i = 1; i < SVR4_NSIG; i++) {
169 if (SIGISMEMBER(*bss, i)) {
170 newsig = bsd_to_svr4_sig[i];
172 svr4_sigaddset(sss, newsig);
178 * XXX: Only a subset of the flags is currently implemented.
181 svr4_to_bsd_sigaction(ssa, bsa)
182 const struct svr4_sigaction *ssa;
183 struct sigaction *bsa;
186 bsa->sa_handler = (sig_t) ssa->ssa_handler;
187 svr4_to_bsd_sigset(&ssa->ssa_mask, &bsa->sa_mask);
189 if ((ssa->ssa_flags & SVR4_SA_ONSTACK) != 0)
190 bsa->sa_flags |= SA_ONSTACK;
191 if ((ssa->ssa_flags & SVR4_SA_RESETHAND) != 0)
192 bsa->sa_flags |= SA_RESETHAND;
193 if ((ssa->ssa_flags & SVR4_SA_RESTART) != 0)
194 bsa->sa_flags |= SA_RESTART;
195 if ((ssa->ssa_flags & SVR4_SA_SIGINFO) != 0)
196 DPRINTF(("svr4_to_bsd_sigaction: SA_SIGINFO ignored\n"));
197 if ((ssa->ssa_flags & SVR4_SA_NOCLDSTOP) != 0)
198 bsa->sa_flags |= SA_NOCLDSTOP;
199 if ((ssa->ssa_flags & SVR4_SA_NODEFER) != 0)
200 bsa->sa_flags |= SA_NODEFER;
201 if ((ssa->ssa_flags & SVR4_SA_NOCLDWAIT) != 0)
202 bsa->sa_flags |= SA_NOCLDWAIT;
203 if ((ssa->ssa_flags & ~SVR4_SA_ALLBITS) != 0)
204 DPRINTF(("svr4_to_bsd_sigaction: extra bits ignored\n"));
208 bsd_to_svr4_sigaction(bsa, ssa)
209 const struct sigaction *bsa;
210 struct svr4_sigaction *ssa;
213 ssa->ssa_handler = (svr4_sig_t) bsa->sa_handler;
214 bsd_to_svr4_sigset(&bsa->sa_mask, &ssa->ssa_mask);
216 if ((bsa->sa_flags & SA_ONSTACK) != 0)
217 ssa->ssa_flags |= SVR4_SA_ONSTACK;
218 if ((bsa->sa_flags & SA_RESETHAND) != 0)
219 ssa->ssa_flags |= SVR4_SA_RESETHAND;
220 if ((bsa->sa_flags & SA_RESTART) != 0)
221 ssa->ssa_flags |= SVR4_SA_RESTART;
222 if ((bsa->sa_flags & SA_NODEFER) != 0)
223 ssa->ssa_flags |= SVR4_SA_NODEFER;
224 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
225 ssa->ssa_flags |= SVR4_SA_NOCLDSTOP;
229 svr4_to_bsd_sigaltstack(sss, bss)
230 const struct svr4_sigaltstack *sss;
231 struct sigaltstack *bss;
234 bss->ss_sp = sss->ss_sp;
235 bss->ss_size = sss->ss_size;
237 if ((sss->ss_flags & SVR4_SS_DISABLE) != 0)
238 bss->ss_flags |= SS_DISABLE;
239 if ((sss->ss_flags & SVR4_SS_ONSTACK) != 0)
240 bss->ss_flags |= SS_ONSTACK;
241 if ((sss->ss_flags & ~SVR4_SS_ALLBITS) != 0)
242 /*XXX*/ uprintf("svr4_to_bsd_sigaltstack: extra bits ignored\n");
246 bsd_to_svr4_sigaltstack(bss, sss)
247 const struct sigaltstack *bss;
248 struct svr4_sigaltstack *sss;
251 sss->ss_sp = bss->ss_sp;
252 sss->ss_size = bss->ss_size;
254 if ((bss->ss_flags & SS_DISABLE) != 0)
255 sss->ss_flags |= SVR4_SS_DISABLE;
256 if ((bss->ss_flags & SS_ONSTACK) != 0)
257 sss->ss_flags |= SVR4_SS_ONSTACK;
261 svr4_sys_sigaction(td, uap)
263 struct svr4_sys_sigaction_args *uap;
265 struct svr4_sigaction isa;
266 struct sigaction nbsa, obsa;
267 struct sigaction *nbsap;
270 if (uap->signum < 0 || uap->signum >= SVR4_NSIG)
273 DPRINTF(("@@@ svr4_sys_sigaction(%d, %d, %d)\n", td->td_proc->p_pid,
275 SVR4_SVR42BSD_SIG(uap->signum)));
277 if (uap->nsa != NULL) {
278 if ((error = copyin(uap->nsa, &isa, sizeof(isa))) != 0)
280 svr4_to_bsd_sigaction(&isa, &nbsa);
284 #if defined(DEBUG_SVR4)
287 for (i = 0; i < 4; i++)
288 DPRINTF(("\tssa_mask[%d] = %lx\n", i,
289 isa.ssa_mask.bits[i]));
290 DPRINTF(("\tssa_handler = %p\n", isa.ssa_handler));
293 error = kern_sigaction(td, SVR4_SVR42BSD_SIG(uap->signum), nbsap, &obsa,
295 if (error == 0 && uap->osa != NULL) {
296 bsd_to_svr4_sigaction(&obsa, &isa);
297 error = copyout(&isa, uap->osa, sizeof(isa));
303 svr4_sys_sigaltstack(td, uap)
305 struct svr4_sys_sigaltstack_args *uap;
307 struct svr4_sigaltstack sss;
308 struct sigaltstack nbss, obss, *nbssp;
311 if (uap->nss != NULL) {
312 if ((error = copyin(uap->nss, &sss, sizeof(sss))) != 0)
314 svr4_to_bsd_sigaltstack(&sss, &nbss);
318 error = kern_sigaltstack(td, nbssp, &obss);
319 if (error == 0 && uap->oss != NULL) {
320 bsd_to_svr4_sigaltstack(&obss, &sss);
321 error = copyout(&sss, uap->oss, sizeof(sss));
327 * Stolen from the ibcs2 one
330 svr4_sys_signal(td, uap)
332 struct svr4_sys_signal_args *uap;
339 DPRINTF(("@@@ svr4_sys_signal(%d)\n", p->p_pid));
341 signum = SVR4_SIGNO(uap->signum);
342 if (signum < 0 || signum >= SVR4_NSIG) {
343 if (SVR4_SIGCALL(uap->signum) == SVR4_SIGNAL_MASK ||
344 SVR4_SIGCALL(uap->signum) == SVR4_SIGDEFER_MASK)
345 td->td_retval[0] = (int)SVR4_SIG_ERR;
348 signum = SVR4_SVR42BSD_SIG(signum);
350 switch (SVR4_SIGCALL(uap->signum)) {
351 case SVR4_SIGDEFER_MASK:
352 if (uap->handler == SVR4_SIG_HOLD)
356 case SVR4_SIGNAL_MASK:
358 struct sigaction nbsa, obsa;
360 nbsa.sa_handler = (sig_t) uap->handler;
361 SIGEMPTYSET(nbsa.sa_mask);
363 if (signum != SIGALRM)
364 nbsa.sa_flags = SA_RESTART;
365 error = kern_sigaction(td, signum, &nbsa, &obsa, 0);
367 DPRINTF(("signal: sigaction failed: %d\n",
369 td->td_retval[0] = (int)SVR4_SIG_ERR;
372 td->td_retval[0] = (int)obsa.sa_handler;
376 case SVR4_SIGHOLD_MASK:
382 SIGADDSET(set, signum);
383 return (kern_sigprocmask(td, SIG_BLOCK, &set, NULL, 0));
386 case SVR4_SIGRELSE_MASK:
391 SIGADDSET(set, signum);
392 return (kern_sigprocmask(td, SIG_UNBLOCK, &set, NULL,
396 case SVR4_SIGIGNORE_MASK:
400 sa.sa_handler = SIG_IGN;
401 SIGEMPTYSET(sa.sa_mask);
403 error = kern_sigaction(td, signum, &sa, NULL, 0);
405 DPRINTF(("sigignore: sigaction failed\n"));
409 case SVR4_SIGPAUSE_MASK:
414 mask = td->td_sigmask;
416 SIGDELSET(mask, signum);
417 return kern_sigsuspend(td, mask);
427 svr4_sys_sigprocmask(td, uap)
429 struct svr4_sys_sigprocmask_args *uap;
436 if (uap->set != NULL) {
437 if ((error = copyin(uap->set, &sss, sizeof(sss))) != 0)
439 svr4_to_bsd_sigset(&sss, &nss);
444 /* SVR/4 sigprocmask flag values are the same as the FreeBSD values. */
445 error = kern_sigprocmask(td, uap->how, nssp, &oss, 0);
446 if (error == 0 && uap->oset != NULL) {
447 bsd_to_svr4_sigset(&oss, &sss);
448 error = copyout(&sss, uap->oset, sizeof(sss));
454 svr4_sys_sigpending(td, uap)
456 struct svr4_sys_sigpending_args *uap;
463 DPRINTF(("@@@ svr4_sys_sigpending(%d)\n", p->p_pid));
465 case 1: /* sigpending */
466 if (uap->mask == NULL)
470 SIGSETOR(bss, td->td_siglist);
471 SIGSETAND(bss, td->td_sigmask);
473 bsd_to_svr4_sigset(&bss, &sss);
476 case 2: /* sigfillset */
477 svr4_sigfillset(&sss);
478 #if defined(DEBUG_SVR4)
481 for (i = 0; i < 4; i++)
482 DPRINTF(("new sigset[%d] = %lx\n", i, (long)sss.bits[i]));
491 return copyout(&sss, uap->mask, sizeof(sss));
495 svr4_sys_sigsuspend(td, uap)
497 struct svr4_sys_sigsuspend_args *uap;
503 if ((error = copyin(uap->ss, &sss, sizeof(sss))) != 0)
506 svr4_to_bsd_sigset(&sss, &bss);
507 return kern_sigsuspend(td, bss);
512 svr4_sys_kill(td, uap)
514 struct svr4_sys_kill_args *uap;
518 if (uap->signum < 0 || uap->signum >= SVR4_NSIG)
521 ka.signum = SVR4_SVR42BSD_SIG(uap->signum);
522 return sys_kill(td, &ka);
527 svr4_sys_context(td, uap)
529 struct svr4_sys_context_args *uap;
531 struct svr4_ucontext uc;
536 DPRINTF(("getcontext(%p)\n", uap->uc));
537 PROC_LOCK(td->td_proc);
538 onstack = sigonstack(cpu_getstack(td));
539 PROC_UNLOCK(td->td_proc);
540 svr4_getcontext(td, &uc, &td->td_sigmask, onstack);
541 return copyout(&uc, uap->uc, sizeof(uc));
544 DPRINTF(("setcontext(%p)\n", uap->uc));
545 if ((error = copyin(uap->uc, &uc, sizeof(uc))) != 0)
547 DPRINTF(("uc_flags = %lx\n", uc.uc_flags));
548 #if defined(DEBUG_SVR4)
551 for (i = 0; i < 4; i++)
552 DPRINTF(("uc_sigmask[%d] = %lx\n", i,
553 uc.uc_sigmask.bits[i]));
556 return svr4_setcontext(td, &uc);
559 DPRINTF(("context(%d, %p)\n", uap->func,
567 svr4_sys_pause(td, uap)
569 struct svr4_sys_pause_args *uap;
573 PROC_LOCK(td->td_proc);
574 mask = td->td_sigmask;
575 PROC_UNLOCK(td->td_proc);
576 return kern_sigsuspend(td, mask);