diff mbox series

[for-3.2,13/13] slirp: simplify fork_exec()

Message ID 20181110134548.14741-14-marcandre.lureau@redhat.com
State New
Headers show
Series slirp: cleanups | expand

Commit Message

Marc-André Lureau Nov. 10, 2018, 1:45 p.m. UTC
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 <marcandre.lureau@redhat.com>
---
 slirp/misc.c | 77 +++++++++++++++++++++++++---------------------------
 1 file changed, 37 insertions(+), 40 deletions(-)

Comments

Samuel Thibault Nov. 10, 2018, 1:54 p.m. UTC | #1
Marc-André Lureau, le sam. 10 nov. 2018 17:45:48 +0400, a ecrit:
> Use g_spawn_async_with_fds() to setup the child.
> 
> GSpawn handles reaping the child, and closing parent file descriptors.

Similarly :)

Samuel
diff mbox series

Patch

diff --git a/slirp/misc.c b/slirp/misc.c
index dedc9bf6c3..f99e3a8fcc 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -127,56 +127,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);
-		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);
+    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);
+
+    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