mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-07 23:28:55 +00:00
signal: cleanup sys_rt_sigprocmask()
sys_rt_sigprocmask() looks unnecessarily complicated, simplify it. We can just read current->blocked lockless unconditionally before anything else and then copy-to-user it if needed. At worst we copy 4 words on mips. We could copy-to-user the old mask first and simplify the code even more, but the patch tries to keep the current behaviour: we change current->block even if copy_to_user(oset) fails. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com> Acked-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
e9bd3f0faa
commit
bb7efee2ca
1 changed files with 17 additions and 23 deletions
|
@ -2364,40 +2364,34 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
|
||||||
* @oset: previous value of signal mask if non-null
|
* @oset: previous value of signal mask if non-null
|
||||||
* @sigsetsize: size of sigset_t type
|
* @sigsetsize: size of sigset_t type
|
||||||
*/
|
*/
|
||||||
SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, set,
|
SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset,
|
||||||
sigset_t __user *, oset, size_t, sigsetsize)
|
sigset_t __user *, oset, size_t, sigsetsize)
|
||||||
{
|
{
|
||||||
int error = -EINVAL;
|
|
||||||
sigset_t old_set, new_set;
|
sigset_t old_set, new_set;
|
||||||
|
int error;
|
||||||
|
|
||||||
/* XXX: Don't preclude handling different sized sigset_t's. */
|
/* XXX: Don't preclude handling different sized sigset_t's. */
|
||||||
if (sigsetsize != sizeof(sigset_t))
|
if (sigsetsize != sizeof(sigset_t))
|
||||||
goto out;
|
return -EINVAL;
|
||||||
|
|
||||||
if (set) {
|
old_set = current->blocked;
|
||||||
error = -EFAULT;
|
|
||||||
if (copy_from_user(&new_set, set, sizeof(*set)))
|
if (nset) {
|
||||||
goto out;
|
if (copy_from_user(&new_set, nset, sizeof(sigset_t)))
|
||||||
|
return -EFAULT;
|
||||||
sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
|
sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
|
||||||
|
|
||||||
error = sigprocmask(how, &new_set, &old_set);
|
error = sigprocmask(how, &new_set, NULL);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
|
||||||
if (oset)
|
|
||||||
goto set_old;
|
|
||||||
} else if (oset) {
|
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
|
||||||
old_set = current->blocked;
|
|
||||||
spin_unlock_irq(¤t->sighand->siglock);
|
|
||||||
|
|
||||||
set_old:
|
|
||||||
error = -EFAULT;
|
|
||||||
if (copy_to_user(oset, &old_set, sizeof(*oset)))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
error = 0;
|
|
||||||
out:
|
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oset) {
|
||||||
|
if (copy_to_user(oset, &old_set, sizeof(sigset_t)))
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long do_sigpending(void __user *set, unsigned long sigsetsize)
|
long do_sigpending(void __user *set, unsigned long sigsetsize)
|
||||||
|
|
Loading…
Add table
Reference in a new issue