summary refs log tree commit diff
path: root/kernel/compat.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2011-04-27 21:24:19 +0200
committerOleg Nesterov <oleg@redhat.com>2011-04-28 13:01:38 +0200
commitfe0faa005d43bc44c357631d51c273806086caa4 (patch)
tree7977c5ec7c452ed3a0036747b8d8861b742c30b3 /kernel/compat.c
parentbb7efee2ca63b08795ffb3cda96fc89d2e641b79 (diff)
downloadlinux-fe0faa005d43bc44c357631d51c273806086caa4.tar.gz
signal: sys_rt_sigtimedwait: simplify the timeout logic
No functional changes, cleanup compat_sys_rt_sigtimedwait() and
sys_rt_sigtimedwait().

Calculate the timeout before we take ->siglock, this simplifies and
lessens the code. Use timespec_valid() to check the timespec.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Matt Fleming <matt.fleming@linux.intel.com>
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 38b1d2c1cbe8..06cbb0619531 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -893,7 +893,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
 	int sig;
 	struct timespec t;
 	siginfo_t info;
-	long ret, timeout = 0;
+	long ret, timeout;
 
 	if (sigsetsize != sizeof(sigset_t))
 		return -EINVAL;
@@ -904,36 +904,30 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
 	sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP));
 	signotset(&s);
 
+	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (uts) {
 		if (get_compat_timespec (&t, uts))
 			return -EFAULT;
-		if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0
-				|| t.tv_sec < 0)
+		if (!timespec_valid(&t))
 			return -EINVAL;
+		timeout = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
 	}
 
 	spin_lock_irq(&current->sighand->siglock);
 	sig = dequeue_signal(current, &s, &info);
-	if (!sig) {
-		timeout = MAX_SCHEDULE_TIMEOUT;
-		if (uts)
-			timeout = timespec_to_jiffies(&t)
-				+(t.tv_sec || t.tv_nsec);
-		if (timeout) {
-			current->real_blocked = current->blocked;
-			sigandsets(&current->blocked, &current->blocked, &s);
-
-			recalc_sigpending();
-			spin_unlock_irq(&current->sighand->siglock);
-
-			timeout = schedule_timeout_interruptible(timeout);
-
-			spin_lock_irq(&current->sighand->siglock);
-			sig = dequeue_signal(current, &s, &info);
-			current->blocked = current->real_blocked;
-			siginitset(&current->real_blocked, 0);
-			recalc_sigpending();
-		}
+	if (!sig && timeout) {
+		current->real_blocked = current->blocked;
+		sigandsets(&current->blocked, &current->blocked, &s);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+
+		timeout = schedule_timeout_interruptible(timeout);
+
+		spin_lock_irq(&current->sighand->siglock);
+		sig = dequeue_signal(current, &s, &info);
+		current->blocked = current->real_blocked;
+		siginitset(&current->real_blocked, 0);
+		recalc_sigpending();
 	}
 	spin_unlock_irq(&current->sighand->siglock);
 
@@ -943,7 +937,7 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
 			if (copy_siginfo_to_user32(uinfo, &info))
 				ret = -EFAULT;
 		}
-	}else {
+	} else {
 		ret = timeout?-EINTR:-EAGAIN;
 	}
 	return ret;