瀏覽代碼

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>
Al Viro 13 年之前
父節點
當前提交
68f3f16d9a

+ 1 - 10
arch/alpha/kernel/signal.c

@@ -121,17 +121,8 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
 SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
 SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	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
 asmlinkage int

+ 1 - 10
arch/arm/kernel/signal.c

@@ -67,17 +67,8 @@ const unsigned long syscall_restart_code[2] = {
 asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
 asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	siginitset(&blocked, mask);
-	set_current_blocked(&blocked);
-
-	current->state = TASK_INTERRUPTIBLE;
-	schedule();
-	set_restore_sigmask();
-	return -ERESTARTNOHAND;
+	return sigsuspend(&blocked);
 }
 }
 
 
 asmlinkage int 
 asmlinkage int 

+ 4 - 12
arch/cris/arch-v10/kernel/signal.c

@@ -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
  * dummy arguments to be able to reach the regs argument.  (Note that this
  * arrangement relies on old_sigset_t occupying one register.)
  * 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,
 int sys_sigaction(int sig, const struct old_sigaction __user *act,

+ 4 - 12
arch/cris/arch-v32/kernel/signal.c

@@ -59,19 +59,11 @@ void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
  * dummy arguments to be able to reach the regs argument.
  * dummy arguments to be able to reach the regs argument.
  */
  */
 int
 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
 int

+ 3 - 11
arch/frv/kernel/signal.c

@@ -40,17 +40,9 @@ struct fdpic_func_descriptor {
  */
  */
 asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 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,
 asmlinkage int sys_sigaction(int sig,

+ 3 - 12
arch/m68k/kernel/signal.c

@@ -230,18 +230,9 @@ static inline void push_cache(unsigned long vaddr)
 asmlinkage int
 asmlinkage int
 sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
 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
 asmlinkage int

+ 2 - 18
arch/mips/kernel/signal.c

@@ -255,15 +255,7 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	uset = (sigset_t __user *) regs.regs[4];
 	uset = (sigset_t __user *) regs.regs[4];
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 		return -EFAULT;
 		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
 #endif
 
 
@@ -281,15 +273,7 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	unewset = (sigset_t __user *) regs.regs[4];
 	unewset = (sigset_t __user *) regs.regs[4];
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 		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
 #ifdef CONFIG_TRAD_SIGNALS

+ 2 - 18
arch/mips/kernel/signal32.c

@@ -288,15 +288,7 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	uset = (compat_sigset_t __user *) regs.regs[4];
 	uset = (compat_sigset_t __user *) regs.regs[4];
 	if (get_sigset(&newset, uset))
 	if (get_sigset(&newset, uset))
 		return -EFAULT;
 		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)
 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];
 	uset = (compat_sigset_t __user *) regs.regs[4];
 	if (get_sigset(&newset, uset))
 	if (get_sigset(&newset, uset))
 		return -EFAULT;
 		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,
 SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,

+ 1 - 9
arch/mips/kernel/signal_n32.c

@@ -91,15 +91,7 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 	if (copy_from_user(&uset, unewset, sizeof(uset)))
 	if (copy_from_user(&uset, unewset, sizeof(uset)))
 		return -EFAULT;
 		return -EFAULT;
 	sigset_from_compat(&newset, &uset);
 	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)
 asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)

+ 3 - 11
arch/mn10300/kernel/signal.c

@@ -38,17 +38,9 @@
  */
  */
 asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 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);
 }
 }
 
 
 /*
 /*

+ 1 - 10
arch/powerpc/kernel/signal_32.c

@@ -244,17 +244,8 @@ static inline int restore_general_regs(struct pt_regs *regs,
 long sys_sigsuspend(old_sigset_t mask)
 long sys_sigsuspend(old_sigset_t mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	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,
 long sys_sigaction(int sig, struct old_sigaction __user *act,

+ 1 - 8
arch/s390/kernel/signal.c

@@ -59,15 +59,8 @@ typedef struct
 SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
 SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	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,
 SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act,

+ 1 - 11
arch/sh/kernel/signal_32.c

@@ -58,18 +58,8 @@ sys_sigsuspend(old_sigset_t mask,
 	       struct pt_regs __regs)
 	       struct pt_regs __regs)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	siginitset(&blocked, mask);
-	set_current_blocked(&blocked);
-
-	current->state = TASK_INTERRUPTIBLE;
-	schedule();
-	set_restore_sigmask();
-
-	return -ERESTARTNOHAND;
+	return sigsuspend(&blocked);
 }
 }
 
 
 asmlinkage int
 asmlinkage int

+ 1 - 11
arch/sparc/kernel/signal_32.c

@@ -64,18 +64,8 @@ struct rt_signal_frame {
 static int _sigpause_common(old_sigset_t set)
 static int _sigpause_common(old_sigset_t set)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	set &= _BLOCKABLE;
 	siginitset(&blocked, set);
 	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)
 asmlinkage int sys_sigsuspend(old_sigset_t set)

+ 1 - 12
arch/sparc/kernel/signal_64.c

@@ -242,19 +242,8 @@ struct rt_signal_frame {
 static long _sigpause_common(old_sigset_t set)
 static long _sigpause_common(old_sigset_t set)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	set &= _BLOCKABLE;
 	siginitset(&blocked, set);
 	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)
 asmlinkage long sys_sigpause(unsigned int set)

+ 1 - 8
arch/um/kernel/signal.c

@@ -152,15 +152,8 @@ int do_signal(void)
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	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)
 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)

+ 1 - 11
arch/x86/ia32/ia32_signal.c

@@ -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)
 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	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,
 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,

+ 1 - 11
arch/x86/kernel/signal.c

@@ -478,18 +478,8 @@ asmlinkage int
 sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 sys_sigsuspend(int history0, int history1, old_sigset_t mask)
 {
 {
 	sigset_t blocked;
 	sigset_t blocked;
-
-	current->saved_sigmask = current->blocked;
-
-	mask &= _BLOCKABLE;
 	siginitset(&blocked, mask);
 	siginitset(&blocked, mask);
-	set_current_blocked(&blocked);
-
-	current->state = TASK_INTERRUPTIBLE;
-	schedule();
-
-	set_restore_sigmask();
-	return -ERESTARTNOHAND;
+	return sigsuspend(&blocked);
 }
 }
 
 
 asmlinkage int
 asmlinkage int

+ 1 - 0
include/linux/signal.h

@@ -252,6 +252,7 @@ extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 extern void set_current_blocked(const sigset_t *);
 extern void set_current_blocked(const sigset_t *);
 extern int show_unhandled_signals;
 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 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);
 extern void block_sigmask(struct k_sigaction *ka, int signr);

+ 1 - 9
kernel/compat.c

@@ -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)))
 	if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
 		return -EFAULT;
 		return -EFAULT;
 	sigset_from_compat(&newset, &newset32);
 	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 */
 #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
 
 

+ 16 - 9
kernel/signal.c

@@ -3236,6 +3236,21 @@ SYSCALL_DEFINE0(pause)
 
 
 #endif
 #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
 #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND
 /**
 /**
  *  sys_rt_sigsuspend - replace the signal mask for a value with the
  *  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)))
 	if (copy_from_user(&newset, unewset, sizeof(newset)))
 		return -EFAULT;
 		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 */
 #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */