diff mbox series

[32/33] linux-user: Split out rt_sigpending, rt_sigsuspend, sigpending, sigsuspend

Message ID 20180601073050.8054-33-richard.henderson@linaro.org
State New
Headers show
Series linux-user: Begin splitting do_syscall | expand

Commit Message

Richard Henderson June 1, 2018, 7:30 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall.c | 176 +++++++++++++++++++++++++------------------
 1 file changed, 101 insertions(+), 75 deletions(-)

-- 
2.17.0
diff mbox series

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e37a3ab643..c3bd625965 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8805,6 +8805,32 @@  IMPL(rt_sigaction)
     return ret;
 }
 
+IMPL(rt_sigpending)
+{
+    sigset_t set;
+    abi_long ret;
+
+    /* Yes, this check is >, not != like most. We follow the kernel's
+     * logic and it does it like this because it implements
+     * NR_sigpending through the same code path, and in that case
+     * the old_sigset_t is smaller in size.
+     */
+    if (arg2 > sizeof(target_sigset_t)) {
+        return -TARGET_EINVAL;
+    }
+    ret = get_errno(sigpending(&set));
+    if (!is_error(ret)) {
+        target_sigset_t *p;
+        p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        host_to_target_sigset(p, &set);
+        unlock_user(p, arg1, sizeof(target_sigset_t));
+    }
+    return ret;
+}
+
 IMPL(rt_sigprocmask)
 {
     int how = 0;
@@ -8850,6 +8876,29 @@  IMPL(rt_sigprocmask)
     return ret;
 }
 
+IMPL(rt_sigsuspend)
+{
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    TaskState *ts = cpu->opaque;
+    target_sigset_t *p;
+    abi_long ret;
+
+    if (arg2 != sizeof(target_sigset_t)) {
+        return -TARGET_EINVAL;
+    }
+    p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    target_to_host_sigset(&ts->sigsuspend_mask, p);
+    unlock_user(p, arg1, 0);
+    ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask, SIGSET_T_SIZE));
+    if (ret != -TARGET_ERESTARTSYS) {
+        ts->in_sigsuspend = 1;
+    }
+    return ret;
+}
+
 #ifdef TARGET_NR_sgetmask
 IMPL(sgetmask)
 {
@@ -8960,6 +9009,24 @@  IMPL(sigaction)
 }
 #endif
 
+#ifdef TARGET_NR_sigpending
+IMPL(sigpending)
+{
+    sigset_t set;
+    abi_long ret = get_errno(sigpending(&set));
+    if (!is_error(ret)) {
+        abi_ulong *p;
+        p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        host_to_target_old_sigset(p, &set);
+        unlock_user(p, arg1, sizeof(target_sigset_t));
+    }
+    return ret;
+}
+#endif
+
 #ifdef TARGET_NR_sigprocmask
 IMPL(sigprocmask)
 {
@@ -9032,6 +9099,32 @@  IMPL(sigprocmask)
 }
 #endif
 
+#ifdef TARGET_NR_sigsuspend
+IMPL(sigsuspend)
+{
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    TaskState *ts = cpu->opaque;
+    abi_long ret;
+
+# ifdef TARGET_ALPHA
+    abi_ulong mask = arg1;
+    target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
+# else
+    abi_ulong *p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+    if (!p) {
+        return -TARGET_EFAULT;
+    }
+    target_to_host_old_sigset(&ts->sigsuspend_mask, p);
+    unlock_user(p, arg1, 0);
+# endif
+    ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask, SIGSET_T_SIZE));
+    if (ret != -TARGET_ERESTARTSYS) {
+        ts->in_sigsuspend = 1;
+    }
+    return ret;
+}
+#endif
+
 #ifdef TARGET_NR_ssetmask
 IMPL(ssetmask)
 {
@@ -9300,81 +9393,6 @@  IMPL(everything_else)
     char *fn;
 
     switch(num) {
-#ifdef TARGET_NR_sigpending
-    case TARGET_NR_sigpending:
-        {
-            sigset_t set;
-            ret = get_errno(sigpending(&set));
-            if (!is_error(ret)) {
-                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
-                    return -TARGET_EFAULT;
-                host_to_target_old_sigset(p, &set);
-                unlock_user(p, arg1, sizeof(target_sigset_t));
-            }
-        }
-        return ret;
-#endif
-    case TARGET_NR_rt_sigpending:
-        {
-            sigset_t set;
-
-            /* Yes, this check is >, not != like most. We follow the kernel's
-             * logic and it does it like this because it implements
-             * NR_sigpending through the same code path, and in that case
-             * the old_sigset_t is smaller in size.
-             */
-            if (arg2 > sizeof(target_sigset_t)) {
-                return -TARGET_EINVAL;
-            }
-
-            ret = get_errno(sigpending(&set));
-            if (!is_error(ret)) {
-                if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
-                    return -TARGET_EFAULT;
-                host_to_target_sigset(p, &set);
-                unlock_user(p, arg1, sizeof(target_sigset_t));
-            }
-        }
-        return ret;
-#ifdef TARGET_NR_sigsuspend
-    case TARGET_NR_sigsuspend:
-        {
-            TaskState *ts = cpu->opaque;
-#if defined(TARGET_ALPHA)
-            abi_ulong mask = arg1;
-            target_to_host_old_sigset(&ts->sigsuspend_mask, &mask);
-#else
-            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
-                return -TARGET_EFAULT;
-            target_to_host_old_sigset(&ts->sigsuspend_mask, p);
-            unlock_user(p, arg1, 0);
-#endif
-            ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
-                                               SIGSET_T_SIZE));
-            if (ret != -TARGET_ERESTARTSYS) {
-                ts->in_sigsuspend = 1;
-            }
-        }
-        return ret;
-#endif
-    case TARGET_NR_rt_sigsuspend:
-        {
-            TaskState *ts = cpu->opaque;
-
-            if (arg2 != sizeof(target_sigset_t)) {
-                return -TARGET_EINVAL;
-            }
-            if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
-                return -TARGET_EFAULT;
-            target_to_host_sigset(&ts->sigsuspend_mask, p);
-            unlock_user(p, arg1, 0);
-            ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
-                                               SIGSET_T_SIZE));
-            if (ret != -TARGET_ERESTARTSYS) {
-                ts->in_sigsuspend = 1;
-            }
-        }
-        return ret;
     case TARGET_NR_rt_sigtimedwait:
         {
             sigset_t set;
@@ -13112,7 +13130,9 @@  static impl_fn * const syscall_table[] = {
     [TARGET_NR_rmdir] = impl_rmdir,
 #endif
     [TARGET_NR_rt_sigaction] = impl_rt_sigaction,
+    [TARGET_NR_rt_sigpending] = impl_rt_sigpending,
     [TARGET_NR_rt_sigprocmask] = impl_rt_sigprocmask,
+    [TARGET_NR_rt_sigsuspend] = impl_rt_sigsuspend,
 #ifdef TARGET_NR_sgetmask
     [TARGET_NR_sgetmask] = impl_sgetmask,
 #endif
@@ -13121,9 +13141,15 @@  static impl_fn * const syscall_table[] = {
 #ifdef TARGET_NR_sigaction
     [TARGET_NR_sigaction] = impl_sigaction,
 #endif
+#ifdef TARGET_NR_sigpending
+    [TARGET_NR_sigpending] = impl_sigpending,
+#endif
 #ifdef TARGET_NR_sigprocmask
     [TARGET_NR_sigprocmask] = impl_sigprocmask,
 #endif
+#ifdef TARGET_NR_sigsuspend
+    [TARGET_NR_sigsuspend] = impl_sigsuspend,
+#endif
 #ifdef TARGET_NR_ssetmask
     [TARGET_NR_ssetmask] = impl_ssetmask,
 #endif