Exemplo n.º 1
0
gboolean
mcview_load_command_output (WView * view, const char *command)
{
    mc_pipe_t *p;
    GError *error = NULL;

    mcview_close_datasource (view);

    p = mc_popen (command, &error);
    if (p == NULL)
    {
        mcview_display (view);
        mcview_show_error (view, error->message);
        g_error_free (error);
        return FALSE;
    }

    /* Check if filter produced any output */
    mcview_set_datasource_stdio_pipe (view, p);
    if (!mcview_get_byte (view, 0, NULL))
    {
        mcview_close_datasource (view);
        mcview_display (view);
        return FALSE;
    }

    return TRUE;
}
Exemplo n.º 2
0
gboolean
mcview_load_command_output (mcview_t * view, const char *command)
{
    FILE *fp;

    mcview_close_datasource (view);

    open_error_pipe ();
    fp = popen (command, "r");
    if (fp == NULL)
    {
        /* Avoid two messages.  Message from stderr has priority.  */
        mcview_display (view);
        if (!close_error_pipe (mcview_is_in_panel (view) ? -1 : D_ERROR, NULL))
            mcview_show_error (view, _("Cannot spawn child process"));
        return FALSE;
    }

    /* First, check if filter produced any output */
    mcview_set_datasource_stdio_pipe (view, fp);
    if (!mcview_get_byte (view, 0, NULL))
    {
        mcview_close_datasource (view);

        /* Avoid two messages.  Message from stderr has priority.  */
        mcview_display (view);
        if (!close_error_pipe (mcview_is_in_panel (view) ? -1 : D_ERROR, NULL))
            mcview_show_error (view, _("Empty output from child filter"));
        return FALSE;
    }
    else
    {
        /*
         * At least something was read correctly. Close stderr and let
         * program die if it will try to write something there.
         *
         * Ideally stderr should be read asynchronously to prevent programs
         * from blocking (poll/select multiplexor).
         */
        close_error_pipe (D_NORMAL, NULL);
    }
    return TRUE;
}
Exemplo n.º 3
0
gboolean
mcview_load (mcview_t * view, const char *command, const char *file, int start_line)
{
    gboolean retval = FALSE;
    vfs_path_t *vpath = NULL;

#ifdef HAVE_ASSERT_H
    assert (view->bytes_per_line != 0);
#endif

    view->filename_vpath = 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))
        {
            vfs_path_t *p;

            p = vfs_path_clone (vfs_get_raw_current_dir ());
            view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL);
            vfs_path_free (p);
        }
        else
        {
            /* try extract path form filename */
            const char *fname;
            char *dir;

            fname = x_basename (file);
            dir = g_strndup (file, (size_t) (fname - file));
            view->workdir_vpath = vfs_path_from_str (dir);
            g_free (dir);
        }
    }

    if (!mcview_is_in_panel (view))
        view->dpy_text_column = 0;

    mcview_set_codeset (view);

    if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0'))
        retval = mcview_load_command_output (view, command);
    else if (file != NULL && file[0] != '\0')
    {
        int fd;
        char tmp[BUF_MEDIUM];
        struct stat st;

        /* Open the file */
        vpath = vfs_path_from_str (file);
        fd = mc_open (vpath, O_RDONLY | O_NONBLOCK);
        if (fd == -1)
        {
            g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        /* Make sure we are working with a regular file */
        if (mc_fstat (fd, &st) == -1)
        {
            mc_close (fd);
            g_snprintf (tmp, sizeof (tmp), _("Cannot stat \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (!S_ISREG (st.st_mode))
        {
            mc_close (fd);
            mcview_show_error (view, _("Cannot view: not a regular file"));
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1)
        {
            /* Must be one of those nice files that grow (/proc) */
            mcview_set_datasource_vfs_pipe (view, fd);
        }
        else
        {
            int type;

            type = get_compression_type (fd, file);

            if (view->magic_mode && (type != COMPRESSION_NONE))
            {
                char *tmp_filename;
                vfs_path_t *vpath1;
                int fd1;

                tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
                vpath1 = vfs_path_from_str (tmp_filename);
                fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK);
                if (fd1 == -1)
                {
                    g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\" in parse mode\n%s"),
                                file, unix_error_string (errno));
                    mcview_show_error (view, tmp);
                }
                else
                {
                    mc_close (fd);
                    fd = fd1;
                    mc_fstat (fd, &st);
                }
                vfs_path_free (vpath1);

                g_free (tmp_filename);
            }
            mcview_set_datasource_file (view, fd, &st);
        }
        retval = TRUE;
    }

  finish:
    view->command = g_strdup (command);
    view->dpy_start = 0;
    view->search_start = 0;
    view->search_end = 0;
    view->dpy_text_column = 0;

    mcview_compute_areas (view);
    mcview_update_bytes_per_line (view);

    if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0)
    {
        long line, col;
        off_t new_offset, max_offset;

        load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks);
        max_offset = mcview_get_filesize (view) - 1;
        if (max_offset < 0)
            new_offset = 0;
        else
            new_offset = min (new_offset, max_offset);
        if (!view->hex_mode)
            view->dpy_start = mcview_bol (view, new_offset, 0);
        else
        {
            view->dpy_start = new_offset - new_offset % view->bytes_per_line;
            view->hex_cursor = new_offset;
        }
    }
    else if (start_line > 0)
        mcview_moveto (view, start_line - 1, 0);

    view->hexedit_lownibble = FALSE;
    view->hexview_in_text = FALSE;
    view->change_list = NULL;
    vfs_path_free (vpath);
    return retval;
}
Exemplo n.º 4
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;
    }
}