Commit 68f3f16d9ad0f1e28ab3fd0001ab5798c41f15a3
1 parent
bf67f3a5c4
Exists in
master
and in
20 other branches
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>
Showing 21 changed files with 50 additions and 223 deletions Side-by-side Diff
- 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
arch/alpha/kernel/signal.c
... | ... | @@ -121,17 +121,8 @@ |
121 | 121 | SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) |
122 | 122 | { |
123 | 123 | sigset_t blocked; |
124 | - | |
125 | - current->saved_sigmask = current->blocked; | |
126 | - | |
127 | - mask &= _BLOCKABLE; | |
128 | 124 | siginitset(&blocked, mask); |
129 | - set_current_blocked(&blocked); | |
130 | - | |
131 | - current->state = TASK_INTERRUPTIBLE; | |
132 | - schedule(); | |
133 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
134 | - return -ERESTARTNOHAND; | |
125 | + return sigsuspend(&blocked); | |
135 | 126 | } |
136 | 127 | |
137 | 128 | asmlinkage int |
arch/arm/kernel/signal.c
... | ... | @@ -67,17 +67,8 @@ |
67 | 67 | asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) |
68 | 68 | { |
69 | 69 | sigset_t blocked; |
70 | - | |
71 | - current->saved_sigmask = current->blocked; | |
72 | - | |
73 | - mask &= _BLOCKABLE; | |
74 | 70 | siginitset(&blocked, mask); |
75 | - set_current_blocked(&blocked); | |
76 | - | |
77 | - current->state = TASK_INTERRUPTIBLE; | |
78 | - schedule(); | |
79 | - set_restore_sigmask(); | |
80 | - return -ERESTARTNOHAND; | |
71 | + return sigsuspend(&blocked); | |
81 | 72 | } |
82 | 73 | |
83 | 74 | asmlinkage int |
arch/cris/arch-v10/kernel/signal.c
... | ... | @@ -48,19 +48,11 @@ |
48 | 48 | * dummy arguments to be able to reach the regs argument. (Note that this |
49 | 49 | * arrangement relies on old_sigset_t occupying one register.) |
50 | 50 | */ |
51 | -int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, | |
52 | - long srp, struct pt_regs *regs) | |
51 | +int sys_sigsuspend(old_sigset_t mask) | |
53 | 52 | { |
54 | - mask &= _BLOCKABLE; | |
55 | - spin_lock_irq(¤t->sighand->siglock); | |
56 | - current->saved_sigmask = current->blocked; | |
57 | - siginitset(¤t->blocked, mask); | |
58 | - recalc_sigpending(); | |
59 | - spin_unlock_irq(¤t->sighand->siglock); | |
60 | - current->state = TASK_INTERRUPTIBLE; | |
61 | - schedule(); | |
62 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
63 | - return -ERESTARTNOHAND; | |
53 | + sigset_t blocked; | |
54 | + siginitset(&blocked, mask); | |
55 | + return sigsuspend(&blocked); | |
64 | 56 | } |
65 | 57 | |
66 | 58 | int sys_sigaction(int sig, const struct old_sigaction __user *act, |
arch/cris/arch-v32/kernel/signal.c
... | ... | @@ -59,19 +59,11 @@ |
59 | 59 | * dummy arguments to be able to reach the regs argument. |
60 | 60 | */ |
61 | 61 | int |
62 | -sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, | |
63 | - long srp, struct pt_regs *regs) | |
62 | +sys_sigsuspend(old_sigset_t mask) | |
64 | 63 | { |
65 | - mask &= _BLOCKABLE; | |
66 | - spin_lock_irq(¤t->sighand->siglock); | |
67 | - current->saved_sigmask = current->blocked; | |
68 | - siginitset(¤t->blocked, mask); | |
69 | - recalc_sigpending(); | |
70 | - spin_unlock_irq(¤t->sighand->siglock); | |
71 | - current->state = TASK_INTERRUPTIBLE; | |
72 | - schedule(); | |
73 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
74 | - return -ERESTARTNOHAND; | |
64 | + sigset_t blocked; | |
65 | + siginitset(&blocked, mask); | |
66 | + return sigsuspend(&blocked); | |
75 | 67 | } |
76 | 68 | |
77 | 69 | int |
arch/frv/kernel/signal.c
... | ... | @@ -40,17 +40,9 @@ |
40 | 40 | */ |
41 | 41 | asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask) |
42 | 42 | { |
43 | - mask &= _BLOCKABLE; | |
44 | - spin_lock_irq(¤t->sighand->siglock); | |
45 | - current->saved_sigmask = current->blocked; | |
46 | - siginitset(¤t->blocked, mask); | |
47 | - recalc_sigpending(); | |
48 | - spin_unlock_irq(¤t->sighand->siglock); | |
49 | - | |
50 | - current->state = TASK_INTERRUPTIBLE; | |
51 | - schedule(); | |
52 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
53 | - return -ERESTARTNOHAND; | |
43 | + sigset_t blocked; | |
44 | + siginitset(&blocked, mask); | |
45 | + return sigsuspend(&blocked); | |
54 | 46 | } |
55 | 47 | |
56 | 48 | asmlinkage int sys_sigaction(int sig, |
arch/m68k/kernel/signal.c
... | ... | @@ -230,18 +230,9 @@ |
230 | 230 | asmlinkage int |
231 | 231 | sys_sigsuspend(int unused0, int unused1, old_sigset_t mask) |
232 | 232 | { |
233 | - mask &= _BLOCKABLE; | |
234 | - spin_lock_irq(¤t->sighand->siglock); | |
235 | - current->saved_sigmask = current->blocked; | |
236 | - siginitset(¤t->blocked, mask); | |
237 | - recalc_sigpending(); | |
238 | - spin_unlock_irq(¤t->sighand->siglock); | |
239 | - | |
240 | - current->state = TASK_INTERRUPTIBLE; | |
241 | - schedule(); | |
242 | - set_restore_sigmask(); | |
243 | - | |
244 | - return -ERESTARTNOHAND; | |
233 | + sigset_t blocked; | |
234 | + siginitset(&blocked, mask); | |
235 | + return sigsuspend(&blocked); | |
245 | 236 | } |
246 | 237 | |
247 | 238 | asmlinkage int |
arch/mips/kernel/signal.c
... | ... | @@ -255,15 +255,7 @@ |
255 | 255 | uset = (sigset_t __user *) regs.regs[4]; |
256 | 256 | if (copy_from_user(&newset, uset, sizeof(sigset_t))) |
257 | 257 | return -EFAULT; |
258 | - sigdelsetmask(&newset, ~_BLOCKABLE); | |
259 | - | |
260 | - current->saved_sigmask = current->blocked; | |
261 | - set_current_blocked(&newset); | |
262 | - | |
263 | - current->state = TASK_INTERRUPTIBLE; | |
264 | - schedule(); | |
265 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
266 | - return -ERESTARTNOHAND; | |
258 | + return sigsuspend(&newset); | |
267 | 259 | } |
268 | 260 | #endif |
269 | 261 | |
... | ... | @@ -281,15 +273,7 @@ |
281 | 273 | unewset = (sigset_t __user *) regs.regs[4]; |
282 | 274 | if (copy_from_user(&newset, unewset, sizeof(newset))) |
283 | 275 | return -EFAULT; |
284 | - sigdelsetmask(&newset, ~_BLOCKABLE); | |
285 | - | |
286 | - current->saved_sigmask = current->blocked; | |
287 | - set_current_blocked(&newset); | |
288 | - | |
289 | - current->state = TASK_INTERRUPTIBLE; | |
290 | - schedule(); | |
291 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
292 | - return -ERESTARTNOHAND; | |
276 | + return sigsuspend(&newset); | |
293 | 277 | } |
294 | 278 | |
295 | 279 | #ifdef CONFIG_TRAD_SIGNALS |
arch/mips/kernel/signal32.c
... | ... | @@ -288,15 +288,7 @@ |
288 | 288 | uset = (compat_sigset_t __user *) regs.regs[4]; |
289 | 289 | if (get_sigset(&newset, uset)) |
290 | 290 | return -EFAULT; |
291 | - sigdelsetmask(&newset, ~_BLOCKABLE); | |
292 | - | |
293 | - current->saved_sigmask = current->blocked; | |
294 | - set_current_blocked(&newset); | |
295 | - | |
296 | - current->state = TASK_INTERRUPTIBLE; | |
297 | - schedule(); | |
298 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
299 | - return -ERESTARTNOHAND; | |
291 | + return sigsuspend(&newset); | |
300 | 292 | } |
301 | 293 | |
302 | 294 | asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) |
... | ... | @@ -313,15 +305,7 @@ |
313 | 305 | uset = (compat_sigset_t __user *) regs.regs[4]; |
314 | 306 | if (get_sigset(&newset, uset)) |
315 | 307 | return -EFAULT; |
316 | - sigdelsetmask(&newset, ~_BLOCKABLE); | |
317 | - | |
318 | - current->saved_sigmask = current->blocked; | |
319 | - set_current_blocked(&newset); | |
320 | - | |
321 | - current->state = TASK_INTERRUPTIBLE; | |
322 | - schedule(); | |
323 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
324 | - return -ERESTARTNOHAND; | |
308 | + return sigsuspend(&newset); | |
325 | 309 | } |
326 | 310 | |
327 | 311 | SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act, |
arch/mips/kernel/signal_n32.c
... | ... | @@ -91,15 +91,7 @@ |
91 | 91 | if (copy_from_user(&uset, unewset, sizeof(uset))) |
92 | 92 | return -EFAULT; |
93 | 93 | sigset_from_compat(&newset, &uset); |
94 | - sigdelsetmask(&newset, ~_BLOCKABLE); | |
95 | - | |
96 | - current->saved_sigmask = current->blocked; | |
97 | - set_current_blocked(&newset); | |
98 | - | |
99 | - current->state = TASK_INTERRUPTIBLE; | |
100 | - schedule(); | |
101 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
102 | - return -ERESTARTNOHAND; | |
94 | + return sigsuspend(&newset); | |
103 | 95 | } |
104 | 96 | |
105 | 97 | asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |
arch/mn10300/kernel/signal.c
... | ... | @@ -38,17 +38,9 @@ |
38 | 38 | */ |
39 | 39 | asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask) |
40 | 40 | { |
41 | - mask &= _BLOCKABLE; | |
42 | - spin_lock_irq(¤t->sighand->siglock); | |
43 | - current->saved_sigmask = current->blocked; | |
44 | - siginitset(¤t->blocked, mask); | |
45 | - recalc_sigpending(); | |
46 | - spin_unlock_irq(¤t->sighand->siglock); | |
47 | - | |
48 | - current->state = TASK_INTERRUPTIBLE; | |
49 | - schedule(); | |
50 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
51 | - return -ERESTARTNOHAND; | |
41 | + sigset_t blocked; | |
42 | + siginitset(&blocked, mask); | |
43 | + return sigsuspend(&blocked); | |
52 | 44 | } |
53 | 45 | |
54 | 46 | /* |
arch/powerpc/kernel/signal_32.c
... | ... | @@ -244,17 +244,8 @@ |
244 | 244 | long sys_sigsuspend(old_sigset_t mask) |
245 | 245 | { |
246 | 246 | sigset_t blocked; |
247 | - | |
248 | - current->saved_sigmask = current->blocked; | |
249 | - | |
250 | - mask &= _BLOCKABLE; | |
251 | 247 | siginitset(&blocked, mask); |
252 | - set_current_blocked(&blocked); | |
253 | - | |
254 | - current->state = TASK_INTERRUPTIBLE; | |
255 | - schedule(); | |
256 | - set_restore_sigmask(); | |
257 | - return -ERESTARTNOHAND; | |
248 | + return sigsuspend(&blocked); | |
258 | 249 | } |
259 | 250 | |
260 | 251 | long sys_sigaction(int sig, struct old_sigaction __user *act, |
arch/s390/kernel/signal.c
... | ... | @@ -59,15 +59,8 @@ |
59 | 59 | SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) |
60 | 60 | { |
61 | 61 | sigset_t blocked; |
62 | - | |
63 | - current->saved_sigmask = current->blocked; | |
64 | - mask &= _BLOCKABLE; | |
65 | 62 | siginitset(&blocked, mask); |
66 | - set_current_blocked(&blocked); | |
67 | - set_current_state(TASK_INTERRUPTIBLE); | |
68 | - schedule(); | |
69 | - set_restore_sigmask(); | |
70 | - return -ERESTARTNOHAND; | |
63 | + return sigsuspend(&blocked); | |
71 | 64 | } |
72 | 65 | |
73 | 66 | SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act, |
arch/sh/kernel/signal_32.c
... | ... | @@ -58,18 +58,8 @@ |
58 | 58 | struct pt_regs __regs) |
59 | 59 | { |
60 | 60 | sigset_t blocked; |
61 | - | |
62 | - current->saved_sigmask = current->blocked; | |
63 | - | |
64 | - mask &= _BLOCKABLE; | |
65 | 61 | siginitset(&blocked, mask); |
66 | - set_current_blocked(&blocked); | |
67 | - | |
68 | - current->state = TASK_INTERRUPTIBLE; | |
69 | - schedule(); | |
70 | - set_restore_sigmask(); | |
71 | - | |
72 | - return -ERESTARTNOHAND; | |
62 | + return sigsuspend(&blocked); | |
73 | 63 | } |
74 | 64 | |
75 | 65 | asmlinkage int |
arch/sparc/kernel/signal_32.c
... | ... | @@ -64,18 +64,8 @@ |
64 | 64 | static int _sigpause_common(old_sigset_t set) |
65 | 65 | { |
66 | 66 | sigset_t blocked; |
67 | - | |
68 | - current->saved_sigmask = current->blocked; | |
69 | - | |
70 | - set &= _BLOCKABLE; | |
71 | 67 | siginitset(&blocked, set); |
72 | - set_current_blocked(&blocked); | |
73 | - | |
74 | - current->state = TASK_INTERRUPTIBLE; | |
75 | - schedule(); | |
76 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
77 | - | |
78 | - return -ERESTARTNOHAND; | |
68 | + return sigsuspend(&blocked); | |
79 | 69 | } |
80 | 70 | |
81 | 71 | asmlinkage int sys_sigsuspend(old_sigset_t set) |
arch/sparc/kernel/signal_64.c
... | ... | @@ -242,19 +242,8 @@ |
242 | 242 | static long _sigpause_common(old_sigset_t set) |
243 | 243 | { |
244 | 244 | sigset_t blocked; |
245 | - | |
246 | - current->saved_sigmask = current->blocked; | |
247 | - | |
248 | - set &= _BLOCKABLE; | |
249 | 245 | siginitset(&blocked, set); |
250 | - set_current_blocked(&blocked); | |
251 | - | |
252 | - current->state = TASK_INTERRUPTIBLE; | |
253 | - schedule(); | |
254 | - | |
255 | - set_restore_sigmask(); | |
256 | - | |
257 | - return -ERESTARTNOHAND; | |
246 | + return sigsuspend(&blocked); | |
258 | 247 | } |
259 | 248 | |
260 | 249 | asmlinkage long sys_sigpause(unsigned int set) |
arch/um/kernel/signal.c
... | ... | @@ -152,15 +152,8 @@ |
152 | 152 | long sys_sigsuspend(int history0, int history1, old_sigset_t mask) |
153 | 153 | { |
154 | 154 | sigset_t blocked; |
155 | - | |
156 | - mask &= _BLOCKABLE; | |
157 | 155 | siginitset(&blocked, mask); |
158 | - set_current_blocked(&blocked); | |
159 | - | |
160 | - current->state = TASK_INTERRUPTIBLE; | |
161 | - schedule(); | |
162 | - set_thread_flag(TIF_RESTORE_SIGMASK); | |
163 | - return -ERESTARTNOHAND; | |
156 | + return sigsuspend(&blocked); | |
164 | 157 | } |
165 | 158 | |
166 | 159 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) |
arch/x86/ia32/ia32_signal.c
... | ... | @@ -127,18 +127,8 @@ |
127 | 127 | asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask) |
128 | 128 | { |
129 | 129 | sigset_t blocked; |
130 | - | |
131 | - current->saved_sigmask = current->blocked; | |
132 | - | |
133 | - mask &= _BLOCKABLE; | |
134 | 130 | siginitset(&blocked, mask); |
135 | - set_current_blocked(&blocked); | |
136 | - | |
137 | - current->state = TASK_INTERRUPTIBLE; | |
138 | - schedule(); | |
139 | - | |
140 | - set_restore_sigmask(); | |
141 | - return -ERESTARTNOHAND; | |
131 | + return sigsuspend(&blocked); | |
142 | 132 | } |
143 | 133 | |
144 | 134 | asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, |
arch/x86/kernel/signal.c
... | ... | @@ -478,18 +478,8 @@ |
478 | 478 | sys_sigsuspend(int history0, int history1, old_sigset_t mask) |
479 | 479 | { |
480 | 480 | sigset_t blocked; |
481 | - | |
482 | - current->saved_sigmask = current->blocked; | |
483 | - | |
484 | - mask &= _BLOCKABLE; | |
485 | 481 | siginitset(&blocked, mask); |
486 | - set_current_blocked(&blocked); | |
487 | - | |
488 | - current->state = TASK_INTERRUPTIBLE; | |
489 | - schedule(); | |
490 | - | |
491 | - set_restore_sigmask(); | |
492 | - return -ERESTARTNOHAND; | |
482 | + return sigsuspend(&blocked); | |
493 | 483 | } |
494 | 484 | |
495 | 485 | asmlinkage int |
include/linux/signal.h
... | ... | @@ -252,6 +252,7 @@ |
252 | 252 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
253 | 253 | extern void set_current_blocked(const sigset_t *); |
254 | 254 | extern int show_unhandled_signals; |
255 | +extern int sigsuspend(sigset_t *); | |
255 | 256 | |
256 | 257 | extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); |
257 | 258 | extern void block_sigmask(struct k_sigaction *ka, int signr); |
kernel/compat.c
... | ... | @@ -1073,15 +1073,7 @@ |
1073 | 1073 | if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t))) |
1074 | 1074 | return -EFAULT; |
1075 | 1075 | sigset_from_compat(&newset, &newset32); |
1076 | - sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | |
1077 | - | |
1078 | - current->saved_sigmask = current->blocked; | |
1079 | - set_current_blocked(&newset); | |
1080 | - | |
1081 | - current->state = TASK_INTERRUPTIBLE; | |
1082 | - schedule(); | |
1083 | - set_restore_sigmask(); | |
1084 | - return -ERESTARTNOHAND; | |
1076 | + return sigsuspend(&newset); | |
1085 | 1077 | } |
1086 | 1078 | #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */ |
1087 | 1079 |
kernel/signal.c
... | ... | @@ -3236,6 +3236,21 @@ |
3236 | 3236 | |
3237 | 3237 | #endif |
3238 | 3238 | |
3239 | +#ifdef HAVE_SET_RESTORE_SIGMASK | |
3240 | +int sigsuspend(sigset_t *set) | |
3241 | +{ | |
3242 | + sigdelsetmask(set, sigmask(SIGKILL)|sigmask(SIGSTOP)); | |
3243 | + | |
3244 | + current->saved_sigmask = current->blocked; | |
3245 | + set_current_blocked(set); | |
3246 | + | |
3247 | + current->state = TASK_INTERRUPTIBLE; | |
3248 | + schedule(); | |
3249 | + set_restore_sigmask(); | |
3250 | + return -ERESTARTNOHAND; | |
3251 | +} | |
3252 | +#endif | |
3253 | + | |
3239 | 3254 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND |
3240 | 3255 | /** |
3241 | 3256 | * sys_rt_sigsuspend - replace the signal mask for a value with the |
... | ... | @@ -3253,15 +3268,7 @@ |
3253 | 3268 | |
3254 | 3269 | if (copy_from_user(&newset, unewset, sizeof(newset))) |
3255 | 3270 | return -EFAULT; |
3256 | - sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | |
3257 | - | |
3258 | - current->saved_sigmask = current->blocked; | |
3259 | - set_current_blocked(&newset); | |
3260 | - | |
3261 | - current->state = TASK_INTERRUPTIBLE; | |
3262 | - schedule(); | |
3263 | - set_restore_sigmask(); | |
3264 | - return -ERESTARTNOHAND; | |
3271 | + return sigsuspend(&newset); | |
3265 | 3272 | } |
3266 | 3273 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ |
3267 | 3274 |