>From 267206b7cba10ffb2de8f17b0f224c10a479868c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Diego=20Aur=C3=A9lio=20Mesquita?= Date: Sun, 12 Aug 2018 13:42:01 -0300 Subject: [PATCH] filter: replace fork with clone so that file descriptors can be shared between parent and child. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes https://savannah.gnu.org/bugs/?54499. Signed-off-by: Marco Diego Aurélio Mesquita --- src/text.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/text.c b/src/text.c index 4fe441fc..9a5c6357 100644 --- a/src/text.c +++ b/src/text.c @@ -30,6 +30,10 @@ #include #include #include +#include + +#define STACK_SIZE 65536 + /* Stack size for cloned process to pipe out the buffer. */ #ifndef NANO_TINY static pid_t pid_of_command = -1; @@ -1094,21 +1098,20 @@ RETSIGTYPE cancel_the_command(int signal) kill(pid_of_command, SIGKILL); } -/* Send the text that starts at the given line to file descriptor fd. */ -void send_data(const filestruct *line, int fd) +/* Sends the current buffer or cutbuffer to file descriptor. */ +int send_data(void *fds) { - FILE *tube = fdopen(fd, "w"); - - if (tube == NULL) - return; - - /* Send each line, except a final empty line. */ + int *to_fd = ((int*)fds); + const filestruct *line = cutbuffer != NULL ? cutbuffer : openfile->fileage; while (line != NULL && (line->next != NULL || line->data[0] != '\0')) { - fprintf(tube, "%s%s", line->data, line->next == NULL ? "" : "\n"); + dprintf(to_fd[1], "%s%s", line->data, line->next == NULL ? "" : "\n"); line = line->next; } - fclose(tube); + close(to_fd[0]); + close(to_fd[1]); + + return 0; } /* Execute the given command in a shell. Return TRUE on success. */ @@ -1123,6 +1126,8 @@ bool execute_command(const char *command) /* Original and temporary handlers for SIGINT. */ bool setup_failed = FALSE; /* Whether setting up the temporary SIGINT handler failed. */ + char *stack; + /* Stack for cloned process to pipe out the buffer. */ /* Create a pipe to read the command's output from, and, if needed, * a pipe to feed the command's input through. */ @@ -1143,7 +1148,6 @@ bool execute_command(const char *command) /* Connect the write end of the output pipe to the process' output streams. */ dup2(from_fd[1], fileno(stdout)); - dup2(from_fd[1], fileno(stderr)); /* If the parent sends text, connect the read end of the * feeding pipe to the child's input stream. */ @@ -1192,15 +1196,9 @@ bool execute_command(const char *command) update_undo(CUT); } - if (fork() == 0) { - close(to_fd[0]); - send_data(cutbuffer != NULL ? cutbuffer : openfile->fileage, to_fd[1]); - close(to_fd[1]); - exit(0); - } - - close(to_fd[0]); - close(to_fd[1]); + stack = malloc(STACK_SIZE); + clone(send_data, stack + STACK_SIZE, CLONE_FILES, to_fd); + free(stack); #ifdef ENABLE_MULTIBUFFER if (ISSET(MULTIBUFFER)) -- 2.11.0