nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] files: improve the error handling when executing an external com


From: Benno Schulenberg
Subject: [PATCH] files: improve the error handling when executing an external command
Date: Mon, 3 Oct 2022 12:42:58 +0200

When something goes wrong while executing an external command or while
piping text to it, report an error on the status bar and restore the
state of the buffer to what it was before the execution.

This fixes https://savannah.gnu.org/bugs/?63114.

Bug existed since version 2.9.8, since filtering text was introduced,
but basically existed since before version 2.0.0, since executing an
external command was introduced.
---
 src/files.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/files.c b/src/files.c
index 512f5826..f3376b6f 100644
--- a/src/files.c
+++ b/src/files.c
@@ -1012,6 +1012,8 @@ void execute_command(const char *command)
                /* 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;
 
        /* Create a pipe to read the command's output from, and, if needed,
@@ -1095,11 +1097,14 @@ void execute_command(const char *command)
                }
 
                /* Create a separate process for piping the data to the 
command. */
-               if (fork() == 0) {
+               if ((pid_of_sender = fork()) == 0) {
                        send_data(whole_buffer ? openfile->filetop : cutbuffer, 
to_fd[1]);
                        exit(0);
                }
 
+               if (pid_of_sender == -1)
+                       statusline(ALERT, _("Could not fork: %s"), 
strerror(errno));
+
                close(to_fd[0]);
                close(to_fd[1]);
 
@@ -1133,9 +1138,23 @@ void execute_command(const char *command)
        }
 
        /* Wait for the external command (and possibly data sender) to 
terminate. */
-       wait(NULL);
+       waitpid(pid_of_command, &command_status, 0);
        if (should_pipe)
-               wait(NULL);
+               waitpid(pid_of_sender, &sender_status, 0);
+
+       /* If the command failed, show what the shell reported. */
+       if (WIFEXITED(command_status) == 0 || WEXITSTATUS(command_status))
+               statusline(ALERT, _("Error: %s"), openfile->current->prev &&
+                                                       
strstr(openfile->current->prev->data, ": ") ?
+                                                       
strstr(openfile->current->prev->data, ": ") + 2 : "---");
+       else if (should_pipe && (WIFEXITED(sender_status) == 0 || 
WEXITSTATUS(sender_status)))
+               statusline(ALERT, _("Piping failed"));
+
+       /* If there was an error, undo and discard what the command did. */
+       if (lastmessage == ALERT) {
+               do_undo();
+               discard_until(openfile->current_undo);
+       }
 
        /* Restore the original handler for SIGINT. */
        sigaction(SIGINT, &oldaction, NULL);
-- 
2.37.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]