(mc_popen): add two parameters:

do or don't read stdout of child process;
do or don't read stderr of child process.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2021-02-24 14:10:52 +03:00
parent 68556db80d
commit 1e45efecb2
4 changed files with 21 additions and 16 deletions

View File

@ -87,11 +87,10 @@ typedef struct
int fd;
/* data read from fd */
char buf[MC_PIPE_BUFSIZE];
/* positive: length of data in buf as before read as after;
* zero or negative before read: do not read drom fd;
* MC_PIPE_STREAM_EOF after read: EOF of fd;
* MC_PIPE_STREAM_UNREAD after read: there was not read from fd;
* MC_PIPE_ERROR_READ after read: reading error from fd.
/* positive: length of data in buf;
* MC_PIPE_STREAM_EOF: EOF of fd;
* MC_PIPE_STREAM_UNREAD: there was not read from fd;
* MC_PIPE_ERROR_READ: reading error from fd.
*/
ssize_t len;
/* whether buf is null-terminated or not */
@ -218,7 +217,7 @@ int my_systeml (int flags, const char *shell, ...);
int my_systemv (const char *command, char *const argv[]);
int my_systemv_flags (int flags, const char *command, char *const argv[]);
mc_pipe_t *mc_popen (const char *command, GError ** error);
mc_pipe_t *mc_popen (const char *command, gboolean read_out, gboolean read_err, GError ** error);
void mc_pread (mc_pipe_t * p, GError ** error);
void mc_pclose (mc_pipe_t * p, GError ** error);

View File

@ -503,13 +503,15 @@ my_systemv_flags (int flags, const char *command, char *const argv[])
* Create pipe and run child process.
*
* @parameter command command line of child process
* @parameter read_out do or don't read the stdout of child process
* @parameter read_err do or don't read the stderr of child process
* @paremeter error contains pointer to object to handle error code and message
*
* @return newly created object of mc_pipe_t class in success, NULL otherwise
*/
mc_pipe_t *
mc_popen (const char *command, GError ** error)
mc_popen (const char *command, gboolean read_out, gboolean read_err, GError ** error)
{
mc_pipe_t *p;
const char *const argv[] = { "/bin/sh", "sh", "-c", command, NULL };
@ -522,9 +524,13 @@ mc_popen (const char *command, GError ** error)
goto ret_err;
}
p->out.fd = -1;
p->err.fd = -1;
if (!g_spawn_async_with_pipes
(NULL, (gchar **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_FILE_AND_ARGV_ZERO,
NULL, NULL, &p->child_pid, NULL, &p->out.fd, &p->err.fd, error))
(NULL, (gchar **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_FILE_AND_ARGV_ZERO, NULL,
NULL, &p->child_pid, NULL, read_out ? &p->out.fd : NULL, read_err ? &p->err.fd : NULL,
error))
{
mc_replace_error (error, MC_PIPE_ERROR_CREATE_PIPE_STREAM, "%s",
_("Cannot create pipe streams"));
@ -553,9 +559,9 @@ mc_popen (const char *command, GError ** error)
* @parameter p pipe descriptor
*
* The lengths of read data contain in p->out.len and p->err.len.
* Before read, p->xxx.len is an input:
* p->xxx.len > 0: do read stream p->xxx and store data in p->xxx.buf;
* p->xxx.len <= 0: do not read stream p->xxx.
*
* Before read, p->xxx.len is an input. It defines the number of data to read.
* Should not be greater than MC_PIPE_BUFSIZE.
*
* After read, p->xxx.len is an output and contains the following:
* p->xxx.len > 0: an actual length of read data stored in p->xxx.buf;
@ -577,8 +583,8 @@ mc_pread (mc_pipe_t * p, GError ** error)
if (error != NULL)
*error = NULL;
read_out = p->out.fd >= 0 && p->out.len > 0;
read_err = p->err.fd >= 0 && p->err.len > 0;
read_out = p->out.fd >= 0;
read_err = p->err.fd >= 0;
if (!read_out && !read_err)
{

View File

@ -109,7 +109,7 @@ clipboard_file_from_ext_clip (const gchar * event_group_name, const gchar * even
if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
return TRUE;
p = mc_popen (clipboard_paste_path, NULL);
p = mc_popen (clipboard_paste_path, TRUE, TRUE, NULL);
if (p == NULL)
return TRUE; /* don't show error message */

View File

@ -385,7 +385,7 @@ mcview_load_command_output (WView * view, const char *command)
mcview_close_datasource (view);
p = mc_popen (command, &error);
p = mc_popen (command, TRUE, TRUE, &error);
if (p == NULL)
{
mcview_display (view);