diff options
author | Daniel Stone <daniels@collabora.com> | 2022-07-21 16:46:07 +0100 |
---|---|---|
committer | Pekka Paalanen <pq@iki.fi> | 2023-04-19 08:28:21 +0000 |
commit | 11c9ec11fa7514ea2d70d6cabad331f7becb1b3e (patch) | |
tree | 7a890ff696cb6c9abfa6024f51f7a8106fe5f05a | |
parent | 7397030f707891cee2f362dd5b4e5d7f7504ecc2 (diff) | |
download | weston-11c9ec11fa7514ea2d70d6cabad331f7becb1b3e.tar.gz |
frontend: Use array for clearing CLOEXEC in child
When we launch a child, we need to clear CLOEXEC on any FDs we want to
survive the exec. Use an array for doing this, so it's more generic and
we can allow callers to pass in their own.
Signed-off-by: Daniel Stone <daniels@collabora.com>
-rw-r--r-- | compositor/main.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/compositor/main.c b/compositor/main.c index 41e20123..e679af8d 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -396,13 +396,16 @@ weston_client_launch(struct weston_compositor *compositor, struct wl_client *client = NULL; struct custom_env child_env; struct fdstr wayland_socket = FDSTR_INIT; - const char *fail_cloexec = "Couldn't unset CLOEXEC on client socket"; + int no_cloexec_fds[1]; + size_t num_no_cloexec_fds = 0; + const char *fail_cloexec = "Couldn't unset CLOEXEC on child FDs"; const char *fail_seteuid = "Couldn't call seteuid"; char *fail_exec; char * const *argp; char * const *envp; pid_t pid; - bool ret; + int err; + size_t i; size_t written __attribute__((unused)); weston_log("launching '%s'\n", path); @@ -420,12 +423,15 @@ weston_client_launch(struct weston_compositor *compositor, return NULL; } fdstr_update_str1(&wayland_socket); + no_cloexec_fds[num_no_cloexec_fds++] = wayland_socket.fds[1]; custom_env_set_env_var(&child_env, "WAYLAND_SOCKET", wayland_socket.str1); argp = custom_env_get_argp(&child_env); envp = custom_env_get_envp(&child_env); + assert(num_no_cloexec_fds <= ARRAY_LENGTH(no_cloexec_fds)); + pid = fork(); switch (pid) { case 0: @@ -438,11 +444,13 @@ weston_client_launch(struct weston_compositor *compositor, _exit(EXIT_FAILURE); } - ret = fdstr_clear_cloexec_fd1(&wayland_socket); - if (!ret) { - written = write(STDERR_FILENO, fail_cloexec, - strlen(fail_cloexec)); - _exit(EXIT_FAILURE); + for (i = 0; i < num_no_cloexec_fds; i++) { + err = os_fd_clear_cloexec(no_cloexec_fds[i]); + if (err < 0) { + written = write(STDERR_FILENO, fail_cloexec, + strlen(fail_cloexec)); + _exit(EXIT_FAILURE); + } } execve(argp[0], argp, envp); |