[mutter/wayland] xwayland: Fork the X server ourselves
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] xwayland: Fork the X server ourselves
- Date: Wed, 2 Apr 2014 15:42:50 +0000 (UTC)
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]