|
@@ -2768,7 +2768,7 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from)
|
|
|
* @info: if non-null, the signal's siginfo is returned here
|
|
|
* @ts: upper bound on process time suspension
|
|
|
*/
|
|
|
-int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
|
|
|
+static int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
|
|
|
const struct timespec *ts)
|
|
|
{
|
|
|
ktime_t *to = NULL, timeout = KTIME_MAX;
|
|
@@ -2857,6 +2857,40 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
|
|
|
+ struct compat_siginfo __user *, uinfo,
|
|
|
+ struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
|
|
|
+{
|
|
|
+ compat_sigset_t s32;
|
|
|
+ sigset_t s;
|
|
|
+ struct timespec t;
|
|
|
+ siginfo_t info;
|
|
|
+ long ret;
|
|
|
+
|
|
|
+ if (sigsetsize != sizeof(sigset_t))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
|
|
|
+ return -EFAULT;
|
|
|
+ sigset_from_compat(&s, &s32);
|
|
|
+
|
|
|
+ if (uts) {
|
|
|
+ if (compat_get_timespec(&t, uts))
|
|
|
+ return -EFAULT;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
|
|
|
+
|
|
|
+ if (ret > 0 && uinfo) {
|
|
|
+ if (copy_siginfo_to_user32(uinfo, &info))
|
|
|
+ ret = -EFAULT;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/**
|
|
|
* sys_kill - send a signal to a process
|
|
|
* @pid: the PID of the process
|