summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniels@collabora.com>2022-07-21 16:46:07 +0100
committerPekka Paalanen <pq@iki.fi>2023-04-19 08:28:21 +0000
commit11c9ec11fa7514ea2d70d6cabad331f7becb1b3e (patch)
tree7a890ff696cb6c9abfa6024f51f7a8106fe5f05a
parent7397030f707891cee2f362dd5b4e5d7f7504ecc2 (diff)
downloadweston-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.c22
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);