From fea6b2891cee24071b3d75805734c9e1a64517c5 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Tue, 9 Jul 2024 17:11:56 +0200 Subject: [PATCH] xdp-utils: Make xdp_spawn() fit better our use cases There aren't many places where we need to spawn a subprocess but in all cases we have a list of commend args and need the output as a response. Make `xdp_spawn()` and `xdp_spawnv()` nicer to use and only take arguments that are actually used. --- document-portal/document-portal.c | 27 ++--------- src/xdp-app-info.c | 5 +- src/xdp-utils.c | 76 ++++++++++++------------------- src/xdp-utils.h | 14 ++---- 4 files changed, 39 insertions(+), 83 deletions(-) diff --git a/document-portal/document-portal.c b/document-portal/document-portal.c index 853394a7e..ed939f6bd 100644 --- a/document-portal/document-portal.c +++ b/document-portal/document-portal.c @@ -522,27 +522,6 @@ portal_add (GDBusMethodInvocation *invocation, g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", ids[0])); } -static char * -get_output (GError **error, - const char *argv0, - ...) -{ - gboolean res; - g_autofree char *output = NULL; - va_list ap; - - va_start (ap, argv0); - res = xdp_spawn (NULL, &output, 0, error, argv0, ap); - va_end (ap); - - if (res) - { - g_strchomp (output); - return g_steal_pointer (&output); - } - return NULL; -} - /* out => 0 == hidden 1 == read-only @@ -659,16 +638,18 @@ app_has_file_access (const char *target_app_id, if (g_str_has_prefix (target_app_id, "snap.")) { - res = get_output (&error, "snap", "routine", "file-access", + res = xdp_spawn (&error, "snap", "routine", "file-access", target_app_id + strlen ("snap."), path, NULL); } else { /* First we try flatpak info --file-access=PATH APPID, which is supported on new versions */ arg = g_strdup_printf ("--file-access=%s", path); - res = get_output (&error, "flatpak", "info", arg, target_app_id, NULL); + res = xdp_spawn (&error, "flatpak", "info", arg, target_app_id, NULL); } + g_strchomp (res); + if (res) { if (strcmp (res, "read-write") == 0) diff --git a/src/xdp-app-info.c b/src/xdp-app-info.c index 02b1fefc5..d5caa6dfe 100644 --- a/src/xdp-app-info.c +++ b/src/xdp-app-info.c @@ -1765,7 +1765,6 @@ xdp_app_info_from_snap (int pid, { g_autoptr(GError) local_error = NULL; g_autofree char *pid_str = NULL; - const char *argv[] = { "snap", "routine", "portal-info", NULL, NULL }; g_autofree char *output = NULL; g_autoptr(GKeyFile) metadata = NULL; g_autoptr(XdpAppInfo) app_info = NULL; @@ -1779,8 +1778,8 @@ xdp_app_info_from_snap (int pid, } pid_str = g_strdup_printf ("%u", (guint) pid); - argv[3] = pid_str; - if (!xdp_spawnv (NULL, &output, 0, error, argv)) + output = xdp_spawn (error, "snap", "routine", "portal-info", pid_str, NULL); + if (output == NULL) { return FALSE; } diff --git a/src/xdp-utils.c b/src/xdp-utils.c index a5c421363..8b335561b 100644 --- a/src/xdp-utils.c +++ b/src/xdp-utils.c @@ -414,37 +414,34 @@ spawn_exit_cb (GObject *obj, spawn_data_exit (data); } -gboolean -xdp_spawn (GFile *dir, - char **output, - GSubprocessFlags flags, - GError **error, +gchar * +xdp_spawn (GError **error, const gchar *argv0, - va_list ap) + ...) { GPtrArray *args; const gchar *arg; - gboolean res; + va_list ap; + char *output; + va_start (ap, argv0); args = g_ptr_array_new (); g_ptr_array_add (args, (gchar *) argv0); while ((arg = va_arg (ap, const gchar *))) g_ptr_array_add (args, (gchar *) arg); g_ptr_array_add (args, NULL); + va_end (ap); - res = xdp_spawnv (dir, output, flags, error, (const gchar * const *) args->pdata); + output = xdp_spawnv ((const gchar * const *) args->pdata, error); g_ptr_array_free (args, TRUE); - return res; + return output; } -gboolean -xdp_spawnv (GFile *dir, - char **output, - GSubprocessFlags flags, - GError **error, - const gchar * const *argv) +gchar * +xdp_spawnv (const gchar * const *argv, + GError **error) { g_autoptr(GSubprocessLauncher) launcher = NULL; g_autoptr(GSubprocess) subp = NULL; @@ -454,18 +451,7 @@ xdp_spawnv (GFile *dir, SpawnData data = {0}; g_autofree gchar *commandline = NULL; - launcher = g_subprocess_launcher_new (0); - - if (output) - flags |= G_SUBPROCESS_FLAGS_STDOUT_PIPE; - - g_subprocess_launcher_set_flags (launcher, flags); - - if (dir) - { - g_autofree char *path = g_file_get_path (dir); - g_subprocess_launcher_set_cwd (launcher, path); - } + launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); commandline = xdp_quote_argv ((const char **)argv); g_debug ("Running: %s", commandline); @@ -473,26 +459,22 @@ xdp_spawnv (GFile *dir, subp = g_subprocess_launcher_spawnv (launcher, argv, error); if (subp == NULL) - return FALSE; + return NULL; loop = g_main_loop_new (NULL, FALSE); data.loop = loop; - data.refs = 1; - - if (output) - { - data.refs++; - in = g_subprocess_get_stdout_pipe (subp); - out = g_memory_output_stream_new_resizable (); - g_output_stream_splice_async (out, - in, - G_OUTPUT_STREAM_SPLICE_NONE, - 0, - NULL, - spawn_output_spliced_cb, - &data); - } + data.refs = 2; + + in = g_subprocess_get_stdout_pipe (subp); + out = g_memory_output_stream_new_resizable (); + g_output_stream_splice_async (out, + in, + G_OUTPUT_STREAM_SPLICE_NONE, + 0, + NULL, + spawn_output_spliced_cb, + &data); g_subprocess_wait_async (subp, NULL, spawn_exit_cb, &data); @@ -502,7 +484,7 @@ xdp_spawnv (GFile *dir, { g_propagate_error (error, data.error); g_clear_error (&data.splice_error); - return FALSE; + return NULL; } if (out) @@ -510,16 +492,16 @@ xdp_spawnv (GFile *dir, if (data.splice_error) { g_propagate_error (error, data.splice_error); - return FALSE; + return NULL; } /* Null terminate */ g_output_stream_write (out, "\0", 1, NULL, NULL); g_output_stream_close (out, NULL, NULL); - *output = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); + return g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out)); } - return TRUE; + return NULL; } char * diff --git a/src/xdp-utils.h b/src/xdp-utils.h index 0a801c7d5..85c72a23a 100644 --- a/src/xdp-utils.h +++ b/src/xdp-utils.h @@ -122,17 +122,11 @@ xdp_close_fd (int *fdp) char * xdp_quote_argv (const char *argv[]); -gboolean xdp_spawn (GFile *dir, - char **output, - GSubprocessFlags flags, - GError **error, +char * xdp_spawn (GError **error, const gchar *argv0, - va_list ap); -gboolean xdp_spawnv (GFile *dir, - char **output, - GSubprocessFlags flags, - GError **error, - const gchar * const *argv); + ...) G_GNUC_NULL_TERMINATED; +char * xdp_spawnv (const gchar * const *argv, + GError **error); char * xdp_canonicalize_filename (const char *path); gboolean xdp_has_path_prefix (const char *str,