summaryrefslogtreecommitdiff
path: root/xwayland/launcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'xwayland/launcher.c')
-rw-r--r--xwayland/launcher.c106
1 files changed, 62 insertions, 44 deletions
diff --git a/xwayland/launcher.c b/xwayland/launcher.c
index 8d8e060a..f0a87f5b 100644
--- a/xwayland/launcher.c
+++ b/xwayland/launcher.c
@@ -33,20 +33,38 @@
#include <signal.h>
#include "xwayland.h"
-#include "xserver-server-protocol.h"
static int
+handle_sigusr1(int signal_number, void *data)
+{
+ struct weston_xserver *wxs = data;
+
+ /* We'd be safer if we actually had the struct
+ * signalfd_siginfo from the signalfd data and could verify
+ * this came from Xwayland.*/
+ weston_wm_create(wxs, wxs->wm_fd);
+ wl_event_source_remove(wxs->sigusr1_source);
+
+ return 1;
+}
+
+static int
weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
{
struct weston_xserver *wxs = data;
- char display[8], s[8];
- int sv[2], client_fd;
+ char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8];
+ int sv[2], wm[2], fd;
char *xserver = NULL;
struct weston_config_section *section;
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
- weston_log("socketpair failed\n");
+ weston_log("wl connection socketpair failed\n");
+ return 1;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) {
+ weston_log("X wm connection socketpair failed\n");
return 1;
}
@@ -55,29 +73,52 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
case 0:
/* SOCK_CLOEXEC closes both ends, so we need to unset
* the flag on the client fd. */
- client_fd = dup(sv[1]);
- if (client_fd < 0)
- return 1;
-
- snprintf(s, sizeof s, "%d", client_fd);
+ fd = dup(sv[1]);
+ if (fd < 0)
+ goto fail;
+ snprintf(s, sizeof s, "%d", fd);
setenv("WAYLAND_SOCKET", s, 1);
snprintf(display, sizeof display, ":%d", wxs->display);
- section = weston_config_get_section(wxs->compositor->config, "xwayland", NULL, NULL);
- weston_config_section_get_string(section, "path", &xserver, XSERVER_PATH);
+ fd = dup(wxs->abstract_fd);
+ if (fd < 0)
+ goto fail;
+ snprintf(abstract_fd, sizeof abstract_fd, "%d", fd);
+ fd = dup(wxs->unix_fd);
+ if (fd < 0)
+ goto fail;
+ snprintf(unix_fd, sizeof unix_fd, "%d", fd);
+ fd = dup(wm[1]);
+ if (fd < 0)
+ goto fail;
+ snprintf(wm_fd, sizeof wm_fd, "%d", fd);
+
+ section = weston_config_get_section(wxs->compositor->config,
+ "xwayland", NULL, NULL);
+ weston_config_section_get_string(section, "path",
+ &xserver, XSERVER_PATH);
+
+ /* Ignore SIGUSR1 in the child, which will make the X
+ * server send SIGUSR1 to the parent (weston) when
+ * it's done with initialization. During
+ * initialization the X server will round trip and
+ * block on the wayland compositor, so avoid making
+ * blocking requests (like xcb_connect_to_fd) until
+ * it's done with that. */
+ signal(SIGUSR1, SIG_IGN);
if (execl(xserver,
xserver,
display,
- "-wayland",
"-rootless",
- "-retro",
- "-nolisten", "all",
+ "-listen", abstract_fd,
+ "-listen", unix_fd,
+ "-wm", wm_fd,
"-terminate",
NULL) < 0)
weston_log("exec failed: %m\n");
- free(xserver);
+ fail:
_exit(EXIT_FAILURE);
default:
@@ -86,6 +127,9 @@ weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
close(sv[1]);
wxs->client = wl_client_create(wxs->wl_display, sv[0]);
+ close(wm[1]);
+ wxs->wm_fd = wm[0];
+
weston_watch_process(&wxs->process);
wl_event_source_remove(wxs->abstract_source);
@@ -153,32 +197,6 @@ weston_xserver_cleanup(struct weston_process *process, int status)
}
}
-static void
-bind_xserver(struct wl_client *client,
- void *data, uint32_t version, uint32_t id)
-{
- struct weston_xserver *wxs = data;
-
- /* If it's a different client than the xserver we launched,
- * don't start the wm. */
- if (client != wxs->client)
- return;
-
- wxs->resource =
- wl_resource_create(client, &xserver_interface,
- 1, id);
- wl_resource_set_implementation(wxs->resource, &xserver_implementation,
- wxs, NULL);
-
- wxs->wm = weston_wm_create(wxs);
- if (wxs->wm == NULL) {
- weston_log("failed to create wm\n");
- }
-
- xserver_send_listen_socket(wxs->resource, wxs->abstract_fd);
- xserver_send_listen_socket(wxs->resource, wxs->unix_fd);
-}
-
static int
bind_to_abstract_socket(int display)
{
@@ -251,7 +269,7 @@ create_lockfile(int display, char *lockfile, size_t lsize)
snprintf(lockfile, lsize, "/tmp/.X%d-lock", display);
fd = open(lockfile, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
if (fd < 0 && errno == EEXIST) {
- fd = open(lockfile, O_CLOEXEC, O_RDONLY);
+ fd = open(lockfile, O_CLOEXEC | O_RDONLY);
if (fd < 0 || read(fd, pid, 11) != 11) {
weston_log("can't read lock file %s: %s\n",
lockfile, strerror(errno));
@@ -380,8 +398,8 @@ module_init(struct weston_compositor *compositor,
WL_EVENT_READABLE,
weston_xserver_handle_event, wxs);
- wl_global_create(display, &xserver_interface, 1, wxs, bind_xserver);
-
+ wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1,
+ handle_sigusr1, wxs);
wxs->destroy_listener.notify = weston_xserver_destroy;
wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);