new helper: sigsuspend()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 May 2012 01:42:32 +0000 (21:42 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 22 May 2012 03:52:30 +0000 (23:52 -0400)
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>
21 files changed:
arch/alpha/kernel/signal.c
arch/arm/kernel/signal.c
arch/cris/arch-v10/kernel/signal.c
arch/cris/arch-v32/kernel/signal.c
arch/frv/kernel/signal.c
arch/m68k/kernel/signal.c
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mn10300/kernel/signal.c
arch/powerpc/kernel/signal_32.c
arch/s390/kernel/signal.c
arch/sh/kernel/signal_32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/um/kernel/signal.c
arch/x86/ia32/ia32_signal.c
arch/x86/kernel/signal.c
include/linux/signal.h
kernel/compat.c
kernel/signal.c

index 35f2ef44de12629cfa166cef50f23b5e72b365cb..74b05e6ed44153e9b4d1841a43e64db948304237 100644 (file)
@@ -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
index 73d9a420850def55f6ea65cc1b00aa85c6d3245f..4e5fdd9bd9e39778b64c5354544b1c7f9fe89d77 100644 (file)
@@ -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 
index 289c584ba499505705bb1c8fce122609ac3f1cc0..170f4970d590514cdd6597ac68e85a54187934af 100644 (file)
@@ -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(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->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,
index ce4ab1a5552cae542ab4b7234867a0926f5857c3..e09083208cb6058ceaf5f3f92a52a6111c4cebb7 100644 (file)
@@ -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(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->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
index bab01298b58ee2873fd7ef85de9230ac7af354f7..df957c7ba387727067952f9c7c922fda518ecb9f 100644 (file)
@@ -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(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->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,
index 1747c7030a336e2c2c6a7920fedc7c3f7a49ab47..8186982fb320761303ef4e3c3f456d4bd1ed6f1c 100644 (file)
@@ -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(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       set_restore_sigmask();
-
-       return -ERESTARTNOHAND;
+       sigset_t blocked;
+       siginitset(&blocked, mask);
+       return sigsuspend(&blocked);
 }
 
 asmlinkage int
index d5a338a1739c9027fcc3db50c30a59f15f6c2e62..17f6ee30ad0d604da53fca7da7569bf4006d3d35 100644 (file)
@@ -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
index ac3b8d89aae51a4a75f14249ddc5a4f894046087..b4fe2eacbd5d258a55146f5d51154491119569e8 100644 (file)
@@ -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,
index 86eb4b04631c43924527231da81e3e23a5b01d0e..63ffac9af7c5b61fa9fa966e641889f935b7d747 100644 (file)
@@ -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)
index 690f4e9507d77811ef58f75a57960b1b078189a5..50eb94a05826b17d6ce2972617f73eb40911bf99 100644 (file)
  */
 asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
-       mask &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       set_thread_flag(TIF_RESTORE_SIGMASK);
-       return -ERESTARTNOHAND;
+       sigset_t blocked;
+       siginitset(&blocked, mask);
+       return sigsuspend(&blocked);
 }
 
 /*
index 45eb998557f8c3fbd9f8de333f58b17a29c2c959..ac1f96027bf56e992522345d68532632015095d3 100644 (file)
@@ -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,
index 8a4e2b760d562eebc32124bb4680aa391a9cb476..f626232e216c0ca100f14c1cbeed52c8696c578f 100644 (file)
@@ -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,
index 5901fba3176e519e3c8ecdc947c532b55c7b884a..46c9f9b00b14d52b6585aae6297a556cfe203b93 100644 (file)
@@ -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
index ac8e66b50f07d812c52ae0f65a40236be9bfb89d..2b7e849f7c6528b1da91146f3f515ccbf21370c3 100644 (file)
@@ -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)
index 48b0f57b65f7e8f0820ba7f60d2df9e4823f2449..eafaab486b2d24465a0911e46a08c35ce17d3d29 100644 (file)
@@ -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)
index fb12f4c5e649f60e8ddd847f88fc7c72b5639d24..b9b75b3bd5c93b923b1b440ccc431d0f842f5970 100644 (file)
@@ -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)
index a69245ba27e328363de1e389dd5ba50ed2eb979c..fa54410c666652cf40cbfc63c2cd5fda87a5689f 100644 (file)
@@ -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,
index 115eac431483cbc6acc3a01d54f26abcd69d0227..b68ccadd2ff4ba52217a703de590d00803af9b95 100644 (file)
@@ -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
index 7987ce74874b366b413ef6191b67caf02b42aba4..17046cc484bced6426c36b81f43ce43fdf0ffde4 100644 (file)
@@ -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);
index d2c67aa49ae667f85d41e2616ece39654ba9d0b3..c28a306ae05c069bbd11f107438459c106c5dc59 100644 (file)
@@ -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 */
 
index 17afcaf582d07a5bb8abf843a44d1f593403e473..3ad220a81619d84d777b001a28c739242029d2dc 100644 (file)
@@ -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 */