diff mbox series

[v7,15/74] linux-user: Split out exit

Message ID 20190519203726.20729-16-richard.henderson@linaro.org (mailing list archive)
State New, archived
Headers show
Series linux-user: Split do_syscall | expand

Commit Message

Richard Henderson May 19, 2019, 8:36 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/syscall-defs.h     |  1 +
 linux-user/syscall-proc.inc.c | 61 +++++++++++++++++++++++++++++++++++
 linux-user/syscall.c          | 38 +---------------------
 3 files changed, 63 insertions(+), 37 deletions(-)
 create mode 100644 linux-user/syscall-proc.inc.c
diff mbox series

Patch

diff --git a/linux-user/syscall-defs.h b/linux-user/syscall-defs.h
index 88f433e998..88aa1a6bfd 100644
--- a/linux-user/syscall-defs.h
+++ b/linux-user/syscall-defs.h
@@ -17,6 +17,7 @@ 
  */
 
 SYSCALL_DEF(close, ARG_DEC);
+SYSCALL_DEF(exit, ARG_DEC);
 #ifdef TARGET_NR_ipc
 SYSCALL_DEF_ARGS(ipc, ARG_HEX, ARG_DEC, ARG_DEC, ARG_HEX, ARG_PTR, ARG_HEX);
 #endif
diff --git a/linux-user/syscall-proc.inc.c b/linux-user/syscall-proc.inc.c
new file mode 100644
index 0000000000..96ad363c1a
--- /dev/null
+++ b/linux-user/syscall-proc.inc.c
@@ -0,0 +1,61 @@ 
+/*
+ *  Linux process related syscalls
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+SYSCALL_IMPL(exit)
+{
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+    int status = arg1;
+
+    /*
+     * In old applications this may be used to implement _exit(2).
+     * However in threaded applictions it is used for thread termination,
+     * and _exit_group is used for application termination.
+     * Do thread termination if we have more then one thread.
+     */
+    if (block_signals()) {
+        return -TARGET_ERESTARTSYS;
+    }
+
+    cpu_list_lock();
+
+    if (CPU_NEXT(first_cpu)) {
+        TaskState *ts;
+
+        /* Remove the CPU from the list.  */
+        QTAILQ_REMOVE_RCU(&cpus, cpu, node);
+
+        cpu_list_unlock();
+
+        ts = cpu->opaque;
+        if (ts->child_tidptr) {
+            put_user_u32(0, ts->child_tidptr);
+            sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
+                      NULL, NULL, 0);
+        }
+        thread_cpu = NULL;
+        object_unref(OBJECT(cpu));
+        g_free(ts);
+        rcu_unregister_thread();
+        pthread_exit(NULL);
+    }
+
+    cpu_list_unlock();
+    preexit_cleanup(cpu_env, status);
+    _exit(status);
+}
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 876426dd9c..c72d24aa76 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5681,43 +5681,6 @@  static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
     void *p;
 
     switch(num) {
-    case TARGET_NR_exit:
-        /* In old applications this may be used to implement _exit(2).
-           However in threaded applictions it is used for thread termination,
-           and _exit_group is used for application termination.
-           Do thread termination if we have more then one thread.  */
-
-        if (block_signals()) {
-            return -TARGET_ERESTARTSYS;
-        }
-
-        cpu_list_lock();
-
-        if (CPU_NEXT(first_cpu)) {
-            TaskState *ts;
-
-            /* Remove the CPU from the list.  */
-            QTAILQ_REMOVE_RCU(&cpus, cpu, node);
-
-            cpu_list_unlock();
-
-            ts = cpu->opaque;
-            if (ts->child_tidptr) {
-                put_user_u32(0, ts->child_tidptr);
-                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
-                          NULL, NULL, 0);
-            }
-            thread_cpu = NULL;
-            object_unref(OBJECT(cpu));
-            g_free(ts);
-            rcu_unregister_thread();
-            pthread_exit(NULL);
-        }
-
-        cpu_list_unlock();
-        preexit_cleanup(cpu_env, arg1);
-        _exit(arg1);
-        return 0; /* avoid warning */
     case TARGET_NR_brk:
         return do_brk(arg1);
 #ifdef TARGET_NR_fork
@@ -9975,6 +9938,7 @@  static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
 #include "syscall-file.inc.c"
 #include "syscall-ipc.inc.c"
 #include "syscall-mem.inc.c"
+#include "syscall-proc.inc.c"
 
 #undef SYSCALL_IMPL
 #undef SYSCALL_ARGS