>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