diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 47 |
1 files changed, 7 insertions, 40 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 38b1d2c1cbe8..9214dcd087b7 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -890,10 +890,9 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, | |||
890 | { | 890 | { |
891 | compat_sigset_t s32; | 891 | compat_sigset_t s32; |
892 | sigset_t s; | 892 | sigset_t s; |
893 | int sig; | ||
894 | struct timespec t; | 893 | struct timespec t; |
895 | siginfo_t info; | 894 | siginfo_t info; |
896 | long ret, timeout = 0; | 895 | long ret; |
897 | 896 | ||
898 | if (sigsetsize != sizeof(sigset_t)) | 897 | if (sigsetsize != sizeof(sigset_t)) |
899 | return -EINVAL; | 898 | return -EINVAL; |
@@ -901,51 +900,19 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, | |||
901 | if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t))) | 900 | if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t))) |
902 | return -EFAULT; | 901 | return -EFAULT; |
903 | sigset_from_compat(&s, &s32); | 902 | sigset_from_compat(&s, &s32); |
904 | sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
905 | signotset(&s); | ||
906 | 903 | ||
907 | if (uts) { | 904 | if (uts) { |
908 | if (get_compat_timespec (&t, uts)) | 905 | if (get_compat_timespec(&t, uts)) |
909 | return -EFAULT; | 906 | return -EFAULT; |
910 | if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 | ||
911 | || t.tv_sec < 0) | ||
912 | return -EINVAL; | ||
913 | } | 907 | } |
914 | 908 | ||
915 | spin_lock_irq(¤t->sighand->siglock); | 909 | ret = do_sigtimedwait(&s, &info, uts ? &t : NULL); |
916 | sig = dequeue_signal(current, &s, &info); | ||
917 | if (!sig) { | ||
918 | timeout = MAX_SCHEDULE_TIMEOUT; | ||
919 | if (uts) | ||
920 | timeout = timespec_to_jiffies(&t) | ||
921 | +(t.tv_sec || t.tv_nsec); | ||
922 | if (timeout) { | ||
923 | current->real_blocked = current->blocked; | ||
924 | sigandsets(¤t->blocked, ¤t->blocked, &s); | ||
925 | |||
926 | recalc_sigpending(); | ||
927 | spin_unlock_irq(¤t->sighand->siglock); | ||
928 | |||
929 | timeout = schedule_timeout_interruptible(timeout); | ||
930 | |||
931 | spin_lock_irq(¤t->sighand->siglock); | ||
932 | sig = dequeue_signal(current, &s, &info); | ||
933 | current->blocked = current->real_blocked; | ||
934 | siginitset(¤t->real_blocked, 0); | ||
935 | recalc_sigpending(); | ||
936 | } | ||
937 | } | ||
938 | spin_unlock_irq(¤t->sighand->siglock); | ||
939 | 910 | ||
940 | if (sig) { | 911 | if (ret > 0 && uinfo) { |
941 | ret = sig; | 912 | if (copy_siginfo_to_user32(uinfo, &info)) |
942 | if (uinfo) { | 913 | ret = -EFAULT; |
943 | if (copy_siginfo_to_user32(uinfo, &info)) | ||
944 | ret = -EFAULT; | ||
945 | } | ||
946 | }else { | ||
947 | ret = timeout?-EINTR:-EAGAIN; | ||
948 | } | 914 | } |
915 | |||
949 | return ret; | 916 | return ret; |
950 | 917 | ||
951 | } | 918 | } |