mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
new helper: sigsuspend()
guts of saved_sigmask-based sigsuspend/rt_sigsuspend. Takes kernel sigset_t *. Open-coded instances replaced with calling it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
bf67f3a5c4
commit
68f3f16d9a
@ -121,17 +121,8 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
|
||||
SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -67,17 +67,8 @@ const unsigned long syscall_restart_code[2] = {
|
||||
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -48,19 +48,11 @@ void do_signal(int canrestart, struct pt_regs *regs);
|
||||
* dummy arguments to be able to reach the regs argument. (Note that this
|
||||
* arrangement relies on old_sigset_t occupying one register.)
|
||||
*/
|
||||
int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
|
||||
long srp, struct pt_regs *regs)
|
||||
int sys_sigsuspend(old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
int sys_sigaction(int sig, const struct old_sigaction __user *act,
|
||||
|
@ -59,19 +59,11 @@ void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
|
||||
* dummy arguments to be able to reach the regs argument.
|
||||
*/
|
||||
int
|
||||
sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
|
||||
long srp, struct pt_regs *regs)
|
||||
sys_sigsuspend(old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -40,17 +40,9 @@ struct fdpic_func_descriptor {
|
||||
*/
|
||||
asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int sys_sigaction(int sig,
|
||||
|
@ -230,18 +230,9 @@ static inline void push_cache(unsigned long vaddr)
|
||||
asmlinkage int
|
||||
sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
|
||||
return -ERESTARTNOHAND;
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -255,15 +255,7 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
uset = (sigset_t __user *) regs.regs[4];
|
||||
if (copy_from_user(&newset, uset, sizeof(sigset_t)))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -281,15 +273,7 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
unewset = (sigset_t __user *) regs.regs[4];
|
||||
if (copy_from_user(&newset, unewset, sizeof(newset)))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRAD_SIGNALS
|
||||
|
@ -288,15 +288,7 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
uset = (compat_sigset_t __user *) regs.regs[4];
|
||||
if (get_sigset(&newset, uset))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
|
||||
asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
@ -313,15 +305,7 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
uset = (compat_sigset_t __user *) regs.regs[4];
|
||||
if (get_sigset(&newset, uset))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
|
||||
|
@ -91,15 +91,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||
if (copy_from_user(&uset, unewset, sizeof(uset)))
|
||||
return -EFAULT;
|
||||
sigset_from_compat(&newset, &uset);
|
||||
sigdelsetmask(&newset, ~_BLOCKABLE);
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
|
||||
asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
|
||||
|
@ -38,17 +38,9 @@
|
||||
*/
|
||||
asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
sigset_t blocked;
|
||||
siginitset(&blocked, mask);
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -244,17 +244,8 @@ static inline int restore_general_regs(struct pt_regs *regs,
|
||||
long sys_sigsuspend(old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
long sys_sigaction(int sig, struct old_sigaction __user *act,
|
||||
|
@ -59,15 +59,8 @@ typedef struct
|
||||
SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act,
|
||||
|
@ -58,18 +58,8 @@ sys_sigsuspend(old_sigset_t mask,
|
||||
struct pt_regs __regs)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -64,18 +64,8 @@ struct rt_signal_frame {
|
||||
static int _sigpause_common(old_sigset_t set)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
set &= _BLOCKABLE;
|
||||
siginitset(&blocked, set);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int sys_sigsuspend(old_sigset_t set)
|
||||
|
@ -242,19 +242,8 @@ struct rt_signal_frame {
|
||||
static long _sigpause_common(old_sigset_t set)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
set &= _BLOCKABLE;
|
||||
siginitset(&blocked, set);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
|
||||
set_restore_sigmask();
|
||||
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage long sys_sigpause(unsigned int set)
|
||||
|
@ -152,15 +152,8 @@ int do_signal(void)
|
||||
long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_thread_flag(TIF_RESTORE_SIGMASK);
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
|
||||
|
@ -127,18 +127,8 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
|
||||
asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
|
||||
|
@ -478,18 +478,8 @@ asmlinkage int
|
||||
sys_sigsuspend(int history0, int history1, old_sigset_t mask)
|
||||
{
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&blocked);
|
||||
}
|
||||
|
||||
asmlinkage int
|
||||
|
@ -252,6 +252,7 @@ extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
|
||||
extern int sigprocmask(int, sigset_t *, sigset_t *);
|
||||
extern void set_current_blocked(const sigset_t *);
|
||||
extern int show_unhandled_signals;
|
||||
extern int sigsuspend(sigset_t *);
|
||||
|
||||
extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
|
||||
extern void block_sigmask(struct k_sigaction *ka, int signr);
|
||||
|
@ -1073,15 +1073,7 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
|
||||
if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
|
||||
return -EFAULT;
|
||||
sigset_from_compat(&newset, &newset32);
|
||||
sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
#endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
|
||||
|
||||
|
@ -3236,6 +3236,21 @@ SYSCALL_DEFINE0(pause)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SET_RESTORE_SIGMASK
|
||||
int sigsuspend(sigset_t *set)
|
||||
{
|
||||
sigdelsetmask(set, sigmask(SIGKILL)|sigmask(SIGSTOP));
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(set);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND
|
||||
/**
|
||||
* sys_rt_sigsuspend - replace the signal mask for a value with the
|
||||
@ -3253,15 +3268,7 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
|
||||
|
||||
if (copy_from_user(&newset, unewset, sizeof(newset)))
|
||||
return -EFAULT;
|
||||
sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP));
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
set_current_blocked(&newset);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
set_restore_sigmask();
|
||||
return -ERESTARTNOHAND;
|
||||
return sigsuspend(&newset);
|
||||
}
|
||||
#endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user