summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniels@collabora.com>2022-07-21 17:32:51 +0100
committerPekka Paalanen <pq@iki.fi>2023-04-19 08:28:21 +0000
commit3ac27480210c0460cb72f4957a09886fcdcd8a5d (patch)
tree5dcf47d8a997527abfc46c1e42515fad0c933372
parentdfda0ca9d2d8b940059bc0e48543cd2a731e4543 (diff)
downloadweston-3ac27480210c0460cb72f4957a09886fcdcd8a5d.tar.gz
xwayland: Reuse weston_client_launch
Now that our process-launching internals are identical between the (still-misnamed) weston_client_launch and the frontend's Xwayland launcher, we can reuse the internals instead of open-coding it. As a result, we now additionally prevent Xwayland from inheriting Weston's signal mask, by clearing SIG_UNBLOCK on all signals. This should have no observable effect as we do not depend on signal handling within Xwayland, instead using the displayfd readiness mechanism since c2f4201ed2a8. Signed-off-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--compositor/xwayland.c129
1 files changed, 47 insertions, 82 deletions
diff --git a/compositor/xwayland.c b/compositor/xwayland.c
index f2f9ea76..44f02016 100644
--- a/compositor/xwayland.c
+++ b/compositor/xwayland.c
@@ -91,11 +91,20 @@ out:
return 0;
}
+static void
+xserver_cleanup(struct weston_process *process, int status)
+{
+ struct wet_xwayland *wxw =
+ container_of(process, struct wet_xwayland, process);
+
+ wxw->api->xserver_exited(wxw->xwayland, status);
+ wxw->client = NULL;
+}
+
static pid_t
spawn_xserver(void *user_data, const char *display, int abstract_fd, int unix_fd)
{
struct wet_xwayland *wxw = user_data;
- pid_t pid;
struct fdstr wayland_socket = FDSTR_INIT;
struct fdstr x11_abstract_socket = FDSTR_INIT;
struct fdstr x11_unix_socket = FDSTR_INIT;
@@ -105,34 +114,29 @@ spawn_xserver(void *user_data, const char *display, int abstract_fd, int unix_fd
struct weston_config *config = wet_get_config(wxw->compositor);
struct weston_config_section *section;
struct wl_event_loop *loop;
- char *exec_failure_msg;
- const char *cloexec_failure_msg = "Couldn't unset CLOEXEC on child FDs";
struct custom_env child_env;
int no_cloexec_fds[5];
size_t num_no_cloexec_fds = 0;
- size_t i;
- char *const *envp;
- char *const *argp;
int ret;
size_t written __attribute__ ((unused));
if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, wayland_socket.fds) < 0) {
weston_log("wl connection socketpair failed\n");
- return -1;
+ goto err;
}
fdstr_update_str1(&wayland_socket);
no_cloexec_fds[num_no_cloexec_fds++] = wayland_socket.fds[1];
if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, x11_wm_socket.fds) < 0) {
weston_log("X wm connection socketpair failed\n");
- goto err_wayland_socket;
+ goto err;
}
fdstr_update_str1(&x11_wm_socket);
no_cloexec_fds[num_no_cloexec_fds++] = x11_wm_socket.fds[1];
if (pipe2(display_pipe.fds, O_CLOEXEC) < 0) {
weston_log("pipe creation for displayfd failed\n");
- goto err_x11_wm_socket;
+ goto err;
}
fdstr_update_str1(&display_pipe);
no_cloexec_fds[num_no_cloexec_fds++] = display_pipe.fds[1];
@@ -148,8 +152,6 @@ spawn_xserver(void *user_data, const char *display, int abstract_fd, int unix_fd
section = weston_config_get_section(config, "xwayland", NULL, NULL);
weston_config_section_get_string(section, "path",
&xserver, XSERVER_PATH);
- str_printf(&exec_failure_msg,
- "Error: executing Xwayland as '%s' failed.\n", xserver);
custom_env_init_from_environ(&child_env);
custom_env_set_env_var(&child_env, "WAYLAND_SOCKET", wayland_socket.str1);
@@ -166,88 +168,51 @@ spawn_xserver(void *user_data, const char *display, int abstract_fd, int unix_fd
custom_env_add_arg(&child_env, x11_wm_socket.str1);
custom_env_add_arg(&child_env, "-terminate");
- envp = custom_env_get_envp(&child_env);
- argp = custom_env_get_argp(&child_env);
-
- pid = fork();
- switch (pid) {
- case 0:
- setsid();
-
- for (i = 0; i < num_no_cloexec_fds; i++) {
- ret = os_fd_clear_cloexec(no_cloexec_fds[i]);
- if (ret < 0) {
- write(STDERR_FILENO, cloexec_failure_msg,
- strlen(cloexec_failure_msg));
- _exit(EXIT_FAILURE);
- }
- }
-
- execve(xserver, argp, envp);
- /* execve does not return on success, so it failed */
-
- if (exec_failure_msg) {
- written = write(STDERR_FILENO, exec_failure_msg,
- strlen(exec_failure_msg));
- }
-
- _exit(EXIT_FAILURE);
-
- default:
- close(wayland_socket.fds[1]);
- wxw->client = wl_client_create(wxw->compositor->wl_display,
- wayland_socket.fds[0]);
-
- close(x11_wm_socket.fds[1]);
- wxw->wm_fd = x11_wm_socket.fds[0];
-
- /* 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. */
- close(display_pipe.fds[1]);
- loop = wl_display_get_event_loop(wxw->compositor->wl_display);
- wxw->display_fd_source =
- wl_event_loop_add_fd(loop, display_pipe.fds[0],
- WL_EVENT_READABLE,
- handle_display_fd, wxw);
-
- wxw->process.pid = pid;
- wet_watch_process(wxw->compositor, &wxw->process);
- break;
-
- case -1:
- weston_log("Failed to fork to spawn xserver process\n");
- fdstr_close_all(&wayland_socket);
- fdstr_close_all(&x11_wm_socket);
- fdstr_close_all(&display_pipe);
- break;
+ ret = weston_client_launch(wxw->compositor, &wxw->process, &child_env,
+ no_cloexec_fds, num_no_cloexec_fds,
+ xserver_cleanup);
+ if (!ret) {
+ weston_log("Couldn't start Xwayland\n");
+ goto err;
}
- custom_env_fini(&child_env);
- free(exec_failure_msg);
+ wxw->client = wl_client_create(wxw->compositor->wl_display,
+ wayland_socket.fds[0]);
+ if (!wxw->client) {
+ weston_log("Couldn't create client for Xwayland\n");
+ goto err;
+ }
+
+ wxw->wm_fd = x11_wm_socket.fds[0];
+
+ /* Now we can no longer fail, close the child end of our sockets */
+ close(wayland_socket.fds[1]);
+ close(x11_wm_socket.fds[1]);
+ close(display_pipe.fds[1]);
+
+ /* 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. */
+ loop = wl_display_get_event_loop(wxw->compositor->wl_display);
+ wxw->display_fd_source =
+ wl_event_loop_add_fd(loop, display_pipe.fds[0],
+ WL_EVENT_READABLE,
+ handle_display_fd, wxw);
+
free(xserver);
- return pid;
+ return wxw->process.pid;
-err_x11_wm_socket:
+err:
+ free(xserver);
+ fdstr_close_all(&display_pipe);
fdstr_close_all(&x11_wm_socket);
-err_wayland_socket:
fdstr_close_all(&wayland_socket);
return -1;
}
static void
-xserver_cleanup(struct weston_process *process, int status)
-{
- struct wet_xwayland *wxw =
- container_of(process, struct wet_xwayland, process);
-
- wxw->api->xserver_exited(wxw->xwayland, status);
- wxw->client = NULL;
-}
-
-static void
wxw_compositor_destroy(struct wl_listener *listener, void *data)
{
struct wet_xwayland *wxw =