diff options
Diffstat (limited to 'kernel/compat.c')
-rw-r--r-- | kernel/compat.c | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index 38b1d2c1cbe8..fc9eb093acd5 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -293,6 +293,8 @@ asmlinkage long compat_sys_times(struct compat_tms __user *tbuf) | |||
293 | return compat_jiffies_to_clock_t(jiffies); | 293 | return compat_jiffies_to_clock_t(jiffies); |
294 | } | 294 | } |
295 | 295 | ||
296 | #ifdef __ARCH_WANT_SYS_SIGPENDING | ||
297 | |||
296 | /* | 298 | /* |
297 | * Assumption: old_sigset_t and compat_old_sigset_t are both | 299 | * Assumption: old_sigset_t and compat_old_sigset_t are both |
298 | * types that can be passed to put_user()/get_user(). | 300 | * types that can be passed to put_user()/get_user(). |
@@ -312,6 +314,10 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set) | |||
312 | return ret; | 314 | return ret; |
313 | } | 315 | } |
314 | 316 | ||
317 | #endif | ||
318 | |||
319 | #ifdef __ARCH_WANT_SYS_SIGPROCMASK | ||
320 | |||
315 | asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, | 321 | asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, |
316 | compat_old_sigset_t __user *oset) | 322 | compat_old_sigset_t __user *oset) |
317 | { | 323 | { |
@@ -333,6 +339,8 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, | |||
333 | return ret; | 339 | return ret; |
334 | } | 340 | } |
335 | 341 | ||
342 | #endif | ||
343 | |||
336 | asmlinkage long compat_sys_setrlimit(unsigned int resource, | 344 | asmlinkage long compat_sys_setrlimit(unsigned int resource, |
337 | struct compat_rlimit __user *rlim) | 345 | struct compat_rlimit __user *rlim) |
338 | { | 346 | { |
@@ -890,10 +898,9 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, | |||
890 | { | 898 | { |
891 | compat_sigset_t s32; | 899 | compat_sigset_t s32; |
892 | sigset_t s; | 900 | sigset_t s; |
893 | int sig; | ||
894 | struct timespec t; | 901 | struct timespec t; |
895 | siginfo_t info; | 902 | siginfo_t info; |
896 | long ret, timeout = 0; | 903 | long ret; |
897 | 904 | ||
898 | if (sigsetsize != sizeof(sigset_t)) | 905 | if (sigsetsize != sizeof(sigset_t)) |
899 | return -EINVAL; | 906 | return -EINVAL; |
@@ -901,51 +908,19 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese, | |||
901 | if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t))) | 908 | if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t))) |
902 | return -EFAULT; | 909 | return -EFAULT; |
903 | sigset_from_compat(&s, &s32); | 910 | sigset_from_compat(&s, &s32); |
904 | sigdelsetmask(&s,sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
905 | signotset(&s); | ||
906 | 911 | ||
907 | if (uts) { | 912 | if (uts) { |
908 | if (get_compat_timespec (&t, uts)) | 913 | if (get_compat_timespec(&t, uts)) |
909 | return -EFAULT; | 914 | return -EFAULT; |
910 | if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 | ||
911 | || t.tv_sec < 0) | ||
912 | return -EINVAL; | ||
913 | } | 915 | } |
914 | 916 | ||
915 | spin_lock_irq(¤t->sighand->siglock); | 917 | 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 | 918 | ||
940 | if (sig) { | 919 | if (ret > 0 && uinfo) { |
941 | ret = sig; | 920 | if (copy_siginfo_to_user32(uinfo, &info)) |
942 | if (uinfo) { | 921 | ret = -EFAULT; |
943 | if (copy_siginfo_to_user32(uinfo, &info)) | ||
944 | ret = -EFAULT; | ||
945 | } | ||
946 | }else { | ||
947 | ret = timeout?-EINTR:-EAGAIN; | ||
948 | } | 922 | } |
923 | |||
949 | return ret; | 924 | return ret; |
950 | 925 | ||
951 | } | 926 | } |