aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-11-26 17:23:19 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-11-26 18:00:04 +0100
commitf0e87e3af9b64f5f5d96296a3baac62a1d2f8632 (patch)
treec35f9411e4851e9a64188bdd4934eff874e6c985
parentf42a3165e8b527a81865870f74865c1cd99b7196 (diff)
downloadvis-f0e87e3af9b64f5f5d96296a3baac62a1d2f8632.tar.gz
vis-f0e87e3af9b64f5f5d96296a3baac62a1d2f8632.tar.xz
vis: redirect stdout and stderr streams to /dev/null when lacking a consumer
If the caller of vis_pipe is not interested in the output, redirect it to /dev/null and close the pipe. Otherwise we would wait for possible output (which might never arrive) only to throw it away. As a consequence background processes can now be started with: :> { plumber <&3 3<&- & } 3<&0 2>&- whereas before one also had to explicitly close stdout: :> { plumber <&3 3<&- & } 3<&0 1>&- 2>&-
-rw-r--r--vis.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/vis.c b/vis.c
index 971af8b..b7619fe 100644
--- a/vis.c
+++ b/vis.c
@@ -1297,8 +1297,8 @@ int vis_pipe(Vis *vis, Filerange *range, const char *argv[],
* through the external command. */
Text *text = vis->win->file->text;
int pin[2], pout[2], perr[2], status = -1;
- bool valid_range = text_range_valid(range);
- Filerange rout = valid_range ? *range : text_range_new(0, 0);
+ bool interactive = !text_range_valid(range);
+ Filerange rout = interactive ? text_range_new(0, 0) : *range;
if (pipe(pin) == -1)
return -1;
@@ -1329,20 +1329,32 @@ int vis_pipe(Vis *vis, Filerange *range, const char *argv[],
vis_info_show(vis, "fork failure: %s", strerror(errno));
return -1;
} else if (pid == 0) { /* child i.e filter */
- if (valid_range)
+ int null = open("/dev/null", O_WRONLY);
+ if (null == -1) {
+ fprintf(stderr, "failed to open /dev/null");
+ exit(EXIT_FAILURE);
+ }
+ if (!interactive)
dup2(pin[0], STDIN_FILENO);
close(pin[0]);
close(pin[1]);
- if (valid_range)
+ if (interactive)
+ dup2(STDERR_FILENO, STDOUT_FILENO);
+ else if (read_stdout)
dup2(pout[1], STDOUT_FILENO);
else
- dup2(STDERR_FILENO, STDOUT_FILENO);
+ dup2(null, STDOUT_FILENO);
close(pout[1]);
close(pout[0]);
- if (valid_range)
- dup2(perr[1], STDERR_FILENO);
+ if (!interactive) {
+ if (read_stderr)
+ dup2(perr[1], STDERR_FILENO);
+ else
+ dup2(null, STDERR_FILENO);
+ }
close(perr[0]);
close(perr[1]);
+ close(null);
if (!argv[1])
execlp(vis->shell, vis->shell, "-c", argv[0], (char*)NULL);
else