Пример #1
0
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;
}
Пример #2
0
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;
    }
}