aboutsummaryrefslogtreecommitdiff
path: root/vis.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2016-11-25 16:46:38 +0100
committerMarc André Tanner <mat@brain-dump.org>2016-11-25 17:07:39 +0100
commitab65ab5d027e97ead372264a6ecfd3ac642299ba (patch)
tree747a869eadeed1effb902298b90cd828fa7ba806 /vis.c
parent1c9c52647fe2984472246eb2c12b3412fd5fafa4 (diff)
downloadvis-ab65ab5d027e97ead372264a6ecfd3ac642299ba.tar.gz
vis-ab65ab5d027e97ead372264a6ecfd3ac642299ba.tar.xz
vis: fix I/O redirection bugs, cleanup vis_pipe
The `:!` command did redirect stdout to a pipe which was used by `vis-menu` to return the selected entry. However, this breaks other interactive commands such as `:!/bin/sh` where command output was never displayed. Instead we modified `vis-menu` to re-open /dev/tty for its user interface which makes it work as a regular filter `:|` This patch also obsoletes the interactive flag previously passed to the vis_pipe function. Interactive mode is instead enabled by piping an invalid range.
Diffstat (limited to 'vis.c')
-rw-r--r--vis.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/vis.c b/vis.c
index f8d3dbf..971af8b 100644
--- a/vis.c
+++ b/vis.c
@@ -1289,7 +1289,7 @@ Regex *vis_regex(Vis *vis, const char *pattern) {
return regex;
}
-int vis_pipe(Vis *vis, Filerange *range, bool interactive, const char *argv[],
+int vis_pipe(Vis *vis, Filerange *range, const char *argv[],
void *stdout_context, ssize_t (*read_stdout)(void *stdout_context, char *data, size_t len),
void *stderr_context, ssize_t (*read_stderr)(void *stderr_context, char *data, size_t len)) {
@@ -1298,8 +1298,6 @@ int vis_pipe(Vis *vis, Filerange *range, bool interactive, const char *argv[],
Text *text = vis->win->file->text;
int pin[2], pout[2], perr[2], status = -1;
bool valid_range = text_range_valid(range);
- if (!valid_range)
- interactive = true;
Filerange rout = valid_range ? *range : text_range_new(0, 0);
if (pipe(pin) == -1)
@@ -1331,14 +1329,17 @@ int vis_pipe(Vis *vis, Filerange *range, bool interactive, const char *argv[],
vis_info_show(vis, "fork failure: %s", strerror(errno));
return -1;
} else if (pid == 0) { /* child i.e filter */
- if (!interactive || valid_range)
+ if (valid_range)
dup2(pin[0], STDIN_FILENO);
close(pin[0]);
close(pin[1]);
- dup2(pout[1], STDOUT_FILENO);
+ if (valid_range)
+ dup2(pout[1], STDOUT_FILENO);
+ else
+ dup2(STDERR_FILENO, STDOUT_FILENO);
close(pout[1]);
close(pout[0]);
- if (!interactive)
+ if (valid_range)
dup2(perr[1], STDERR_FILENO);
close(perr[0]);
close(perr[1]);
@@ -1457,11 +1458,11 @@ static ssize_t read_buffer(void *context, char *data, size_t len) {
return len;
}
-int vis_pipe_collect(Vis *vis, Filerange *range, bool interactive, const char *argv[], char **out, char **err) {
+int vis_pipe_collect(Vis *vis, Filerange *range, const char *argv[], char **out, char **err) {
Buffer bufout, buferr;
buffer_init(&bufout);
buffer_init(&buferr);
- int status = vis_pipe(vis, range, interactive, argv, &bufout, read_buffer, &buferr, read_buffer);
+ int status = vis_pipe(vis, range, argv, &bufout, read_buffer, &buferr, read_buffer);
buffer_terminate(&bufout);
buffer_terminate(&buferr);
if (out)