From 03ae229751cb7159f5d55571285538523cdfa155 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Mon, 7 Dec 2015 12:27:53 +0100 Subject: [PATCH] Move most of builtins-run to xdg_app_run_app helper This is in preparation for letting the library start apps. --- app/xdg-app-builtins-run.c | 272 ++------------------------------- common/xdg-app-dir.h | 1 + common/xdg-app-run.c | 304 +++++++++++++++++++++++++++++++++++++ common/xdg-app-run.h | 17 +++ 4 files changed, 331 insertions(+), 263 deletions(-) diff --git a/app/xdg-app-builtins-run.c b/app/xdg-app-builtins-run.c index 3f18d7dd..e65eedd0 100644 --- a/app/xdg-app-builtins-run.c +++ b/app/xdg-app-builtins-run.c @@ -50,50 +50,17 @@ static GOptionEntry options[] = { { NULL } }; -static void -dbus_spawn_child_setup (gpointer user_data) -{ - int fd = GPOINTER_TO_INT (user_data); - fcntl (fd, F_SETFD, 0); -} - gboolean xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **error) { g_autoptr(GOptionContext) context = NULL; g_autoptr(XdgAppDeploy) app_deploy = NULL; - g_autoptr(XdgAppDeploy) runtime_deploy = NULL; - g_autoptr(GFile) app_files = NULL; - g_autoptr(GFile) runtime_files = NULL; - g_autoptr(GFile) app_id_dir = NULL; - g_autoptr(GFile) app_cache_dir = NULL; - g_autoptr(GFile) app_data_dir = NULL; - g_autoptr(GFile) app_config_dir = NULL; - g_autoptr(GFile) home = NULL; - g_autoptr(GFile) user_font1 = NULL; - g_autoptr(GFile) user_font2 = NULL; - g_autoptr(XdgAppSessionHelper) session_helper = NULL; - g_autofree char *runtime = NULL; - g_autofree char *default_command = NULL; - g_autofree char *runtime_ref = NULL; g_autofree char *app_ref = NULL; - g_autofree char *doc_mount_path = NULL; - g_autoptr(GKeyFile) metakey = NULL; - g_autoptr(GKeyFile) runtime_metakey = NULL; - g_autoptr(GPtrArray) argv_array = NULL; - g_auto(GStrv) envp = NULL; - g_autoptr(GPtrArray) dbus_proxy_argv = NULL; - g_autofree char *monitor_path = NULL; const char *app; const char *branch = "master"; - const char *command = "/bin/sh"; int i; int rest_argv_start, rest_argc; - int sync_proxy_pipes[2]; g_autoptr(XdgAppContext) arg_context = NULL; - g_autoptr(XdgAppContext) app_context = NULL; - g_autoptr(XdgAppContext) overrides = NULL; - g_autoptr(GDBusConnection) session_bus = NULL; context = g_option_context_new ("APP [args...] - Run an app"); @@ -136,238 +103,17 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** if (app_deploy == NULL) return FALSE; - metakey = xdg_app_deploy_get_metadata (app_deploy); - - argv_array = g_ptr_array_new_with_free_func (g_free); - dbus_proxy_argv = g_ptr_array_new_with_free_func (g_free); - g_ptr_array_add (argv_array, g_strdup (HELPER)); - g_ptr_array_add (argv_array, g_strdup ("-l")); - - if (!xdg_app_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error)) + if (!xdg_app_run_app (app_ref, app_deploy, + arg_context, + opt_runtime, + opt_devel ? XDG_APP_RUN_FLAG_DEVEL : 0, + opt_command, + &argv[rest_argv_start + 1], + rest_argc - 1, + cancellable, + error)) return FALSE; - if (opt_runtime) - runtime = opt_runtime; - else - { - runtime = g_key_file_get_string (metakey, "Application", opt_devel ? "sdk" : "runtime", error); - if (*error) - return FALSE; - } - - runtime_ref = g_build_filename ("runtime", runtime, NULL); - - runtime_deploy = xdg_app_find_deploy_for_ref (runtime_ref, cancellable, error); - if (runtime_deploy == NULL) - return FALSE; - - runtime_metakey = xdg_app_deploy_get_metadata (runtime_deploy); - - app_context = xdg_app_context_new (); - xdg_app_context_set_session_bus_policy (app_context, "org.freedesktop.portal.Documents", XDG_APP_POLICY_TALK); - - if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error)) - return FALSE; - if (!xdg_app_context_load_metadata (app_context, metakey, error)) - return FALSE; - - overrides = xdg_app_deploy_get_overrides (app_deploy); - xdg_app_context_merge (app_context, overrides); - - xdg_app_context_merge (app_context, arg_context); - - { - g_autofree char *tmp_path = NULL; - g_autofree char *path = NULL; - int fd; - - fd = g_file_open_tmp ("xdg-app-context-XXXXXX", &tmp_path, NULL); - if (fd >= 0) - { - g_autoptr(GKeyFile) keyfile = NULL; - - close (fd); - - keyfile = g_key_file_new (); - - g_key_file_set_string (keyfile, "Application", "name", app); - g_key_file_set_string (keyfile, "Application", "runtime", runtime_ref); - - xdg_app_context_save_metadata (app_context, keyfile); - - if (!g_key_file_save_to_file (keyfile, tmp_path, error)) - return FALSE; - - g_ptr_array_add (argv_array, g_strdup ("-M")); - g_ptr_array_add (argv_array, g_strdup_printf ("/run/user/%d/xdg-app-info=%s", getuid(), tmp_path)); - } - } - - if (!xdg_app_run_add_extension_args (argv_array, runtime_metakey, runtime_ref, cancellable, error)) - return FALSE; - - if ((app_id_dir = xdg_app_ensure_data_dir (app, cancellable, error)) == NULL) - return FALSE; - - app_cache_dir = g_file_get_child (app_id_dir, "cache"); - g_ptr_array_add (argv_array, g_strdup ("-B")); - g_ptr_array_add (argv_array, g_strdup_printf ("/var/cache=%s", gs_file_get_path_cached (app_cache_dir))); - - app_data_dir = g_file_get_child (app_id_dir, "data"); - g_ptr_array_add (argv_array, g_strdup ("-B")); - g_ptr_array_add (argv_array, g_strdup_printf ("/var/data=%s", gs_file_get_path_cached (app_data_dir))); - - app_config_dir = g_file_get_child (app_id_dir, "config"); - g_ptr_array_add (argv_array, g_strdup ("-B")); - g_ptr_array_add (argv_array, g_strdup_printf ("/var/config=%s", gs_file_get_path_cached (app_config_dir))); - - app_files = xdg_app_deploy_get_files (app_deploy); - runtime_files = xdg_app_deploy_get_files (runtime_deploy); - - default_command = g_key_file_get_string (metakey, "Application", "command", error); - if (*error) - return FALSE; - if (opt_command) - command = opt_command; - else - command = default_command; - - session_helper = xdg_app_session_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - "org.freedesktop.XdgApp", - "/org/freedesktop/XdgApp/SessionHelper", - NULL, NULL); - if (session_helper && - xdg_app_session_helper_call_request_monitor_sync (session_helper, - &monitor_path, - NULL, NULL)) - { - g_ptr_array_add (argv_array, g_strdup ("-m")); - g_ptr_array_add (argv_array, monitor_path); - } - else - g_ptr_array_add (argv_array, g_strdup ("-r")); - - session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - if (session_bus) - { - g_autoptr (GError) local_error = NULL; - g_autoptr (GDBusMessage) reply = NULL; - g_autoptr (GDBusMessage) msg = g_dbus_message_new_method_call ("org.freedesktop.portal.Documents", - "/org/freedesktop/portal/documents", - "org.freedesktop.portal.Documents", - "GetMountPoint"); - g_dbus_message_set_body (msg, g_variant_new ("()")); - reply = g_dbus_connection_send_message_with_reply_sync (session_bus, msg, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, - 30000, - NULL, - NULL, - NULL); - if (reply) - { - if (g_dbus_message_to_gerror (reply, &local_error)) - { - g_warning ("Can't get document portal: %s\n", local_error->message); - } - else - g_variant_get (g_dbus_message_get_body (reply), - "(^ay)", &doc_mount_path); - } - } - - xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv, doc_mount_path, - app, app_context, app_id_dir); - - g_ptr_array_add (argv_array, g_strdup ("-b")); - g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/fonts=%s", SYSTEM_FONTS_DIR)); - - if (opt_devel) - g_ptr_array_add (argv_array, g_strdup ("-c")); - - home = g_file_new_for_path (g_get_home_dir ()); - user_font1 = g_file_resolve_relative_path (home, ".local/share/fonts"); - user_font2 = g_file_resolve_relative_path (home, ".fonts"); - - if (g_file_query_exists (user_font1, NULL)) - { - g_autofree char *path = g_file_get_path (user_font1); - g_ptr_array_add (argv_array, g_strdup ("-b")); - g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); - } - else if (g_file_query_exists (user_font2, NULL)) - { - g_autofree char *path = g_file_get_path (user_font2); - g_ptr_array_add (argv_array, g_strdup ("-b")); - g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); - } - - /* Must run this before spawning the dbus proxy, to ensure it - ends up in the app cgroup */ - xdg_app_run_in_transient_unit (app); - - if (dbus_proxy_argv->len > 0) - { - char x; - - if (pipe (sync_proxy_pipes) < 0) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to create sync pipe"); - return FALSE; - } - - g_ptr_array_insert (dbus_proxy_argv, 0, g_strdup (DBUSPROXY)); - g_ptr_array_insert (dbus_proxy_argv, 1, g_strdup_printf ("--fd=%d", sync_proxy_pipes[1])); - - g_ptr_array_add (dbus_proxy_argv, NULL); /* NULL terminate */ - - if (!g_spawn_async (NULL, - (char **)dbus_proxy_argv->pdata, - NULL, - G_SPAWN_SEARCH_PATH, - dbus_spawn_child_setup, - GINT_TO_POINTER (sync_proxy_pipes[1]), - NULL, error)) - return FALSE; - - close (sync_proxy_pipes[1]); - - /* Sync with proxy, i.e. wait until its listening on the sockets */ - if (read (sync_proxy_pipes[0], &x, 1) != 1) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to sync with dbus proxy"); - return FALSE; - } - - g_ptr_array_add (argv_array, g_strdup ("-S")); - g_ptr_array_add (argv_array, g_strdup_printf ("%d", sync_proxy_pipes[0])); - } - - g_ptr_array_add (argv_array, g_strdup ("-a")); - g_ptr_array_add (argv_array, g_file_get_path (app_files)); - g_ptr_array_add (argv_array, g_strdup ("-I")); - g_ptr_array_add (argv_array, g_strdup (app)); - g_ptr_array_add (argv_array, g_file_get_path (runtime_files)); - - g_ptr_array_add (argv_array, g_strdup (command)); - for (i = 1; i < rest_argc; i++) - g_ptr_array_add (argv_array, g_strdup (argv[rest_argv_start + i])); - - g_ptr_array_add (argv_array, NULL); - - envp = g_get_environ (); - envp = xdg_app_run_apply_env_default (envp); - - envp = xdg_app_run_apply_env_vars (envp, app_context); - - envp = xdg_app_run_apply_env_appid (envp, app_id_dir); - - if (execvpe (HELPER, (char **)argv_array->pdata, envp) == -1) - { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to start app"); - return FALSE; - } - /* Not actually reached... */ return TRUE; } diff --git a/common/xdg-app-dir.h b/common/xdg-app-dir.h index 65cf0f1a..6ecd96bd 100644 --- a/common/xdg-app-dir.h +++ b/common/xdg-app-dir.h @@ -185,4 +185,5 @@ char * xdg_app_dir_fetch_remote_title (XdgAppDir *self, GCancellable *cancellable, GError **error); + #endif /* __XDG_APP_DIR_H__ */ diff --git a/common/xdg-app-run.c b/common/xdg-app-run.c index d26b8d19..926c3019 100644 --- a/common/xdg-app-run.c +++ b/common/xdg-app-run.c @@ -1838,3 +1838,307 @@ xdg_app_run_in_transient_unit (const char *appid) g_free (job); g_free (name); } + +static void +dbus_spawn_child_setup (gpointer user_data) +{ + int fd = GPOINTER_TO_INT (user_data); + fcntl (fd, F_SETFD, 0); +} + +gboolean +xdg_app_run_app (const char *app_ref, + XdgAppDeploy *app_deploy, + XdgAppContext *extra_context, + const char *custom_runtime, + XdgAppRunFlags flags, + const char *custom_command, + char *args[], + int n_args, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(XdgAppDeploy) runtime_deploy = NULL; + g_autoptr(GFile) app_files = NULL; + g_autoptr(GFile) runtime_files = NULL; + g_autoptr(GFile) app_id_dir = NULL; + g_autoptr(GFile) app_cache_dir = NULL; + g_autoptr(GFile) app_data_dir = NULL; + g_autoptr(GFile) app_config_dir = NULL; + g_autoptr(GFile) home = NULL; + g_autoptr(GFile) user_font1 = NULL; + g_autoptr(GFile) user_font2 = NULL; + g_autoptr(XdgAppSessionHelper) session_helper = NULL; + g_autofree char *runtime = NULL; + g_autofree char *default_command = NULL; + g_autofree char *runtime_ref = NULL; + g_autofree char *doc_mount_path = NULL; + g_autoptr(GKeyFile) metakey = NULL; + g_autoptr(GKeyFile) runtime_metakey = NULL; + g_autoptr(GPtrArray) argv_array = NULL; + g_auto(GStrv) envp = NULL; + g_autoptr(GPtrArray) dbus_proxy_argv = NULL; + g_autofree char *monitor_path = NULL; + const char *command = "/bin/sh"; + int i; + int sync_proxy_pipes[2]; + g_autoptr(XdgAppContext) app_context = NULL; + g_autoptr(XdgAppContext) overrides = NULL; + g_autoptr(GDBusConnection) session_bus = NULL; + g_auto(GStrv) app_ref_parts = NULL; + + app_ref_parts = xdg_app_decompose_ref (app_ref, error); + if (app_ref_parts == NULL) + return FALSE; + + metakey = xdg_app_deploy_get_metadata (app_deploy); + + argv_array = g_ptr_array_new_with_free_func (g_free); + dbus_proxy_argv = g_ptr_array_new_with_free_func (g_free); + g_ptr_array_add (argv_array, g_strdup (HELPER)); + g_ptr_array_add (argv_array, g_strdup ("-l")); + + if (!xdg_app_run_add_extension_args (argv_array, metakey, app_ref, cancellable, error)) + return FALSE; + + if (custom_runtime) + runtime = g_strdup (custom_runtime); + else + { + runtime = g_key_file_get_string (metakey, "Application", + (flags & XDG_APP_RUN_FLAG_DEVEL) != 0 ? "sdk" : "runtime", + error); + if (*error) + return FALSE; + } + + runtime_ref = g_build_filename ("runtime", runtime, NULL); + + runtime_deploy = xdg_app_find_deploy_for_ref (runtime_ref, cancellable, error); + if (runtime_deploy == NULL) + return FALSE; + + runtime_metakey = xdg_app_deploy_get_metadata (runtime_deploy); + + app_context = xdg_app_context_new (); + xdg_app_context_set_session_bus_policy (app_context, "org.freedesktop.portal.Documents", XDG_APP_POLICY_TALK); + + if (!xdg_app_context_load_metadata (app_context, runtime_metakey, error)) + return FALSE; + if (!xdg_app_context_load_metadata (app_context, metakey, error)) + return FALSE; + + overrides = xdg_app_deploy_get_overrides (app_deploy); + xdg_app_context_merge (app_context, overrides); + + xdg_app_context_merge (app_context, extra_context); + + { + g_autofree char *tmp_path = NULL; + int fd; + + fd = g_file_open_tmp ("xdg-app-context-XXXXXX", &tmp_path, NULL); + if (fd >= 0) + { + g_autoptr(GKeyFile) keyfile = NULL; + + close (fd); + + keyfile = g_key_file_new (); + + g_key_file_set_string (keyfile, "Application", "name", app_ref_parts[1]); + g_key_file_set_string (keyfile, "Application", "runtime", runtime_ref); + + xdg_app_context_save_metadata (app_context, keyfile); + + if (!g_key_file_save_to_file (keyfile, tmp_path, error)) + return FALSE; + + g_ptr_array_add (argv_array, g_strdup ("-M")); + g_ptr_array_add (argv_array, g_strdup_printf ("/run/user/%d/xdg-app-info=%s", getuid(), tmp_path)); + } + } + + if (!xdg_app_run_add_extension_args (argv_array, runtime_metakey, runtime_ref, cancellable, error)) + return FALSE; + + if ((app_id_dir = xdg_app_ensure_data_dir (app_ref_parts[1], cancellable, error)) == NULL) + return FALSE; + + app_cache_dir = g_file_get_child (app_id_dir, "cache"); + g_ptr_array_add (argv_array, g_strdup ("-B")); + g_ptr_array_add (argv_array, g_strdup_printf ("/var/cache=%s", gs_file_get_path_cached (app_cache_dir))); + + app_data_dir = g_file_get_child (app_id_dir, "data"); + g_ptr_array_add (argv_array, g_strdup ("-B")); + g_ptr_array_add (argv_array, g_strdup_printf ("/var/data=%s", gs_file_get_path_cached (app_data_dir))); + + app_config_dir = g_file_get_child (app_id_dir, "config"); + g_ptr_array_add (argv_array, g_strdup ("-B")); + g_ptr_array_add (argv_array, g_strdup_printf ("/var/config=%s", gs_file_get_path_cached (app_config_dir))); + + app_files = xdg_app_deploy_get_files (app_deploy); + runtime_files = xdg_app_deploy_get_files (runtime_deploy); + + default_command = g_key_file_get_string (metakey, "Application", "command", error); + if (*error) + return FALSE; + if (custom_command) + command = custom_command; + else + command = default_command; + + session_helper = + xdg_app_session_helper_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + "org.freedesktop.XdgApp", + "/org/freedesktop/XdgApp/SessionHelper", + NULL, NULL); + if (session_helper && + xdg_app_session_helper_call_request_monitor_sync (session_helper, + &monitor_path, + NULL, NULL)) + { + g_ptr_array_add (argv_array, g_strdup ("-m")); + g_ptr_array_add (argv_array, monitor_path); + } + else + g_ptr_array_add (argv_array, g_strdup ("-r")); + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + if (session_bus) + { + g_autoptr (GError) local_error = NULL; + g_autoptr (GDBusMessage) reply = NULL; + g_autoptr (GDBusMessage) msg = + g_dbus_message_new_method_call ("org.freedesktop.portal.Documents", + "/org/freedesktop/portal/documents", + "org.freedesktop.portal.Documents", + "GetMountPoint"); + g_dbus_message_set_body (msg, g_variant_new ("()")); + reply = + g_dbus_connection_send_message_with_reply_sync (session_bus, msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + 30000, + NULL, + NULL, + NULL); + if (reply) + { + if (g_dbus_message_to_gerror (reply, &local_error)) + g_warning ("Can't get document portal: %s\n", local_error->message); + else + g_variant_get (g_dbus_message_get_body (reply), + "(^ay)", &doc_mount_path); + } + } + + xdg_app_run_add_environment_args (argv_array, dbus_proxy_argv, doc_mount_path, + app_ref_parts[1], app_context, app_id_dir); + + g_ptr_array_add (argv_array, g_strdup ("-b")); + g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/fonts=%s", SYSTEM_FONTS_DIR)); + + if ((flags & XDG_APP_RUN_FLAG_DEVEL) != 0) + g_ptr_array_add (argv_array, g_strdup ("-c")); + + home = g_file_new_for_path (g_get_home_dir ()); + user_font1 = g_file_resolve_relative_path (home, ".local/share/fonts"); + user_font2 = g_file_resolve_relative_path (home, ".fonts"); + + if (g_file_query_exists (user_font1, NULL)) + { + g_autofree char *path = g_file_get_path (user_font1); + g_ptr_array_add (argv_array, g_strdup ("-b")); + g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); + } + else if (g_file_query_exists (user_font2, NULL)) + { + g_autofree char *path = g_file_get_path (user_font2); + g_ptr_array_add (argv_array, g_strdup ("-b")); + g_ptr_array_add (argv_array, g_strdup_printf ("/run/host/user-fonts=%s", path)); + } + + /* Must run this before spawning the dbus proxy, to ensure it + ends up in the app cgroup */ + xdg_app_run_in_transient_unit (app_ref_parts[1]); + + if (dbus_proxy_argv->len > 0) + { + char x; + + if (pipe (sync_proxy_pipes) < 0) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to create sync pipe"); + return FALSE; + } + + g_ptr_array_insert (dbus_proxy_argv, 0, g_strdup (DBUSPROXY)); + g_ptr_array_insert (dbus_proxy_argv, 1, g_strdup_printf ("--fd=%d", sync_proxy_pipes[1])); + + g_ptr_array_add (dbus_proxy_argv, NULL); /* NULL terminate */ + + if (!g_spawn_async (NULL, + (char **)dbus_proxy_argv->pdata, + NULL, + G_SPAWN_SEARCH_PATH, + dbus_spawn_child_setup, + GINT_TO_POINTER (sync_proxy_pipes[1]), + NULL, error)) + return FALSE; + + close (sync_proxy_pipes[1]); + + /* Sync with proxy, i.e. wait until its listening on the sockets */ + if (read (sync_proxy_pipes[0], &x, 1) != 1) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Failed to sync with dbus proxy"); + return FALSE; + } + + g_ptr_array_add (argv_array, g_strdup ("-S")); + g_ptr_array_add (argv_array, g_strdup_printf ("%d", sync_proxy_pipes[0])); + } + + g_ptr_array_add (argv_array, g_strdup ("-a")); + g_ptr_array_add (argv_array, g_file_get_path (app_files)); + g_ptr_array_add (argv_array, g_strdup ("-I")); + g_ptr_array_add (argv_array, g_strdup (app_ref_parts[1])); + g_ptr_array_add (argv_array, g_file_get_path (runtime_files)); + + g_ptr_array_add (argv_array, g_strdup (command)); + for (i = 0; i < n_args; i++) + g_ptr_array_add (argv_array, g_strdup (args[i])); + + g_ptr_array_add (argv_array, NULL); + + envp = g_get_environ (); + envp = xdg_app_run_apply_env_default (envp); + + envp = xdg_app_run_apply_env_vars (envp, app_context); + + envp = xdg_app_run_apply_env_appid (envp, app_id_dir); + + if ((flags & XDG_APP_RUN_FLAG_BACKGROUND) != 0) + { + if (!g_spawn_async (NULL, + (char **)argv_array->pdata, + envp, + G_SPAWN_DEFAULT, + NULL, NULL, + NULL, + error)) + return FALSE; + } + else + { + if (execvpe (HELPER, (char **)argv_array->pdata, envp) == -1) + { + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "Unable to start app"); + return FALSE; + } + /* Not actually reached... */ + } + + return TRUE; +} diff --git a/common/xdg-app-run.h b/common/xdg-app-run.h index 60855217..6f25e071 100644 --- a/common/xdg-app-run.h +++ b/common/xdg-app-run.h @@ -76,4 +76,21 @@ GFile *xdg_app_ensure_data_dir (const char *app_id, GCancellable *cancellable, GError **error); +typedef enum { + XDG_APP_RUN_FLAG_DEVEL = (1<<0), + XDG_APP_RUN_FLAG_BACKGROUND = (1<<1), +} XdgAppRunFlags; + +gboolean xdg_app_run_app (const char *app_ref, + XdgAppDeploy *app_deploy, + XdgAppContext *extra_context, + const char *custom_runtime, + XdgAppRunFlags flags, + const char *custom_command, + char *args[], + int n_args, + GCancellable *cancellable, + GError **error); + + #endif /* __XDG_APP_RUN_H__ */