void mcview_close_datasource (WView * view) { switch (view->datasource) { case DS_NONE: break; case DS_STDIO_PIPE: if (view->ds_stdio_pipe != NULL) { mcview_growbuf_done (view); mcview_display (view); } mcview_growbuf_free (view); break; case DS_VFS_PIPE: if (view->ds_vfs_pipe != -1) mcview_growbuf_done (view); mcview_growbuf_free (view); break; case DS_FILE: (void) mc_close (view->ds_file_fd); view->ds_file_fd = -1; MC_PTR_FREE (view->ds_file_data); break; case DS_STRING: MC_PTR_FREE (view->ds_string_data); break; default: #ifdef HAVE_ASSERT_H assert (!"Unknown datasource type") #endif ; } view->datasource = DS_NONE; }
void mcview_growbuf_read_until (WView * view, off_t ofs) { gboolean short_read = FALSE; #ifdef HAVE_ASSERT_H assert (view->growbuf_in_use); #endif if (view->growbuf_finished) return; while (mcview_growbuf_filesize (view) < ofs || short_read) { ssize_t nread = 0; byte *p; size_t bytesfree; if (view->growbuf_lastindex == VIEW_PAGE_SIZE) { /* Append a new block to the growing buffer */ byte *newblock = g_try_malloc (VIEW_PAGE_SIZE); if (newblock == NULL) return; g_ptr_array_add (view->growbuf_blockptr, newblock); view->growbuf_lastindex = 0; } p = (byte *) g_ptr_array_index (view->growbuf_blockptr, view->growbuf_blockptr->len - 1) + view->growbuf_lastindex; bytesfree = VIEW_PAGE_SIZE - view->growbuf_lastindex; if (view->datasource == DS_STDIO_PIPE) { mc_pipe_t *sp = view->ds_stdio_pipe; GError *error = NULL; if (bytesfree > MC_PIPE_BUFSIZE) bytesfree = MC_PIPE_BUFSIZE; sp->out.len = bytesfree; sp->err.len = MC_PIPE_BUFSIZE; mc_pread (sp, &error); if (error != NULL) { mcview_show_error (view, error->message); g_error_free (error); mcview_growbuf_done (view); return; } if (view->pipe_first_err_msg && sp->err.len > 0) { /* ignore possible following errors */ /* reset this flag before call of mcview_show_error() to break * endless recursion: mcview_growbuf_read_until() -> mcview_show_error() -> * MSG_DRAW -> mcview_display() -> mcview_get_byte() -> mcview_growbuf_read_until() */ view->pipe_first_err_msg = FALSE; mcview_show_error (view, sp->err.buf); } if (sp->out.len > 0) { memmove (p, sp->out.buf, sp->out.len); nread = sp->out.len; } else if (sp->out.len == MC_PIPE_STREAM_EOF || sp->out.len == MC_PIPE_ERROR_READ) { if (sp->out.len == MC_PIPE_ERROR_READ) { char *err_msg; err_msg = g_strdup_printf (_("Failed to read data from child stdout:\n%s"), unix_error_string (sp->out.error)); mcview_show_error (view, err_msg); g_free (err_msg); } if (view->ds_stdio_pipe != NULL) { /* when switch from parse to raw mode and back, * do not close the already closed pipe after following loop: * mcview_growbuf_read_until() -> mcview_show_error() -> * MSG_DRAW -> mcview_display() -> mcview_get_byte() -> mcview_growbuf_read_until() */ mcview_growbuf_done (view); } mcview_display (view); return; } } else { #ifdef HAVE_ASSERT_H assert (view->datasource == DS_VFS_PIPE); #endif do { nread = mc_read (view->ds_vfs_pipe, p, bytesfree); } while (nread == -1 && errno == EINTR); if (nread <= 0) { mcview_growbuf_done (view); return; } } short_read = ((size_t) nread < bytesfree); view->growbuf_lastindex += nread; } }