diff options
Diffstat (limited to 'kernel/compat.c')
| -rw-r--r-- | kernel/compat.c | 45 | 
1 files changed, 6 insertions, 39 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 38b1d2c1cbe..9214dcd087b 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -890,10 +890,9 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,  {  	compat_sigset_t s32;  	sigset_t s; -	int sig;  	struct timespec t;  	siginfo_t info; -	long ret, timeout = 0; +	long ret;  	if (sigsetsize != sizeof(sigset_t))  		return -EINVAL; @@ -901,51 +900,19 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,  	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))  		return -EFAULT;  	sigset_from_compat(&s, &s32); -	sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); -	signotset(&s);  	if (uts) { -		if (get_compat_timespec (&t, uts)) +		if (get_compat_timespec(&t, uts))  			return -EFAULT; -		if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 -				|| t.tv_sec < 0) -			return -EINVAL;  	} -	spin_lock_irq(¤t->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(¤t->blocked, ¤t->blocked, &s); - -			recalc_sigpending(); -			spin_unlock_irq(¤t->sighand->siglock); +	ret = do_sigtimedwait(&s, &info, uts ? &t : NULL); -			timeout = schedule_timeout_interruptible(timeout); - -			spin_lock_irq(¤t->sighand->siglock); -			sig = dequeue_signal(current, &s, &info); -			current->blocked = current->real_blocked; -			siginitset(¤t->real_blocked, 0); -			recalc_sigpending(); -		} +	if (ret > 0 && uinfo) { +		if (copy_siginfo_to_user32(uinfo, &info)) +			ret = -EFAULT;  	} -	spin_unlock_irq(¤t->sighand->siglock); -	if (sig) { -		ret = sig; -		if (uinfo) { -			if (copy_siginfo_to_user32(uinfo, &info)) -				ret = -EFAULT; -		} -	}else { -		ret = timeout?-EINTR:-EAGAIN; -	}  	return ret;  }  |