qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 44/65] slirp: simplify fork_exec()


From: Samuel Thibault
Subject: [Qemu-devel] [PULL 44/65] slirp: simplify fork_exec()
Date: Mon, 14 Jan 2019 23:52:45 +0100

From: Marc-André Lureau <address@hidden>

Use g_spawn_async_with_fds() to setup the child.

GSpawn handles reaping the child, and closing parent file descriptors.

Signed-off-by: Marc-André Lureau <address@hidden>
Signed-off-by: Samuel Thibault <address@hidden>
---
 slirp/misc.c | 75 +++++++++++++++++++++++++---------------------------
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index ee3492a2ae..753b3da25b 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -129,56 +129,53 @@ err:
     return -1;
 }
 
+static void
+fork_exec_child_setup(gpointer data)
+{
+    setsid();
+}
+
 int
 fork_exec(struct socket *so, const char *ex)
 {
-       char **argv;
-       int opt, c, sp[2];
-       pid_t pid;
+    GError *err = NULL;
+    char **argv;
+    int opt, sp[2];
 
-       DEBUG_CALL("fork_exec");
-       DEBUG_ARG("so = %p", so);
-       DEBUG_ARG("ex = %p", ex);
+    DEBUG_CALL("fork_exec");
+    DEBUG_ARG("so = %p", so);
+    DEBUG_ARG("ex = %p", ex);
 
     if (slirp_socketpair_with_oob(sp) < 0) {
         return 0;
     }
 
-       pid = fork();
-       switch(pid) {
-        case -1:
-               error_report("Error: fork failed: %s", strerror(errno));
-               closesocket(sp[0]);
-               closesocket(sp[1]);
-               return 0;
-
-        case 0:
-               setsid();
-               dup2(sp[1], 0);
-               dup2(sp[1], 1);
-               dup2(sp[1], 2);
-               for (c = getdtablesize() - 1; c >= 3; c--)
-                  close(c);
+    argv = g_strsplit(ex, " ", -1);
+    g_spawn_async_with_fds(NULL /* cwd */,
+                           argv,
+                           NULL /* env */,
+                           G_SPAWN_SEARCH_PATH,
+                           fork_exec_child_setup, NULL /* data */,
+                           NULL /* child_pid */,
+                           sp[1], sp[1], sp[1],
+                           &err);
+    g_strfreev(argv);
 
-                argv = g_strsplit(ex, " ", -1);
-               execvp(argv[0], (char **)argv);
-
-               /* Ooops, failed, let's tell the user why */
-        fprintf(stderr, "Error: execvp of %s failed: %s\n",
-                argv[0], strerror(errno));
-               close(0); close(1); close(2); /* XXX */
-               exit(1);
+    if (err) {
+        error_report("%s", err->message);
+        g_error_free(err);
+        closesocket(sp[0]);
+        closesocket(sp[1]);
+        return 0;
+    }
 
-        default:
-               so->s = sp[0];
-               closesocket(sp[1]);
-               qemu_add_child_watch(pid);
-               socket_set_fast_reuse(so->s);
-               opt = 1;
-               qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, 
sizeof(int));
-               qemu_set_nonblock(so->s);
-               return 1;
-       }
+    so->s = sp[0];
+    closesocket(sp[1]);
+    socket_set_fast_reuse(so->s);
+    opt = 1;
+    qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+    qemu_set_nonblock(so->s);
+    return 1;
 }
 #endif
 
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]