int abi_sigprocmask(int how, u_long *abinset, u_long *abioset) { sigset_t new_set, *nset = NULL; sigset_t old_set, *oset = NULL; u_long new_set_abi, old_set_abi; mm_segment_t fs; int error; if (abinset) { get_user(new_set_abi, abinset); new_set = map_sigvec_to_kernel(new_set_abi, current_thread_info()->exec_domain->signal_map); nset = &new_set; } if (abioset) oset = &old_set; fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigprocmask,howcnv[how], nset, oset, sizeof(sigset_t)); set_fs(fs); if (!error && abioset) { old_set_abi = map_sigvec_from_kernel(old_set, current_thread_info()->exec_domain->signal_invmap); put_user(old_set_abi, abioset); } return (error); }
asmlinkage int abi_sigprocmask(int how, unsigned long *abinset, unsigned long *abioset) { sigset_t new_set, *nset, old_set, *oset; unsigned long new_set_abi, old_set_abi; mm_segment_t old_fs; int error; nset = oset = NULL; if (abinset) { get_user(new_set_abi, abinset); new_set = map_sigvec_to_kernel(new_set_abi, current->exec_domain->signal_map); nset = &new_set; } if (abioset) oset = &old_set; old_fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigprocmask)(howcnv[how], nset, oset, sizeof(sigset_t)); set_fs(old_fs); if (!error && abioset) { old_set_abi = map_sigvec_from_kernel(old_set, current->exec_domain->signal_invmap); put_user(old_set_abi, abioset); } return error; }
/* * This function is used to handle the sigaction call from SVr4 binaries. * * If anyone else uses this, this function needs to be modified since the * order and size of the ibcs_sigaction structure is different in ibcs * and the SVr4 ABI */ int abi_sigaction(int abi_signum, const struct abi_sigaction *action, struct abi_sigaction *oldaction) { struct abi_sigaction new_sa, old_sa; struct sigaction nsa, osa; mm_segment_t fs; int error, signo; signo = abi_mapsig(abi_signum); if (signo == -1) return -EINVAL; if (oldaction) { if (!access_ok(VERIFY_WRITE, oldaction, sizeof(struct abi_sigaction))) return (-EFAULT); } if (action) { error = copy_from_user(&new_sa, action, sizeof(struct abi_sigaction)); if (error) return (-EFAULT); nsa.sa_handler = new_sa.sa_handler; nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask, current_thread_info()->exec_domain->signal_map); nsa.sa_flags = SA_SIGINFO; if (new_sa.sa_flags & ABI_SA_ONSTACK) nsa.sa_flags |= SA_ONSTACK; if (new_sa.sa_flags & ABI_SA_RESTART) nsa.sa_flags |= SA_RESTART; if (new_sa.sa_flags & ABI_SA_NODEFER) nsa.sa_flags |= SA_NODEFER; if (new_sa.sa_flags & ABI_SA_RESETHAND) nsa.sa_flags |= SA_RESETHAND; if (new_sa.sa_flags & ABI_SA_NOCLDSTOP) nsa.sa_flags |= SA_NOCLDSTOP; if (new_sa.sa_flags & ABI_SA_NOCLDWAIT) nsa.sa_flags |= SA_NOCLDWAIT; nsa.sa_restorer = (void *)abi_sigret(__NR_rt_sigaction); if (nsa.sa_restorer) nsa.sa_flags |= SA_RESTORER; } fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigaction,signo, action ? &nsa : NULL, oldaction ? &osa : NULL, sizeof(sigset_t)); set_fs(fs); if (error || !oldaction) return (error); old_sa.sa_handler = osa.sa_handler; old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask, current_thread_info()->exec_domain->signal_invmap); old_sa.sa_flags = 0; if (osa.sa_flags & SA_ONSTACK) old_sa.sa_flags |= ABI_SA_ONSTACK; if (osa.sa_flags & SA_RESTART) old_sa.sa_flags |= ABI_SA_RESTART; if (osa.sa_flags & SA_NODEFER) old_sa.sa_flags |= ABI_SA_NODEFER; if (osa.sa_flags & SA_RESETHAND) old_sa.sa_flags |= ABI_SA_RESETHAND; if (osa.sa_flags & SA_NOCLDSTOP) old_sa.sa_flags |= ABI_SA_NOCLDSTOP; if (osa.sa_flags & SA_NOCLDWAIT) old_sa.sa_flags |= ABI_SA_NOCLDWAIT; /* * We already did the verify_area at the beginning. */ if (__copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction))) return -EFAULT; return 0; }
asmlinkage int abi_sigaction(int abi_signum, const struct abi_sigaction * action, struct abi_sigaction * oldaction) { struct abi_sigaction new_sa, old_sa; int error, signo; mm_segment_t old_fs; struct sigaction nsa, osa; signo = abi_mapsig(abi_signum); if (signo == -1) return -EINVAL; if (oldaction) { error = verify_area(VERIFY_WRITE, oldaction, sizeof(struct abi_sigaction)); if (error) return error; } if (action) { error = copy_from_user(&new_sa, action, sizeof(struct abi_sigaction)); if (error) return -EFAULT; nsa.sa_restorer = NULL; nsa.sa_handler = new_sa.sa_handler; nsa.sa_mask = map_sigvec_to_kernel(new_sa.sa_mask, current->exec_domain->signal_map); if(new_sa.sa_flags & ABI_SA_ONSTACK) nsa.sa_flags |= SA_ONSTACK; if(new_sa.sa_flags & ABI_SA_RESTART) nsa.sa_flags |= SA_RESTART; if(new_sa.sa_flags & ABI_SA_NODEFER) nsa.sa_flags |= SA_NODEFER; if(new_sa.sa_flags & ABI_SA_RESETHAND) nsa.sa_flags |= SA_RESETHAND; if(new_sa.sa_flags & ABI_SA_NOCLDSTOP) nsa.sa_flags |= SA_NOCLDSTOP; if(new_sa.sa_flags & ABI_SA_NOCLDWAIT) nsa.sa_flags |= SA_NOCLDWAIT; } old_fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigaction)(signo, action ? &nsa : NULL, oldaction ? &osa : NULL, sizeof(sigset_t)); set_fs(old_fs); if (!error && oldaction) { old_sa.sa_handler = osa.sa_handler; old_sa.sa_mask = map_sigvec_from_kernel(osa.sa_mask, current->exec_domain->signal_invmap); old_sa.sa_flags = 0; if(osa.sa_flags & SA_ONSTACK) old_sa.sa_flags |= ABI_SA_ONSTACK; if(osa.sa_flags & SA_RESTART) old_sa.sa_flags |= ABI_SA_RESTART; if(osa.sa_flags & SA_NODEFER) old_sa.sa_flags |= ABI_SA_NODEFER; if(osa.sa_flags & SA_RESETHAND) old_sa.sa_flags |= ABI_SA_RESETHAND; if(osa.sa_flags & SA_NOCLDSTOP) old_sa.sa_flags |= ABI_SA_NOCLDSTOP; if(osa.sa_flags & SA_NOCLDWAIT) old_sa.sa_flags |= ABI_SA_NOCLDWAIT; /* This should never fail... */ copy_to_user(oldaction, &old_sa, sizeof(struct abi_sigaction)); } return error; }