From a42f99081876dd02e28b931f7c0e70230355bb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 23 Jul 2024 06:57:30 +0200 Subject: [PATCH] spawn: add optional reaper callback, return pid_t This will allow spawn() callers to do things when the spawned process has terminated. --- input.c | 4 ++-- notify.c | 6 +++++- spawn.c | 14 +++++++------- spawn.h | 8 +++++--- terminal.c | 8 ++++---- url-mode.c | 5 +++-- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/input.c b/input.c index dc588f75..98f5c89c 100644 --- a/input.c +++ b/input.c @@ -306,8 +306,8 @@ execute_binding(struct seat *seat, struct terminal *term, } } - if (!spawn(term->reaper, term->cwd, binding->aux->pipe.args, - pipe_fd[0], stdout_fd, stderr_fd, NULL)) + if (spawn(term->reaper, term->cwd, binding->aux->pipe.args, + pipe_fd[0], stdout_fd, stderr_fd, NULL, NULL, NULL) < 0) goto pipe_err; /* Close read end */ diff --git a/notify.c b/notify.c index 09e230a0..7cd22ccb 100644 --- a/notify.c +++ b/notify.c @@ -59,7 +59,11 @@ notify_notify(const struct terminal *term, const char *title, const char *body, /* Redirect stdin to /dev/null, but ignore failure to open */ int devnull = open("/dev/null", O_RDONLY); - spawn(term->reaper, NULL, argv, devnull, -1, -1, NULL); + pid_t pid = spawn( + term->reaper, NULL, argv, devnull, stdout_fds[1], -1, + ¬if_done, (void *)term, NULL); + + if (stdout_fds[1] >= 0) { if (devnull >= 0) close(devnull); diff --git a/spawn.c b/spawn.c index 6935a29a..17c821b5 100644 --- a/spawn.c +++ b/spawn.c @@ -15,9 +15,9 @@ #include "debug.h" #include "xmalloc.h" -bool +pid_t spawn(struct reaper *reaper, const char *cwd, char *const argv[], - int stdin_fd, int stdout_fd, int stderr_fd, + int stdin_fd, int stdout_fd, int stderr_fd, reaper_cb cb, void *cb_data, const char *xdg_activation_token) { int pipe_fds[2] = {-1, -1}; @@ -104,16 +104,16 @@ spawn(struct reaper *reaper, const char *cwd, char *const argv[], close(pipe_fds[0]); if (ret == 0) { - reaper_add(reaper, pid, NULL, NULL); - return true; + reaper_add(reaper, pid, cb, cb_data); + return pid; } else if (ret < 0) { LOG_ERRNO("failed to read from pipe"); - return false; + return -1; } else { LOG_ERRNO_P(errno_copy, "%s: failed to spawn", argv[0]); errno = errno_copy; waitpid(pid, NULL, 0); - return false; + return -1; } err: @@ -121,7 +121,7 @@ err: close(pipe_fds[0]); if (pipe_fds[1] != -1) close(pipe_fds[1]); - return false; + return -1; } bool diff --git a/spawn.h b/spawn.h index 0fc95041..1693f1a8 100644 --- a/spawn.h +++ b/spawn.h @@ -1,12 +1,14 @@ #pragma once #include +#include + #include "config.h" #include "reaper.h" -bool spawn(struct reaper *reaper, const char *cwd, char *const argv[], - int stdin_fd, int stdout_fd, int stderr_fd, - const char *xdg_activation_token); +pid_t spawn(struct reaper *reaper, const char *cwd, char *const argv[], + int stdin_fd, int stdout_fd, int stderr_fd, + reaper_cb cb, void *cb_data, const char *xdg_activation_token); bool spawn_expand_template( const struct config_spawn_template *template, diff --git a/terminal.c b/terminal.c index 712b9d4e..bf0c78dc 100644 --- a/terminal.c +++ b/terminal.c @@ -198,7 +198,7 @@ add_utmp_record(const struct config *conf, struct reaper *reaper, int ptmx) return true; char *const argv[] = {conf->utmp_helper_path, UTMP_ADD, getenv("WAYLAND_DISPLAY"), NULL}; - return spawn(reaper, NULL, argv, ptmx, ptmx, -1, NULL); + return spawn(reaper, NULL, argv, ptmx, ptmx, -1, NULL, NULL, NULL) >= 0; #else return true; #endif @@ -222,7 +222,7 @@ del_utmp_record(const struct config *conf, struct reaper *reaper, int ptmx) ; char *const argv[] = {conf->utmp_helper_path, UTMP_DEL, del_argument, NULL}; - return spawn(reaper, NULL, argv, ptmx, ptmx, -1, NULL); + return spawn(reaper, NULL, argv, ptmx, ptmx, -1, NULL, NULL, NULL) >= 0; #else return true; #endif @@ -3594,7 +3594,7 @@ term_bell(struct terminal *term) { int devnull = open("/dev/null", O_RDONLY); spawn(term->reaper, NULL, term->conf->bell.command.argv.args, - devnull, -1, -1, NULL); + devnull, -1, -1, NULL, NULL, NULL); if (devnull >= 0) close(devnull); @@ -3606,7 +3606,7 @@ term_spawn_new(const struct terminal *term) { return spawn( term->reaper, term->cwd, (char *const []){term->foot_exe, NULL}, - -1, -1, -1, NULL); + -1, -1, -1, NULL, NULL, NULL) >= 0; } void diff --git a/url-mode.c b/url-mode.c index 57f47dd0..c6340e94 100644 --- a/url-mode.c +++ b/url-mode.c @@ -74,8 +74,9 @@ spawn_url_launcher_with_token(struct terminal *term, (const char *[]){url}, &argc, &argv)) { - ret = spawn(term->reaper, term->cwd, argv, - dev_null, dev_null, dev_null, xdg_activation_token); + ret = spawn( + term->reaper, term->cwd, argv, + dev_null, dev_null, dev_null, NULL, NULL, xdg_activation_token) >= 0; for (size_t i = 0; i < argc; i++) free(argv[i]);