summary refs log tree commit diff stats
path: root/slirp/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'slirp/misc.c')
-rw-r--r--slirp/misc.c126
1 files changed, 97 insertions, 29 deletions
diff --git a/slirp/misc.c b/slirp/misc.c
index eae9596a55..3f4cd852f8 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -5,11 +5,7 @@
  * terms and conditions of the copyright.
  */
 
-#include "qemu/osdep.h"
 #include "slirp.h"
-#include "libslirp.h"
-#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
 
 inline void
 insque(void *a, void *b)
@@ -32,24 +28,33 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
-int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+             SlirpWriteCb write_cb, void *opaque,
              struct in_addr addr, int port)
 {
-	struct gfwd_list *tmp_ptr;
-
-	tmp_ptr = *ex_ptr;
-	*ex_ptr = g_new0(struct gfwd_list, 1);
-	(*ex_ptr)->ex_fport = port;
-	(*ex_ptr)->ex_addr = addr;
-	if (chardev) {
-		(*ex_ptr)->ex_chardev = chardev;
-	} else {
-		(*ex_ptr)->ex_exec = g_strdup(cmdline);
-	}
-	(*ex_ptr)->ex_next = tmp_ptr;
-	return 0;
+    struct gfwd_list *f = g_new0(struct gfwd_list, 1);
+
+    f->write_cb = write_cb;
+    f->opaque = opaque;
+    f->ex_fport = port;
+    f->ex_addr = addr;
+    f->ex_next = *ex_ptr;
+    *ex_ptr = f;
+
+    return f;
 }
 
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+         struct in_addr addr, int port)
+{
+    struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
+
+    f->ex_exec = g_strdup(cmdline);
+
+    return f;
+}
 
 static int
 slirp_socketpair_with_oob(int sv[2])
@@ -63,14 +68,14 @@ slirp_socketpair_with_oob(int sv[2])
     int ret, s;
 
     sv[1] = -1;
-    s = qemu_socket(AF_INET, SOCK_STREAM, 0);
+    s = slirp_socket(AF_INET, SOCK_STREAM, 0);
     if (s < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
         listen(s, 1) < 0 ||
         getsockname(s, (struct sockaddr *)&addr, &addrlen) < 0) {
         goto err;
     }
 
-    sv[1] = qemu_socket(AF_INET, SOCK_STREAM, 0);
+    sv[1] = slirp_socket(AF_INET, SOCK_STREAM, 0);
     if (sv[1] < 0) {
         goto err;
     }
@@ -93,16 +98,16 @@ slirp_socketpair_with_oob(int sv[2])
         goto err;
     }
 
-    closesocket(s);
+    slirp_closesocket(s);
     return 0;
 
 err:
     g_critical("slirp_socketpair(): %s", strerror(errno));
     if (s >= 0) {
-        closesocket(s);
+        slirp_closesocket(s);
     }
     if (sv[1] >= 0) {
-        closesocket(sv[1]);
+        slirp_closesocket(sv[1]);
     }
     return -1;
 }
@@ -115,6 +120,68 @@ fork_exec_child_setup(gpointer data)
 #endif
 }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+#if !GLIB_CHECK_VERSION(2, 58, 0)
+typedef struct SlirpGSpawnFds {
+    GSpawnChildSetupFunc child_setup;
+    gpointer user_data;
+    gint stdin_fd;
+    gint stdout_fd;
+    gint stderr_fd;
+} SlirpGSpawnFds;
+
+static inline void
+slirp_gspawn_fds_setup(gpointer user_data)
+{
+    SlirpGSpawnFds *q = (SlirpGSpawnFds *)user_data;
+
+    dup2(q->stdin_fd, 0);
+    dup2(q->stdout_fd, 1);
+    dup2(q->stderr_fd, 2);
+    q->child_setup(q->user_data);
+}
+#endif
+
+static inline gboolean
+g_spawn_async_with_fds_slirp(const gchar *working_directory,
+                            gchar **argv,
+                            gchar **envp,
+                            GSpawnFlags flags,
+                            GSpawnChildSetupFunc child_setup,
+                            gpointer user_data,
+                            GPid *child_pid,
+                            gint stdin_fd,
+                            gint stdout_fd,
+                            gint stderr_fd,
+                            GError **error)
+{
+#if GLIB_CHECK_VERSION(2, 58, 0)
+    return g_spawn_async_with_fds(working_directory, argv, envp, flags,
+                                  child_setup, user_data,
+                                  child_pid, stdin_fd, stdout_fd, stderr_fd,
+                                  error);
+#else
+    SlirpGSpawnFds setup = {
+        .child_setup = child_setup,
+        .user_data = user_data,
+        .stdin_fd = stdin_fd,
+        .stdout_fd = stdout_fd,
+        .stderr_fd = stderr_fd,
+    };
+
+    return g_spawn_async(working_directory, argv, envp, flags,
+                         slirp_gspawn_fds_setup, &setup,
+                         child_pid, error);
+#endif
+}
+
+#define g_spawn_async_with_fds(wd, argv, env, f, c, d, p, ifd, ofd, efd, err) \
+    g_spawn_async_with_fds_slirp(wd, argv, env, f, c, d, p, ifd, ofd, efd, err)
+
+#pragma GCC diagnostic pop
+
 int
 fork_exec(struct socket *so, const char *ex)
 {
@@ -144,17 +211,18 @@ fork_exec(struct socket *so, const char *ex)
     if (err) {
         g_critical("fork_exec: %s", err->message);
         g_error_free(err);
-        closesocket(sp[0]);
-        closesocket(sp[1]);
+        slirp_closesocket(sp[0]);
+        slirp_closesocket(sp[1]);
         return 0;
     }
 
     so->s = sp[0];
-    closesocket(sp[1]);
-    socket_set_fast_reuse(so->s);
+    slirp_closesocket(sp[1]);
+    slirp_socket_set_fast_reuse(so->s);
     opt = 1;
-    qemu_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
-    qemu_set_nonblock(so->s);
+    slirp_setsockopt(so->s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+    slirp_set_nonblock(so->s);
+    so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);
     return 1;
 }