(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; int fd;
/* data read from fd */ /* data read from fd */
char buf[MC_PIPE_BUFSIZE]; char buf[MC_PIPE_BUFSIZE];
/* positive: length of data in buf as before read as after; /* positive: length of data in buf;
* zero or negative before read: do not read drom fd; * MC_PIPE_STREAM_EOF: EOF of fd;
* MC_PIPE_STREAM_EOF after read: EOF of fd; * MC_PIPE_STREAM_UNREAD: there was not read from fd;
* MC_PIPE_STREAM_UNREAD after read: there was not read from fd; * MC_PIPE_ERROR_READ: reading error from fd.
* MC_PIPE_ERROR_READ after read: reading error from fd.
*/ */
ssize_t len; ssize_t len;
/* whether buf is null-terminated or not */ /* 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 (const char *command, char *const argv[]);
int my_systemv_flags (int flags, 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_pread (mc_pipe_t * p, GError ** error);
void mc_pclose (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. * Create pipe and run child process.
* *
* @parameter command command line of 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 * @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 * @return newly created object of mc_pipe_t class in success, NULL otherwise
*/ */
mc_pipe_t * 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; mc_pipe_t *p;
const char *const argv[] = { "/bin/sh", "sh", "-c", command, NULL }; const char *const argv[] = { "/bin/sh", "sh", "-c", command, NULL };
@ -522,9 +524,13 @@ mc_popen (const char *command, GError ** error)
goto ret_err; goto ret_err;
} }
p->out.fd = -1;
p->err.fd = -1;
if (!g_spawn_async_with_pipes if (!g_spawn_async_with_pipes
(NULL, (gchar **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_FILE_AND_ARGV_ZERO, (NULL, (gchar **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_FILE_AND_ARGV_ZERO, NULL,
NULL, NULL, &p->child_pid, NULL, &p->out.fd, &p->err.fd, error)) 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", mc_replace_error (error, MC_PIPE_ERROR_CREATE_PIPE_STREAM, "%s",
_("Cannot create pipe streams")); _("Cannot create pipe streams"));
@ -553,9 +559,9 @@ mc_popen (const char *command, GError ** error)
* @parameter p pipe descriptor * @parameter p pipe descriptor
* *
* The lengths of read data contain in p->out.len and p->err.len. * 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; * Before read, p->xxx.len is an input. It defines the number of data to read.
* p->xxx.len <= 0: do not read stream p->xxx. * Should not be greater than MC_PIPE_BUFSIZE.
* *
* After read, p->xxx.len is an output and contains the following: * 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; * 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) if (error != NULL)
*error = NULL; *error = NULL;
read_out = p->out.fd >= 0 && p->out.len > 0; read_out = p->out.fd >= 0;
read_err = p->err.fd >= 0 && p->err.len > 0; read_err = p->err.fd >= 0;
if (!read_out && !read_err) 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') if (clipboard_paste_path == NULL || clipboard_paste_path[0] == '\0')
return TRUE; return TRUE;
p = mc_popen (clipboard_paste_path, NULL); p = mc_popen (clipboard_paste_path, TRUE, TRUE, NULL);
if (p == NULL) if (p == NULL)
return TRUE; /* don't show error message */ 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); mcview_close_datasource (view);
p = mc_popen (command, &error); p = mc_popen (command, TRUE, TRUE, &error);
if (p == NULL) if (p == NULL)
{ {
mcview_display (view); mcview_display (view);