diff mbox series

[v2,030/108] linux-user: Split out rt_sigprocmask, sgetmask, sigprocmask, ssetmask

Message ID 20180610030220.3777-31-richard.henderson@linaro.org
State New
Headers show
Series linux-user: Split do_syscall | expand

Commit Message

Richard Henderson June 10, 2018, 3:01 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 linux-user/syscall.c | 294 +++++++++++++++++++++++--------------------
 1 file changed, 158 insertions(+), 136 deletions(-)

-- 
2.17.1
diff mbox series

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdb4dd5bb4..cc818ea65e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8697,6 +8697,65 @@  IMPL(rt_sigaction)
     return ret;
 }
 
+IMPL(rt_sigprocmask)
+{
+    int how = 0;
+    sigset_t set, oldset, *set_ptr = NULL;
+    abi_long ret;
+    target_sigset_t *p;
+
+    if (arg4 != sizeof(target_sigset_t)) {
+        return -TARGET_EINVAL;
+    }
+
+    if (arg2) {
+        switch (arg1) {
+        case TARGET_SIG_BLOCK:
+            how = SIG_BLOCK;
+            break;
+        case TARGET_SIG_UNBLOCK:
+            how = SIG_UNBLOCK;
+            break;
+        case TARGET_SIG_SETMASK:
+            how = SIG_SETMASK;
+            break;
+        default:
+            return -TARGET_EINVAL;
+        }
+        p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        target_to_host_sigset(&set, p);
+        unlock_user(p, arg2, 0);
+        set_ptr = &set;
+    }
+    ret = do_sigprocmask(how, set_ptr, &oldset);
+    if (!is_error(ret) && arg3) {
+        p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        host_to_target_sigset(p, &oldset);
+        unlock_user(p, arg3, sizeof(target_sigset_t));
+    }
+    return ret;
+}
+
+#ifdef TARGET_NR_sgetmask
+IMPL(sgetmask)
+{
+    sigset_t cur_set;
+    abi_ulong target_set;
+    abi_long ret = do_sigprocmask(0, NULL, &cur_set);
+    if (!ret) {
+        host_to_target_old_sigset(&target_set, &cur_set);
+        ret = target_set;
+    }
+    return ret;
+}
+#endif
+
 IMPL(setpgid)
 {
     return get_errno(setpgid(arg1, arg2));
@@ -8793,6 +8852,95 @@  IMPL(sigaction)
 }
 #endif
 
+#ifdef TARGET_NR_sigprocmask
+IMPL(sigprocmask)
+{
+    abi_long ret;
+# ifdef TARGET_ALPHA
+    sigset_t set, oldset;
+    abi_ulong mask;
+    int how;
+
+    switch (arg1) {
+    case TARGET_SIG_BLOCK:
+        how = SIG_BLOCK;
+        break;
+    case TARGET_SIG_UNBLOCK:
+        how = SIG_UNBLOCK;
+        break;
+    case TARGET_SIG_SETMASK:
+        how = SIG_SETMASK;
+        break;
+    default:
+        return -TARGET_EINVAL;
+    }
+    mask = arg2;
+    target_to_host_old_sigset(&set, &mask);
+
+    ret = do_sigprocmask(how, &set, &oldset);
+    if (!is_error(ret)) {
+        host_to_target_old_sigset(&mask, &oldset);
+        ret = mask;
+        ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
+    }
+# else
+    sigset_t set, oldset, *set_ptr = NULL;
+    int how = 0;
+    abi_ulong *p;
+
+    if (arg2) {
+        switch (arg1) {
+        case TARGET_SIG_BLOCK:
+            how = SIG_BLOCK;
+            break;
+        case TARGET_SIG_UNBLOCK:
+            how = SIG_UNBLOCK;
+            break;
+        case TARGET_SIG_SETMASK:
+            how = SIG_SETMASK;
+            break;
+        default:
+            return -TARGET_EINVAL;
+        }
+        p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        target_to_host_old_sigset(&set, p);
+        unlock_user(p, arg2, 0);
+        set_ptr = &set;
+    }
+    ret = do_sigprocmask(how, set_ptr, &oldset);
+    if (!is_error(ret) && arg3) {
+        p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0);
+        if (!p) {
+            return -TARGET_EFAULT;
+        }
+        host_to_target_old_sigset(p, &oldset);
+        unlock_user(p, arg3, sizeof(target_sigset_t));
+    }
+# endif
+    return ret;
+}
+#endif
+
+#ifdef TARGET_NR_ssetmask
+IMPL(ssetmask)
+{
+    sigset_t set, oset;
+    abi_ulong target_set = arg1;
+    abi_long ret;
+
+    target_to_host_old_sigset(&set, &target_set);
+    ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
+    if (!ret) {
+        host_to_target_old_sigset(&target_set, &oset);
+        ret = target_set;
+    }
+    return ret;
+}
+#endif
+
 #ifdef TARGET_NR_stime
 IMPL(stime)
 {
@@ -9034,142 +9182,6 @@  static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1,
     void *p;
 
     switch(num) {
-#ifdef TARGET_NR_sgetmask /* not on alpha */
-    case TARGET_NR_sgetmask:
-        {
-            sigset_t cur_set;
-            abi_ulong target_set;
-            ret = do_sigprocmask(0, NULL, &cur_set);
-            if (!ret) {
-                host_to_target_old_sigset(&target_set, &cur_set);
-                ret = target_set;
-            }
-        }
-        return ret;
-#endif
-#ifdef TARGET_NR_ssetmask /* not on alpha */
-    case TARGET_NR_ssetmask:
-        {
-            sigset_t set, oset;
-            abi_ulong target_set = arg1;
-            target_to_host_old_sigset(&set, &target_set);
-            ret = do_sigprocmask(SIG_SETMASK, &set, &oset);
-            if (!ret) {
-                host_to_target_old_sigset(&target_set, &oset);
-                ret = target_set;
-            }
-        }
-        return ret;
-#endif
-#ifdef TARGET_NR_sigprocmask
-    case TARGET_NR_sigprocmask:
-        {
-#if defined(TARGET_ALPHA)
-            sigset_t set, oldset;
-            abi_ulong mask;
-            int how;
-
-            switch (arg1) {
-            case TARGET_SIG_BLOCK:
-                how = SIG_BLOCK;
-                break;
-            case TARGET_SIG_UNBLOCK:
-                how = SIG_UNBLOCK;
-                break;
-            case TARGET_SIG_SETMASK:
-                how = SIG_SETMASK;
-                break;
-            default:
-                return -TARGET_EINVAL;
-            }
-            mask = arg2;
-            target_to_host_old_sigset(&set, &mask);
-
-            ret = do_sigprocmask(how, &set, &oldset);
-            if (!is_error(ret)) {
-                host_to_target_old_sigset(&mask, &oldset);
-                ret = mask;
-                ((CPUAlphaState *)cpu_env)->ir[IR_V0] = 0; /* force no error */
-            }
-#else
-            sigset_t set, oldset, *set_ptr;
-            int how;
-
-            if (arg2) {
-                switch (arg1) {
-                case TARGET_SIG_BLOCK:
-                    how = SIG_BLOCK;
-                    break;
-                case TARGET_SIG_UNBLOCK:
-                    how = SIG_UNBLOCK;
-                    break;
-                case TARGET_SIG_SETMASK:
-                    how = SIG_SETMASK;
-                    break;
-                default:
-                    return -TARGET_EINVAL;
-                }
-                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
-                    return -TARGET_EFAULT;
-                target_to_host_old_sigset(&set, p);
-                unlock_user(p, arg2, 0);
-                set_ptr = &set;
-            } else {
-                how = 0;
-                set_ptr = NULL;
-            }
-            ret = do_sigprocmask(how, set_ptr, &oldset);
-            if (!is_error(ret) && arg3) {
-                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
-                    return -TARGET_EFAULT;
-                host_to_target_old_sigset(p, &oldset);
-                unlock_user(p, arg3, sizeof(target_sigset_t));
-            }
-#endif
-        }
-        return ret;
-#endif
-    case TARGET_NR_rt_sigprocmask:
-        {
-            int how = arg1;
-            sigset_t set, oldset, *set_ptr;
-
-            if (arg4 != sizeof(target_sigset_t)) {
-                return -TARGET_EINVAL;
-            }
-
-            if (arg2) {
-                switch(how) {
-                case TARGET_SIG_BLOCK:
-                    how = SIG_BLOCK;
-                    break;
-                case TARGET_SIG_UNBLOCK:
-                    how = SIG_UNBLOCK;
-                    break;
-                case TARGET_SIG_SETMASK:
-                    how = SIG_SETMASK;
-                    break;
-                default:
-                    return -TARGET_EINVAL;
-                }
-                if (!(p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1)))
-                    return -TARGET_EFAULT;
-                target_to_host_sigset(&set, p);
-                unlock_user(p, arg2, 0);
-                set_ptr = &set;
-            } else {
-                how = 0;
-                set_ptr = NULL;
-            }
-            ret = do_sigprocmask(how, set_ptr, &oldset);
-            if (!is_error(ret) && arg3) {
-                if (!(p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0)))
-                    return -TARGET_EFAULT;
-                host_to_target_sigset(p, &oldset);
-                unlock_user(p, arg3, sizeof(target_sigset_t));
-            }
-        }
-        return ret;
 #ifdef TARGET_NR_sigpending
     case TARGET_NR_sigpending:
         {
@@ -12743,11 +12755,21 @@  static impl_fn *syscall_table(unsigned num)
         SYSCALL(rmdir);
 #endif
         SYSCALL(rt_sigaction);
+        SYSCALL(rt_sigprocmask);
+#ifdef TARGET_NR_sgetmask
+        SYSCALL(sgetmask);
+#endif
         SYSCALL(setpgid);
         SYSCALL(setsid);
 #ifdef TARGET_NR_sigaction
         SYSCALL(sigaction);
 #endif
+#ifdef TARGET_NR_sigprocmask
+        SYSCALL(sigprocmask);
+#endif
+#ifdef TARGET_NR_ssetmask
+        SYSCALL(ssetmask);
+#endif
 #ifdef TARGET_NR_stime
         SYSCALL(stime);
 #endif