convenience functions for g_spawn_async() that return stdout/stderr output of child
@tpm
Submitted by Tim-Philipp Müller Link to original bug (#142591)
Description
It would be nice to have some convenience functions for g_spawn_async() that provide something similar to g_spawn_command_line_sync() while at the same time not blocking the Gtk main loop.
I think the case where one wants to spawn an external helper program from a Gtk/Gnome application and process its stdout/stderr output is common enough to have this functionality in glib.
Using g_spawn_async() and setting up GIOChannels for the stdin/stderr file descriptors is a somewhat repetitive task for which GLib should provide convenience functions IMHO.
Here's the API I'm using in my own helper functions, to show what I have in mind:
typedef struct _ScSpawnAsync ScSpawnAsync;
typedef void (*ScSpawnAsyncLineFunc) (ScSpawnAsync *spasync, const gchar *line, gpointer user_data);
ScSpawnAsync * sc_spawn_async (gchar **argv, gchar **p_stdout, gchar **p_stderr, GError **error);
ScSpawnAsync * sc_spawn_async_with_args (gchar **p_stdout, gchar **p_stderr, GError **error, const gchar *argv0, ... );
void
sc_spawn_async_run (ScSpawnAsync *spasync);
void
sc_spawn_async_cancel (ScSpawnAsync *spasync,
gboolean terminate);
void
sc_spawn_async_free (ScSpawnAsync *spasync);
void
sc_spawn_async_set_stdout_line_func (ScSpawnAsync *spasync,
ScSpawnAsyncLineFunc line_func,
gpointer user_data);
void
sc_spawn_async_set_stderr_line_func (ScSpawnAsync *spasync,
ScSpawnAsyncLineFunc line_func,
gpointer user_data);
GPid
sc_spawn_async_get_pid (ScSpawnAsync *spasync);
So in the simplest case one would do:
ScSpawnAsync *spasync; GError *err = NULL; gchar *sout = NULL, *serr = NULL;
spasync = sc_spawn_async_with_args (&sout, &serr, &err, "find", "/home/joe", "-name", "'*.mp3'", NULL);
if (!spasync) g_error ("spawn_async_with_args failed: %s\n", err->message);
sc_spawn_async_run (spasync);
g_print ("stdout:\n%s\n\n\nstderr:\n%s\n\n", sout, serr);
sc_spawn_async_free (spasync);
g_free (sout); g_free (serr);
(When a line function is set, the callback function is called whenever a full line of output has been received, e.g. for GUI status/progress messages).
Cheers -Tim