[mutter/wayland] xwayland: Fork the X server ourselves



commit 5cf0740b4e13cc577935247146628be8f30cb71c
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Apr 1 19:51:43 2014 -0400

    xwayland: Fork the X server ourselves
    
    gspawn just isn't us the fine-grained control we need for starting
    processes and leaking file descriptors in.

 src/wayland/meta-xwayland.c |  101 ++++++++++++++++---------------------------
 1 files changed, 37 insertions(+), 64 deletions(-)
---
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 5321aef..9ef6398 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -252,18 +252,6 @@ bind_to_unix_socket (int display)
 }
 
 static void
-uncloexec (gpointer user_data)
-{
-  int fd = GPOINTER_TO_INT (user_data);
-
-  /* Make sure the client end of the socket pair doesn't get closed
-   * when we exec xwayland. */
-  int flags = fcntl (fd, F_GETFD);
-  if (flags != -1)
-    fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC);
-}
-
-static void
 xserver_died (GPid     pid,
               gint     status,
               gpointer user_data)
@@ -341,9 +329,8 @@ meta_xwayland_start (MetaXWaylandManager *manager,
                      struct wl_display   *wl_display)
 {
   int sp[2];
-  pid_t pid;
-  char **env;
-  char *fd_string;
+  int fd;
+  char *socket_fd;
 
   if (!choose_xdisplay (manager))
     return FALSE;
@@ -361,55 +348,41 @@ meta_xwayland_start (MetaXWaylandManager *manager,
       return 1;
     }
 
-  env = g_get_environ ();
-  fd_string = g_strdup_printf ("%d", sp[1]);
-  env = g_environ_setenv (env, "WAYLAND_SOCKET", fd_string, TRUE);
-  g_free (fd_string);
-
-  {
-    GError *error = NULL;
-    gchar *args[] = { XWAYLAND_PATH,
-                      manager->display_name,
-                      "-wayland",
-                      "-rootless",
-                      "-noreset",
-                      "-nolisten",
-                      "all",
-                      NULL };
-    int flags = 0;
-
-    flags |= G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
-    flags |= G_SPAWN_DO_NOT_REAP_CHILD;
-
-    /* xwayland, please. */
-    if (getenv ("XWAYLAND_STFU"))
-      {
-        flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
-        flags |= G_SPAWN_STDERR_TO_DEV_NULL;
-      }
-
-    if (g_spawn_async (NULL, /* cwd */
-                       args,
-                       env,
-                       flags,
-                       uncloexec,
-                       GINT_TO_POINTER (sp[1]),
-                       &pid,
-                       &error))
-      {
-        close (sp[1]);
-        manager->client = wl_client_create (wl_display, sp[0]);
-
-        manager->pid = pid;
-        g_child_watch_add (pid, xserver_died, NULL);
-      }
-    else
-      {
-        g_error ("Failed to fork for xwayland server: %s", error->message);
-      }
-  }
-
-  g_strfreev (env);
+  manager->pid = fork ();
+  if (manager->pid == 0)
+    {
+      /* We passed SOCK_CLOEXEC, so dup the FD so it isn't
+       * closed on exec.. */
+      fd = dup (sp[1]);
+      socket_fd = g_strdup_printf ("%d", fd);
+      setenv ("WAYLAND_SOCKET", socket_fd, TRUE);
+      g_free (socket_fd);
+
+      /* xwayland, please. */
+      if (g_getenv ("XWAYLAND_STFU"))
+        {
+          int dev_null;
+          dev_null = open ("/dev/null", O_WRONLY);
+
+          dup2 (dev_null, STDOUT_FILENO);
+          dup2 (dev_null, STDERR_FILENO);
+        }
+
+      if (execl (XWAYLAND_PATH, XWAYLAND_PATH,
+                 manager->display_name,
+                 "-wayland",
+                 "-rootless",
+                 "-noreset",
+                 "-nolisten", "all",
+                 NULL) < 0)
+        {
+          g_warning ("Failed to spawn XWayland: %m");
+          exit (EXIT_FAILURE);
+        }
+    }
+
+  g_child_watch_add (manager->pid, xserver_died, NULL);
+  manager->client = wl_client_create (wl_display, sp[0]);
 
   /* We need to run a mainloop until we know xwayland has a binding
    * for our xserver interface at which point we can assume it's


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