From 858f41144729d0271c0d46433fa07e7e27fa3040 Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Fri, 7 Oct 2022 16:04:06 +0200 Subject: [PATCH] filtering: terminate also the sender process when the user hits ^C When the user interrupts an external command that hangs or takes too long, nano should also kill the data-sending process (when present). This fixes https://savannah.gnu.org/bugs/?63177. Bug existed in this form since version 4.3, commit d946f38a, but basically existed since version 3.0, commit ec339d3b. --- src/files.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/files.c b/src/files.c index 64061452..9715face 100644 --- a/src/files.c +++ b/src/files.c @@ -969,12 +969,19 @@ char *get_next_filename(const char *name, const char *suffix) #ifndef NANO_TINY static pid_t pid_of_command = -1; /* The PID of a forked process -- needed when wanting to abort it. */ +static pid_t pid_of_sender = -1; + /* The PID of the process that pipes data to the above process. */ +static bool should_pipe = FALSE; + /* Whether we are piping data to the external command. */ /* Send an unconditional kill signal to the running external command. */ void cancel_the_command(int signal) { #ifdef SIGKILL - kill(pid_of_command, SIGKILL); + if (pid_of_command > 0) + kill(pid_of_command, SIGKILL); + if (should_pipe && pid_of_sender > 0) + kill(pid_of_sender, SIGKILL); #endif } @@ -1011,11 +1018,11 @@ void execute_command(const char *command) struct sigaction oldaction, newaction = {{0}}; /* Original and temporary handlers for SIGINT. */ ssize_t was_lineno = (openfile->mark ? 0 : openfile->current->lineno); - const bool should_pipe = (command[0] == '|'); int command_status, sender_status; - pid_t pid_of_sender; FILE *stream; + should_pipe = (command[0] == '|'); + /* Create a pipe to read the command's output from, and, if needed, * a pipe to feed the command's input through. */ if (pipe(from_fd) == -1 || (should_pipe && pipe(to_fd) == -1)) {