From 1c56750f7b6796e850a9299358dc6a187c6278bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Mon, 14 Nov 2016 17:59:24 +0100 Subject: vis: generalize special stdin handling In preparation to move argument parsing code out of vis.c. --- sam.c | 4 ++-- vis-cmds.c | 2 +- vis-core.h | 2 +- vis.c | 16 ++++++++++++---- vis.h | 5 +++++ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/sam.c b/sam.c index 926b056..328cf3d 100644 --- a/sam.c +++ b/sam.c @@ -1157,7 +1157,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs if (!argv[1]) argv[1] = file->name ? strdup(file->name) : NULL; if (!argv[1]) { - if (!file->is_stdin) { + if (file->fd == -1) { vis_info_show(vis, "Filename expected"); return false; } @@ -1171,7 +1171,7 @@ static bool cmd_write(Vis *vis, Win *win, Command *cmd, const char *argv[], Curs bool all = !text_range_valid(&range); if (all) range = text_range_new(0, text_size(text)); - ssize_t written = text_write_range(text, &range, STDOUT_FILENO); + ssize_t written = text_write_range(text, &range, file->fd); if (written == -1 || (size_t)written != text_range_size(&range)) { vis_info_show(vis, "Can not write to stdout"); return false; diff --git a/vis-cmds.c b/vis-cmds.c index 582f1a8..b3c1de8 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -431,7 +431,7 @@ static bool cmd_wq(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor if (!win) return false; File *file = win->file; - bool unmodified = !file->is_stdin && !file->name && !text_modified(file->text); + bool unmodified = file->fd == -1 && !file->name && !text_modified(file->text); if (unmodified || cmd_write(vis, win, cmd, argv, cur, range)) return cmd_quit(vis, win, cmd, argv, cur, range); return false; diff --git a/vis-core.h b/vis-core.h index e16d23a..05ddca8 100644 --- a/vis-core.h +++ b/vis-core.h @@ -110,7 +110,7 @@ struct File { /* shared state among windows displaying the same file */ Text *text; /* data structure holding the file content */ const char *name; /* file name used when loading/saving */ volatile sig_atomic_t truncated; /* whether the underlying memory mapped region became invalid (SIGBUS) */ - bool is_stdin; /* whether file content was read from stdin */ + int fd; /* output file descriptor associated with this file or -1 if loaded by file name */ bool internal; /* whether it is an internal file (e.g. used for the prompt) */ struct stat stat; /* filesystem information when loaded/saved, used to detect changes outside the editor */ int refcount; /* how many windows are displaying this file? (always >= 1) */ diff --git a/vis.c b/vis.c index 6782a8e..600a636 100644 --- a/vis.c +++ b/vis.c @@ -60,6 +60,7 @@ static File *file_new_text(Vis *vis, Text *text) { File *file = calloc(1, sizeof(*file)); if (!file) return NULL; + file->fd = -1; file->text = text; file->stat = text_stat(text); if (vis->files) @@ -364,6 +365,15 @@ bool vis_window_new(Vis *vis, const char *filename) { return true; } +bool vis_window_new_fd(Vis *vis, int fd) { + if (fd == -1) + return false; + if (!vis_window_new(vis, NULL)) + return false; + vis->win->file->fd = fd; + return true; +} + bool vis_window_closable(Win *win) { if (!win || !text_modified(win->file->text)) return true; @@ -949,13 +959,11 @@ static void vis_args(Vis *vis, int argc, char *argv[]) { if (!vis->windows && vis->running) { if (!strcmp(argv[argc-1], "-")) { - if (!vis_window_new(vis, NULL)) + if (!vis_window_new_fd(vis, STDOUT_FILENO)) vis_die(vis, "Can not create empty buffer\n"); ssize_t len = 0; char buf[PIPE_BUF]; - File *file = vis->win->file; - Text *txt = file->text; - file->is_stdin = true; + Text *txt = vis_text(vis); while ((len = read(STDIN_FILENO, buf, sizeof buf)) > 0) text_insert(txt, text_size(txt), buf, len); if (len == -1) diff --git a/vis.h b/vis.h index 8c981fb..e3d0812 100644 --- a/vis.h +++ b/vis.h @@ -86,6 +86,11 @@ void vis_suspend(Vis*); * in another window, share the underlying text that is changes will be * visible in both windows */ bool vis_window_new(Vis*, const char *filename); +/* Creates a new window and underlying file object associated with the + * given output file descriptor. No data is read from `fd`, but write + * commands without an explicit filename will instead write to the file + * descriptor */ +bool vis_window_new_fd(Vis*, int fd); /* reload the file currently displayed in the window from disk */ bool vis_window_reload(Win*); /* check whether closing the window would loose unsaved changes */ -- cgit v1.2.3