From 7314d67a2097794caefcb19d917f198a3cbfd3ae Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 19 Aug 2024 21:41:23 +0200 Subject: [PATCH] gui: Kill also child processes of external commands. When a command is executed as a display command from para_gui, and the command is interrupted from within para_gui by pressing any key, para_gui only kills the spawned process but leaves alone its child processes. Address this problem by putting the spawned process into a separate process group so that we can easily kill all processes of the group by passing the negated PID of the child to kill(2). In theory, the change in exec.c also affects para_mixer, which executes para_client and para_audioc. However, para_mixer never kills any of its child processes. --- exec.c | 8 ++++++++ gui.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 38f445ee..364395bd 100644 --- a/exec.c +++ b/exec.c @@ -69,6 +69,14 @@ static int para_exec(pid_t *pid, const char *file, char *const *const args, int } if (null >= 0) close(null); + /* + * If stdin is redirected, the foreground process group can no + * longer be signalled with CTRL+C. Set the process group ID of + * the child to its PID so that the parent can send a signal to + * the process group to kill the child and all its subprocesses. + */ + if (fds[0] >= 0) + setpgid(0, 0); execvp(file, args); _exit(EXIT_FAILURE); } diff --git a/gui.c b/gui.c index 66fb7870..2ad8ae46 100644 --- a/gui.c +++ b/gui.c @@ -1119,8 +1119,8 @@ static int input_post_monitor(__a_unused struct sched *s, return 0; if (exs == EXEC_IDLE) handle_command(ret); - else if (exec_pid > 0) - kill(exec_pid, SIGTERM); + else if (exec_pid > 0) /* negate to kill whole process group */ + kill(-exec_pid, SIGTERM); return 0; } -- 2.39.5