From cc178ff64f5fb9a514dc37b97c87ccba95af47e0 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 7 Jan 2018 18:38:03 +0300 Subject: [PATCH] NOT FINISHED: mcviewer: implement reading from stdin. Thanks and Emil Biserov for the original patch. Signed-off-by: Andrew Borodin --- src/args.c | 4 ++++ src/filemanager/midnight.c | 20 ++++++++++++++++---- src/viewer/display.c | 10 +++++++--- src/viewer/growbuf.c | 14 ++++++++++++-- src/viewer/lib.c | 4 ++++ src/viewer/mcviewer.c | 22 ++++++++++++++++------ 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/args.c b/src/args.c index a9c71a09c..c93805b06 100644 --- a/src/args.c +++ b/src/args.c @@ -814,6 +814,10 @@ mc_setup_by_args (int argc, char **argv, GError ** mcerror) break; case MC_RUN_VIEWER: + /* If fd0 is non-interactive, a file is being piped */ + if (isatty (fileno (stdin)) == 0) + tmp = "-"; + if (tmp == NULL) { mc_propagate_error (mcerror, 0, "%s\n", _("No arguments given to the viewer.")); diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 01d196eea..4b4c715ee 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -81,6 +81,8 @@ #include "src/editor/edit.h" #endif +#include "src/viewer/mcviewer.h" /* mcview_viewer() */ + #ifdef USE_DIFF_VIEW #include "src/diffviewer/ydiff.h" #endif @@ -993,11 +995,21 @@ mc_maybe_editor_or_viewer (void) { vfs_path_t *vpath = NULL; - if (mc_run_param0 != NULL && *(char *) mc_run_param0 != '\0') - vpath = prepend_cwd_on_local ((char *) mc_run_param0); + if (mc_run_param0 != NULL) + { + char *filename = (char *) mc_run_param0; - ret = view_file (vpath, FALSE, TRUE); - vfs_path_free (vpath); + if (filename[0] == '-' && filename[1] == '\0') + ret = mcview_viewer (NULL, VFS_PATH_STDIN, 0, 0, 0); + else + { + if (filename[0] != '\0') + vpath = prepend_cwd_on_local (filename); + + ret = view_file (vpath, FALSE, TRUE); + vfs_path_free (vpath); + } + } break; } #ifdef USE_DIFF_VIEW diff --git a/src/viewer/display.c b/src/viewer/display.c index 12e59deea..fcb2ebab2 100644 --- a/src/viewer/display.c +++ b/src/viewer/display.c @@ -108,8 +108,12 @@ mcview_set_buttonbar (WView * view) } buttonbar_set_label (b, 5, Q_ ("ButtonBar|Goto"), keymap, WIDGET (view)); - buttonbar_set_label (b, 8, view->magic_mode ? Q_ ("ButtonBar|Raw") - : Q_ ("ButtonBar|Parse"), keymap, WIDGET (view)); + + if (view->filename_vpath == VFS_PATH_STDIN) + buttonbar_set_label (b, 8, NULL, NULL, NULL); + else + buttonbar_set_label (b, 8, view->magic_mode ? Q_ ("ButtonBar|Raw") + : Q_ ("ButtonBar|Parse"), keymap, WIDGET (view)); if (!mcview_is_in_panel (view)) /* don't override some panel buttonbar keys */ { @@ -158,7 +162,7 @@ mcview_display_status (WView * view) tty_draw_hline (WIDGET (view)->y + top, WIDGET (view)->x + left, ' ', width); file_label = - view->filename_vpath != NULL ? + view->filename_vpath == VFS_PATH_STDIN ? _("") : view->filename_vpath != NULL ? vfs_path_get_last_path_str (view->filename_vpath) : view->command != NULL ? view->command : ""; diff --git a/src/viewer/growbuf.c b/src/viewer/growbuf.c index c1172b6d6..2d6d0155c 100644 --- a/src/viewer/growbuf.c +++ b/src/viewer/growbuf.c @@ -84,7 +84,10 @@ mcview_growbuf_done (WView * view) } else /* view->datasource == DS_VFS_PIPE */ { - (void) mc_close (view->ds_vfs_pipe); + if (view->filename_vpath == VFS_PATH_STDIN) + (void) close (view->ds_vfs_pipe); + else + (void) mc_close (view->ds_vfs_pipe); view->ds_vfs_pipe = -1; } } @@ -221,9 +224,15 @@ mcview_growbuf_read_until (WView * view, off_t ofs) else { g_assert (view->datasource == DS_VFS_PIPE); + do { - nread = mc_read (view->ds_vfs_pipe, p, bytesfree); + if (view->filename_vpath == VFS_PATH_STDIN) + /* NOT FINISHED: in case if 'mcview -' (i.e. w/o pipe at stdin, + implement correct finish of this loop (ctrl-c, ctrl-d, something else) */ + nread = read (view->ds_vfs_pipe, p, bytesfree); + else + nread = mc_read (view->ds_vfs_pipe, p, bytesfree); } while (nread == -1 && errno == EINTR); @@ -233,6 +242,7 @@ mcview_growbuf_read_until (WView * view, off_t ofs) return; } } + short_read = ((size_t) nread < bytesfree); view->growbuf_lastindex += nread; } diff --git a/src/viewer/lib.c b/src/viewer/lib.c index b623b8a65..a628dce92 100644 --- a/src/viewer/lib.c +++ b/src/viewer/lib.c @@ -74,6 +74,10 @@ mcview_toggle_magic_mode (WView * view) dir_list *dir; int *dir_idx; + /* stdin can't be "re-opened" and we can't do magic toggle without reopen, yet */ + if (view->filename_vpath == VFS_PATH_STDIN) + return; + mcview_altered_magic_flag = 1; view->magic_mode = !view->magic_mode; diff --git a/src/viewer/mcviewer.c b/src/viewer/mcviewer.c index 111fafb27..20642cdc9 100644 --- a/src/viewer/mcviewer.c +++ b/src/viewer/mcviewer.c @@ -14,7 +14,7 @@ Pavel Machek, 1998 Roland Illig , 2004, 2005 Slava Zanko , 2009, 2013 - Andrew Borodin , 2009, 2013 + Andrew Borodin , 2009, 2013, 2018 Ilia Maslakov , 2009 This file is part of the Midnight Commander. @@ -232,6 +232,7 @@ mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_lin gboolean succeeded; WView *lc_mcview; WDialog *view_dlg; + const char *filename; /* Create dialog and widgets, put them on the dialog */ view_dlg = dlg_create (FALSE, 0, 0, 1, 1, WPOS_FULLSCREEN, FALSE, NULL, mcview_dialog_callback, @@ -245,9 +246,8 @@ mcview_viewer (const char *command, const vfs_path_t * file_vpath, int start_lin view_dlg->get_title = mcview_get_title; - succeeded = - mcview_load (lc_mcview, command, vfs_path_as_str (file_vpath), start_line, search_start, - search_end); + filename = (file_vpath == VFS_PATH_STDIN ? "-" : vfs_path_as_str (file_vpath)); + succeeded = mcview_load (lc_mcview, command, filename, start_line, search_start, search_end); if (succeeded) dlg_run (view_dlg); @@ -270,17 +270,20 @@ mcview_load (WView * view, const char *command, const char *file, int start_line { gboolean retval = FALSE; vfs_path_t *vpath = NULL; + gboolean from_stdin = (file != NULL && file[0] == '-' && file[1] == '\0'); g_assert (view->bytes_per_line != 0); - view->filename_vpath = vfs_path_from_str (file); + view->filename_vpath = from_stdin ? VFS_PATH_STDIN : vfs_path_from_str (file); /* get working dir */ if (file != NULL && file[0] != '\0') { vfs_path_free (view->workdir_vpath); - if (!g_path_is_absolute (file)) + if (from_stdin) + view->workdir_vpath = vfs_path_clone (vfs_get_raw_current_dir ()); + else if (!g_path_is_absolute (file)) { vfs_path_t *p; @@ -314,6 +317,13 @@ mcview_load (WView * view, const char *command, const char *file, int start_line char tmp[BUF_MEDIUM]; struct stat st; + if (from_stdin) + { + mcview_set_datasource_vfs_pipe (view, fileno (stdin)); + retval = TRUE; + goto finish; + } + /* Open the file */ vpath = vfs_path_from_str (file); fd = mc_open (vpath, O_RDONLY | O_NONBLOCK);