int compat_13_sys_sigaction(struct lwp *l, const struct compat_13_sys_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const struct sigaction13 *) nsa; syscallarg(struct sigaction13 *) osa; } */ struct sigaction13 nesa, oesa; struct sigaction nbsa, obsa; int error; if (SCARG(uap, nsa)) { error = copyin(SCARG(uap, nsa), &nesa, sizeof(nesa)); if (error) return (error); native_sigaction13_to_sigaction(&nesa, &nbsa); } error = sigaction1(l, SCARG(uap, signum), SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0, NULL, 0); if (error) return (error); if (SCARG(uap, osa)) { native_sigaction_to_sigaction13(&obsa, &oesa); error = copyout(&oesa, SCARG(uap, osa), sizeof(oesa)); if (error) return (error); } return (0); }
int sys___sigaction_sigtramp(struct lwp *l, const struct sys___sigaction_sigtramp_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const struct sigaction *) nsa; syscallarg(struct sigaction *) osa; syscallarg(void *) tramp; syscallarg(int) vers; } */ struct sigaction nsa, osa; int error; if (SCARG(uap, nsa)) { error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa)); if (error) return (error); } error = sigaction1(l, SCARG(uap, signum), SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0, SCARG(uap, tramp), SCARG(uap, vers)); if (error) return (error); if (SCARG(uap, osa)) { error = copyout(&osa, SCARG(uap, osa), sizeof(osa)); if (error) return (error); } return 0; }
int linux32_sys_signal(struct lwp *l, const struct linux32_sys_signal_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(linux32_handlerp_t) handler; } */ struct sigaction nbsa, obsa; int error, sig; *retval = -1; sig = SCARG(uap, signum); if (sig < 0 || sig >= LINUX32__NSIG) return EINVAL; nbsa.sa_handler = SCARG_P32(uap, handler); sigemptyset(&nbsa.sa_mask); nbsa.sa_flags = SA_RESETHAND | SA_NODEFER; if ((error = sigaction1(l, linux32_to_native_signo[sig], &nbsa, &obsa, NULL, 0)) != 0) return error; *retval = (int)(long)obsa.sa_handler; return 0; }
int ultrix_sys_sigvec(struct lwp *l, const struct ultrix_sys_sigvec_args *uap, register_t *retval) { struct sigvec nsv, osv; struct sigaction nsa, osa; int error; if (SCARG(uap, nsv)) { error = copyin(SCARG(uap, nsv), &nsv, sizeof(nsv)); if (error) return error; nsa.sa_handler = nsv.sv_handler; #if 0 /* documentation */ /* ONSTACK is identical */ nsa.sa_flags = nsv.sv_flags & ULTRIX_SV_ONSTACK; if ((nsv.sv_flags & ULTRIX_SV_OLDSIG) /* old signal() - always restart */ || (!(nsv.sv_flags & ULTRIX_SV_INTERRUPT)) /* inverted meaning (same bit) */ ) nsa.sa_flags |= SA_RESTART; #else /* optimized - assuming ULTRIX_SV_OLDSIG=>!ULTRIX_SV_INTERRUPT */ nsa.sa_flags = nsv.sv_flags & ~ULTRIX_SV_OLDSIG; nsa.sa_flags ^= SA_RESTART; #endif native_sigset13_to_sigset(&nsv.sv_mask, &nsa.sa_mask); } error = sigaction1(l, SCARG(uap, signum), SCARG(uap, nsv) ? &nsa : 0, SCARG(uap, osv) ? &osa : 0, NULL, 0); if (error) return error; if (SCARG(uap, osv)) { osv.sv_handler = osa.sa_handler; osv.sv_flags = osa.sa_flags ^ SA_RESTART; osv.sv_flags &= (ULTRIX_SV_ONSTACK | ULTRIX_SV_INTERRUPT); native_sigset_to_sigset13(&osa.sa_mask, &osv.sv_mask); error = copyout(&osv, SCARG(uap, osv), sizeof(osv)); if (error) return error; } return 0; }
int netbsd32_sigaction(struct lwp *l, const struct netbsd32_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const netbsd32_sigactionp_t) nsa; syscallarg(netbsd32_sigactionp_t) osa; } */ struct sigaction nsa, osa; struct netbsd32_sigaction13 *sa32p, sa32; int error; if (SCARG_P32(uap, nsa)) { sa32p = SCARG_P32(uap, nsa); if (copyin(sa32p, &sa32, sizeof(sa32))) return EFAULT; nsa.sa_handler = (void *)NETBSD32PTR64(sa32.netbsd32_sa_handler); memset(&nsa.sa_mask, 0, sizeof(nsa.sa_mask)); nsa.sa_mask.__bits[0] = sa32.netbsd32_sa_mask; nsa.sa_flags = sa32.netbsd32_sa_flags; } error = sigaction1(l, SCARG(uap, signum), SCARG_P32(uap, nsa) ? &nsa : 0, SCARG_P32(uap, osa) ? &osa : 0, NULL, 0); if (error) return (error); if (SCARG_P32(uap, osa)) { NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); sa32.netbsd32_sa_mask = osa.sa_mask.__bits[0]; sa32.netbsd32_sa_flags = osa.sa_flags; sa32p = SCARG_P32(uap, osa); if (copyout(&sa32, sa32p, sizeof(sa32))) return EFAULT; } return (0); }
int darwin_sys_sigaction(struct lwp *l, const struct darwin_sys_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(struct darwin___sigaction *) nsa; syscallarg(struct sigaction13 *) osa; } */ struct darwin___sigaction dsa; struct sigaction nsa, osa; struct sigaction13 sa13; int error; if ((error = copyin(SCARG(uap, nsa), &dsa, sizeof(dsa))) != 0) return error; nsa.sa_handler = dsa.darwin_sa_handler.__sa_handler; native_sigset13_to_sigset(&dsa.darwin_sa_mask, &nsa.sa_mask); if (dsa.darwin_sa_flags & ~DARWIN_SA_ALLBITS) { DPRINTF(("darwin_sys_sigaction: ignoring bits (flags = %x)\n", dsa.darwin_sa_flags)); } nsa.sa_flags = dsa.darwin_sa_flags & DARWIN_SA_ALLBITS; error = sigaction1(l, SCARG(uap, signum), &nsa, &osa, dsa.darwin_sa_tramp, 1); if (error != 0) return error; if (SCARG(uap, osa) == NULL) return 0; /* XXX: The returned structure has a different type to that supplied */ sa13.osa_handler = osa.sa_handler; sa13.osa_mask = osa.sa_mask.__bits[0]; native_sigset_to_sigset13(&osa.sa_mask, &sa13.osa_mask); sa13.osa_flags = osa.sa_flags; return copyout(&sa13, SCARG(uap, osa), sizeof(sa13)); }
/* ARGSUSED */ int netbsd32___sigaction_sigtramp(struct lwp *l, const struct netbsd32___sigaction_sigtramp_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const netbsd32_sigactionp_t) nsa; syscallarg(netbsd32_sigactionp_t) osa; syscallarg(netbsd32_voidp) tramp; syscallarg(int) vers; } */ struct netbsd32_sigaction sa32; struct sigaction nsa, osa; int error; if (SCARG_P32(uap, nsa)) { error = copyin(SCARG_P32(uap, nsa), &sa32, sizeof(sa32)); if (error) return (error); nsa.sa_handler = NETBSD32PTR64(sa32.netbsd32_sa_handler); nsa.sa_mask = sa32.netbsd32_sa_mask; nsa.sa_flags = sa32.netbsd32_sa_flags; } error = sigaction1(l, SCARG(uap, signum), SCARG_P32(uap, nsa) ? &nsa : 0, SCARG_P32(uap, osa) ? &osa : 0, SCARG_P32(uap, tramp), SCARG(uap, vers)); if (error) return (error); if (SCARG_P32(uap, osa)) { NETBSD32PTR32(sa32.netbsd32_sa_handler, osa.sa_handler); sa32.netbsd32_sa_mask = osa.sa_mask; sa32.netbsd32_sa_flags = osa.sa_flags; error = copyout(&sa32, SCARG_P32(uap, osa), sizeof(sa32)); if (error) return (error); } return (0); }
/* * The Linux signal() system call. I think that the signal() in the C * library actually calls sigaction, so I doubt this one is ever used. * But hey, it can't hurt having it here. The same restrictions as for * sigaction() apply. */ int linux_sys_signal(struct lwp *l, const struct linux_sys_signal_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(linux_handler_t) handler; } */ struct sigaction nbsa, obsa; int error, sig; *retval = -1; sig = SCARG(uap, signum); if (sig < 0 || sig >= LINUX__NSIG) return (EINVAL); nbsa.sa_handler = SCARG(uap, handler); sigemptyset(&nbsa.sa_mask); nbsa.sa_flags = SA_RESETHAND | SA_NODEFER; error = sigaction1(l, linux_to_native_signo[sig], &nbsa, &obsa, NULL, 0); if (error == 0) *retval = (int)(long)obsa.sa_handler; /* XXXmanu cast */ return (error); }
int linux32_sys_rt_sigaction(struct lwp *l, const struct linux32_sys_rt_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const linux32_sigactionp_t) nsa; syscallarg(linux32_sigactionp_t) osa; syscallarg(netbsd32_size_t) sigsetsize; } */ struct linux32_sigaction nls32; struct linux32_sigaction ols32; struct sigaction ns; struct sigaction os; int error; int sig; int vers = 0; void *tramp = NULL; if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t)) { DPRINTF(("rt_sigaction: Inconsistent sigsetsize %u %zu\n", SCARG(uap, sigsetsize), sizeof(linux32_sigset_t))); return EINVAL; } if (SCARG_P32(uap, nsa) != NULL) { if ((error = copyin(SCARG_P32(uap, nsa), &nls32, sizeof(nls32))) != 0) { DPRINTF(("rt_sigaction: Copyin %d\n", error)); return error; } linux32_to_native_sigaction(&ns, &nls32); } sig = SCARG(uap, signum); if (sig < 0 || sig >= LINUX32__NSIG) { DPRINTF(("rt_sigaction: Bad signal number %d %d\n", sig, LINUX32__NSIG)); return EINVAL; } if (sig > 0 && !linux32_to_native_signo[sig]) { /* unknown signal... */ os.sa_handler = SIG_IGN; sigemptyset(&os.sa_mask); os.sa_flags = 0; } else { if ((error = sigaction1(l, linux32_to_native_signo[sig], SCARG_P32(uap, nsa) ? &ns : NULL, SCARG_P32(uap, osa) ? &os : NULL, tramp, vers)) != 0) { DPRINTF(("rt_sigaction: sigaction %d\n", error)); return error; } } if (SCARG_P32(uap, osa) != NULL) { native_to_linux32_sigaction(&ols32, &os); if ((error = copyout(&ols32, SCARG_P32(uap, osa), sizeof(ols32))) != 0) { DPRINTF(("rt_sigaction: Copyout %d\n", error)); return error; } } return 0; }
/* * The Linux sigaction() system call. Do the usual conversions, * and just call sigaction(). Some flags and values are silently * ignored (see above). */ int linux_sys_rt_sigaction(struct lwp *l, const struct linux_sys_rt_sigaction_args *uap, register_t *retval) { /* { syscallarg(int) signum; syscallarg(const struct linux_sigaction *) nsa; syscallarg(struct linux_sigaction *) osa; syscallarg(size_t) sigsetsize; } */ struct linux_sigaction nlsa, olsa; struct sigaction nbsa, obsa; int error, sig; void *tramp = NULL; int vers = 0; #ifdef LINUX_SA_RESTORER struct sigacts *ps = l->l_proc->p_sigacts; #endif if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t)) return (EINVAL); if (SCARG(uap, nsa)) { error = copyin(SCARG(uap, nsa), &nlsa, sizeof(nlsa)); if (error) return (error); linux_to_native_sigaction(&nbsa, &nlsa); } sig = SCARG(uap, signum); if (sig < 0 || sig >= LINUX__NSIG) return (EINVAL); if (sig > 0 && !linux_to_native_signo[sig]) { /* Pretend that we did something useful for unknown signals. */ obsa.sa_handler = SIG_IGN; sigemptyset(&obsa.sa_mask); obsa.sa_flags = 0; } else { #ifdef LINUX_SA_RESTORER if ((nlsa.linux_sa_flags & LINUX_SA_RESTORER) && (tramp = nlsa.linux_sa_restorer) != NULL) vers = 2; #endif error = sigaction1(l, linux_to_native_signo[sig], SCARG(uap, nsa) ? &nbsa : NULL, SCARG(uap, osa) ? &obsa : NULL, tramp, vers); if (error) return (error); } if (SCARG(uap, osa)) { native_to_linux_sigaction(&olsa, &obsa); #ifdef LINUX_SA_RESTORER if (ps->sa_sigdesc[sig].sd_vers != 0) { olsa.linux_sa_restorer = ps->sa_sigdesc[sig].sd_tramp; olsa.linux_sa_flags |= LINUX_SA_RESTORER; } #endif error = copyout(&olsa, SCARG(uap, osa), sizeof(olsa)); if (error) return (error); } return (0); }