static void linux_save_ucontext(struct lwp *l, struct trapframe *tf, const sigset_t *mask, struct sigaltstack *sas, struct linux_ucontext *uc) { uc->uc_flags = 0; uc->uc_link = NULL; native_to_linux_sigaltstack(&uc->uc_stack, sas); linux_save_sigcontext(l, tf, mask, &uc->uc_mcontext); native_to_linux_sigset(&uc->uc_sigmask, mask); (void)memset(&uc->uc_fpregs_mem, 0, sizeof(uc->uc_fpregs_mem)); }
int linux_sys_sigaltstack(struct lwp *l, const struct linux_sys_sigaltstack_args *uap, register_t *retval) { /* { syscallarg(const struct linux_sigaltstack *) ss; syscallarg(struct linux_sigaltstack *) oss; } */ struct linux_sigaltstack ss; struct sigaltstack nss; struct proc *p = l->l_proc; int error = 0; if (SCARG(uap, oss)) { native_to_linux_sigaltstack(&ss, &l->l_sigstk); if ((error = copyout(&ss, SCARG(uap, oss), sizeof(ss))) != 0) return error; } if (SCARG(uap, ss) != NULL) { if ((error = copyin(SCARG(uap, ss), &ss, sizeof(ss))) != 0) return error; linux_to_native_sigaltstack(&nss, &ss); mutex_enter(p->p_lock); if (nss.ss_flags & ~SS_ALLBITS) error = EINVAL; else if (nss.ss_flags & SS_DISABLE) { if (l->l_sigstk.ss_flags & SS_ONSTACK) error = EINVAL; } else if (nss.ss_size < LINUX_MINSIGSTKSZ) error = ENOMEM; if (error == 0) l->l_sigstk = nss; mutex_exit(p->p_lock); } return error; }