void arv_rtkit_make_high_priority (GDBusConnection *connection, pid_t thread, int nice_level, GError **error) { GDBusMessage *message; GDBusMessage *reply; GError *local_error = NULL; message = g_dbus_message_new_method_call (RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, "org.freedesktop.RealtimeKit1", "MakeThreadHighPriority"); g_dbus_message_set_body (message, g_variant_new ("(ti)", thread, nice_level)); reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000, NULL, NULL, &local_error); g_object_unref (message); if (local_error != NULL) { g_propagate_error (error, local_error); return; } if (g_dbus_message_get_message_type (reply) != G_DBUS_MESSAGE_TYPE_METHOD_RETURN) { local_error = g_error_new (ARV_RTKIT_ERROR, 0, "%s", g_dbus_message_get_error_name (reply)); g_propagate_error (error, local_error); g_object_unref (reply); return; } g_object_unref (reply); }
// returns object path of default adapter or NULL if failed // this object path must be freed with g_free() gchar* bluez_get_default_adapter(GDBusConnection* conn) { GError* error = NULL; GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez", "/", "org.bluez.Manager", "DefaultAdapter"); if(call_message == NULL) { g_printf("g_dbus_message_new_method_call failed\n"); return NULL; } GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn, call_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if(reply_message == NULL) { g_printf("g_dbus_connection_send_message_with_reply_sync failed\n"); return NULL; } if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { printf("Error occured\n"); g_dbus_message_to_gerror(reply_message, &error); g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message); g_error_free(error); return NULL; } GVariant* variant = g_dbus_message_get_body(reply_message); // get first child, as this is the object path of the default interface of bluez GVariant* var_child = g_variant_get_child_value(variant, 0); const gchar* tmp_path = g_variant_get_string(var_child, NULL); // copy content of tmp_path to obj_path, as tmp_path gets freed after unref of the variant gchar* obj_path = g_strdup(tmp_path); // cleanup g_variant_unref(var_child); g_object_unref(call_message); g_object_unref(reply_message); return obj_path; }
static char * xdp_connection_lookup_app_id_sync (GDBusConnection *connection, const char *sender, GCancellable *cancellable, GError **error) { g_autoptr(GDBusMessage) msg = NULL; g_autoptr(GDBusMessage) reply = NULL; char *app_id = NULL; GVariant *body; guint32 pid; G_LOCK (app_ids); if (app_ids) app_id = g_strdup (g_hash_table_lookup (app_ids, sender)); G_UNLOCK (app_ids); if (app_id != NULL) return app_id; msg = g_dbus_message_new_method_call ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetConnectionUnixProcessID"); g_dbus_message_set_body (msg, g_variant_new ("(s)", sender)); reply = g_dbus_connection_send_message_with_reply_sync (connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 30000, NULL, cancellable, error); if (reply == NULL) return NULL; if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't find peer app id"); return NULL; } body = g_dbus_message_get_body (reply); g_variant_get (body, "(u)", &pid); app_id = get_app_id_from_pid (pid, error); if (app_id) { G_LOCK (app_ids); ensure_app_ids (); g_hash_table_insert (app_ids, g_strdup (sender), g_strdup (app_id)); G_UNLOCK (app_ids); } return app_id; }
static GDBusMessage * screensaver_send_message_void (GDBusConnection *connection, const char *name, gboolean expect_reply) { GDBusMessage *message, *reply; GError *error; g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); message = g_dbus_message_new_method_call (GS_SERVICE, GS_PATH, GS_INTERFACE, name); if (message == NULL) { g_warning ("Couldn't allocate the dbus message"); return NULL; } error = NULL; if (! expect_reply) { reply = NULL; g_dbus_connection_send_message (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error); } else { reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); } if (error != NULL) { g_warning ("unable to send message: %s", error->message); g_clear_error (&error); } g_dbus_connection_flush_sync (connection, NULL, &error); if (error != NULL) { g_warning ("unable to flush message queue: %s", error->message); g_clear_error (&error); } g_object_unref (message); return reply; }
void bluez_unregister_watcher(GDBusConnection* conn, const gchar* service_path) { GError* error = NULL; GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez", service_path, "org.bluez.Characteristic", "UnregisterCharacteristicsWatcher"); if(call_message == NULL) { printf("g_dbus_message_new_method_call failed\n"); return; } gchar path[255]; g_snprintf(path, 255, "/test/bluez/%d", getpid()); GVariant* variant_addr = g_variant_new_object_path(path); GVariant* variant_body = g_variant_new_tuple(&variant_addr, 1); g_dbus_message_set_body(call_message, variant_body); GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn, call_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if(reply_message == NULL) { printf("g_dbus_connection_send_message_with_reply_sync failed\n"); return; } if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { printf("Error occured\n"); g_dbus_message_to_gerror(reply_message, &error); g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message); g_error_free(error); return; } // cleanup g_object_unref(call_message); g_object_unref(reply_message); }
GVariant* bluez_characteristic_get_value(GDBusConnection* conn, const gchar* char_path) { GError* error = NULL; GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez", char_path, "org.bluez.Characteristic", "GetProperties"); if(call_message == NULL) { g_printf("g_dbus_message_new_method_call failed\n"); return NULL; } GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn, call_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if(reply_message == NULL) { g_printf("g_dbus_connection_send_message_with_reply_sync failed\n"); return NULL; } if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { g_printf("Error occured\n"); g_dbus_message_to_gerror(reply_message, &error); g_printerr("Error invoking g_dbus_connection_send_message_with_reply_sync: %s\n", error->message); g_error_free(error); return NULL; } GVariant* var_body = g_dbus_message_get_body(reply_message); g_variant_ref(var_body); // cleanup g_object_unref(call_message); g_object_unref(reply_message); return var_body; }
// returns the object path to a given device or NULL if failed // object path has to be freed with g_free() gchar* bluez_find_device(GDBusConnection* conn, const gchar* adapter_path, const char* bt_addr) { GError* error = NULL; GDBusMessage* call_message = g_dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", "FindDevice"); if(call_message == NULL) { return NULL; } GVariant* variant_addr = g_variant_new_string(bt_addr); GVariant* variant_body = g_variant_new_tuple(&variant_addr, 1); g_dbus_message_set_body(call_message, variant_body); GDBusMessage* reply_message = g_dbus_connection_send_message_with_reply_sync(conn, call_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if(reply_message == NULL) { return NULL; } if(g_dbus_message_get_message_type(reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { return NULL; } GVariant* variant = g_dbus_message_get_body(reply_message); // get first child, as this is the object path of the default interface of bluez GVariant* var_child = g_variant_get_child_value(variant, 0); const gchar* tmp_path = g_variant_get_string(var_child, NULL); // copy content of tmp_path to obj_path, as tmp_path gets freed after unref of the variant gchar* obj_path = g_strdup(tmp_path); // cleanup g_variant_unref(var_child); g_object_unref(call_message); g_object_unref(reply_message); return obj_path; }
static int is_dbus_based_screensaver_active(const char *d_service, const char *d_path, const char *d_interface) { GDBusMessage *msg = NULL; GDBusMessage *reply = NULL; uint32_t ret = 0; assert(connection); // detect is screen saver already active msg = g_dbus_message_new_method_call(d_service, d_path, d_interface, "GetActive"); if (!msg) { trace_error("%s, can't allocate GDBusMessage\n", __func__); goto err; } GError *error = NULL; reply = g_dbus_connection_send_message_with_reply_sync(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if (error) { trace_error("%s, can't send message, %s\n", __func__, error->message); g_clear_error(&error); goto err; } g_dbus_connection_flush_sync(connection, NULL, &error); if (error != NULL) { trace_error("%s, can't flush dbus connection, %s\n", __func__, error->message); g_clear_error(&error); goto err; } GVariant *v = g_dbus_message_get_body(reply); v = g_variant_get_child_value(v, 0); if (g_variant_is_of_type(v, G_VARIANT_TYPE_BOOLEAN)) ret = g_variant_get_boolean(v); else ret = 0; err: if (reply) g_object_unref(reply); if (msg) g_object_unref(msg); return ret; }
/* see gdbus-example-server.c for the server implementation */ static gint get_server_stdout (GDBusConnection *connection, const gchar *name_owner, GError **error) { GDBusMessage *method_call_message; GDBusMessage *method_reply_message; GUnixFDList *fd_list; gint fd; fd = -1; method_call_message = NULL; method_reply_message = NULL; method_call_message = g_dbus_message_new_method_call (name_owner, "/org/gtk/GDBus/TestObject", "org.gtk.GDBus.TestInterface", "GimmeStdout"); method_reply_message = g_dbus_connection_send_message_with_reply_sync (connection, method_call_message, -1, NULL, /* out_serial */ NULL, /* cancellable */ error); if (method_reply_message == NULL) goto out; if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) { g_dbus_message_to_gerror (method_reply_message, error); goto out; } fd_list = g_dbus_message_get_unix_fd_list (method_reply_message); fd = g_unix_fd_list_get (fd_list, 0, error); out: g_object_unref (method_call_message); g_object_unref (method_reply_message); return fd; }
static void steadyflow_iapp_service_proxy_set_visible (SteadyflowIAppService* self, gboolean visible, GError** error) { GDBusMessage *_message; GVariant *_arguments; GVariantBuilder _arguments_builder; GDBusMessage *_reply_message; G_IO_ERROR; _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "net.launchpad.steadyflow.App", "SetVisible"); g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value (&_arguments_builder, g_variant_new_boolean (visible)); _arguments = g_variant_builder_end (&_arguments_builder); g_dbus_message_set_body (_message, _arguments); _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); g_object_unref (_message); if (!_reply_message) { return; } if (g_dbus_message_to_gerror (_reply_message, error)) { g_object_unref (_reply_message); return; } g_object_unref (_reply_message); }
static uint32_t detect_dbus_based_screensavers(void) { GDBusMessage *msg, *reply; uint32_t ret; assert(connection); // enumerate all services msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames"); if (!msg) { trace_error("%s, can't allocate GDBusMessage\n", __func__); ret = 0; goto err_1; } GError *error = NULL; reply = g_dbus_connection_send_message_with_reply_sync(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &error); if (error != NULL) { trace_error("%s, can't send message, %s\n", __func__, error->message); g_clear_error(&error); ret = 0; goto err_2; } g_dbus_connection_flush_sync(connection, NULL, &error); if (error != NULL) { trace_error("%s, can't flush dbus connection, %s\n", __func__, error->message); g_clear_error(&error); ret = 0; goto err_3; } // iterate over the list GVariant *v = g_dbus_message_get_body(reply); GVariantIter *iter; gchar *str; uint32_t flags = 0; g_variant_get(v, "(as)", &iter); while (g_variant_iter_loop(iter, "s", &str)) { if (strcmp(str, GS_SERVICE) == 0) flags |= SST_GNOME_SCREENSAVER; if (strcmp(str, KS_SERVICE) == 0) flags |= SST_KDE_SCREENSAVER; if (strcmp(str, FDOS_SERVICE) == 0) flags |= SST_FDO_SCREENSAVER; if (strcmp(str, CINNAMON_SERVICE) == 0) flags |= SST_CINNAMON_SCREENSAVER; } g_variant_iter_free(iter); ret = flags; err_3: g_object_unref(reply); err_2: g_object_unref(msg); err_1: return ret; }
static gint64 arv_rtkit_get_int_property (GDBusConnection *connection, const char* propname, GError **error) { GDBusMessage *message; GDBusMessage *reply; GError *local_error = NULL; GVariant *body; GVariant *parameter; GVariant *variant; const GVariantType *variant_type; gint64 value; message = g_dbus_message_new_method_call (RTKIT_SERVICE_NAME, RTKIT_OBJECT_PATH, "org.freedesktop.DBus.Properties", "Get"); g_dbus_message_set_body (message, g_variant_new ("(ss)", "org.freedesktop.RealtimeKit1", propname)); reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000, NULL, NULL, &local_error); g_object_unref (message); if (local_error != NULL) { g_propagate_error (error, local_error); return 0; } if (g_dbus_message_get_message_type (reply) != G_DBUS_MESSAGE_TYPE_METHOD_RETURN) { local_error = g_error_new (ARV_RTKIT_ERROR, ARV_RTKIT_ERROR_PERMISSION_DENIED, "%s", g_dbus_message_get_error_name (reply)); g_propagate_error (error, local_error); g_object_unref (reply); return 0; } if (!g_variant_type_equal ("v", g_dbus_message_get_signature (reply))) { local_error = g_error_new (ARV_RTKIT_ERROR, ARV_RTKIT_ERROR_WRONG_REPLY, "Invalid reply signature"); g_propagate_error (error, local_error); g_object_unref (reply); return 0; } body = g_dbus_message_get_body (reply); parameter = g_variant_get_child_value (body, 0); variant = g_variant_get_variant (parameter); variant_type = g_variant_get_type (variant); if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32)) value = g_variant_get_int32 (variant); else if (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64)) value = g_variant_get_int64 (variant); else value = 0; g_variant_unref (parameter); g_variant_unref (variant); g_object_unref (reply); return value; }
/** * fu_util_get_details: **/ static gboolean fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error) { GVariant *body; GVariant *val; gint fd; gint retval; _cleanup_object_unref_ GDBusMessage *message = NULL; _cleanup_object_unref_ GDBusMessage *request = NULL; _cleanup_object_unref_ GUnixFDList *fd_list = NULL; /* check args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments: expected 'filename'"); return FALSE; } /* open file */ fd = open (values[0], O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", values[0]); return FALSE; } /* set out of band file descriptor */ fd_list = g_unix_fd_list_new (); retval = g_unix_fd_list_append (fd_list, fd, NULL); g_assert (retval != -1); request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, "GetDetails"); g_dbus_message_set_unix_fd_list (request, fd_list); /* g_unix_fd_list_append did a dup() already */ close (fd); /* send message */ body = g_variant_new ("(h)", fd > -1 ? 0 : -1); g_dbus_message_set_body (request, body); message = g_dbus_connection_send_message_with_reply_sync (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, error); if (message == NULL) { g_dbus_error_strip_remote_error (*error); return FALSE; } if (g_dbus_message_to_gerror (message, error)) { g_dbus_error_strip_remote_error (*error); return FALSE; } /* print results */ val = g_dbus_message_get_body (message); fu_util_print_metadata (val); return TRUE; }
gboolean e_mapi_util_trigger_krb_auth (const EMapiProfileData *empd, GError **error) { gint success = FALSE; GError *local_error = NULL; GDBusConnection *connection; GDBusMessage *message, *reply; gchar *name; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); if (local_error) { g_warning ("could not get system bus: %s\n", local_error->message); g_propagate_error (error, local_error); return FALSE; } g_dbus_connection_set_exit_on_close (connection, FALSE); /* Create a new message on the KRB_DBUS_INTERFACE */ message = g_dbus_message_new_method_call (KRB_DBUS_INTERFACE, KRB_DBUS_PATH, KRB_DBUS_INTERFACE, "acquireTgt"); if (!message) { g_object_unref (connection); return FALSE; } /* Appends the data as an argument to the message */ name = g_strdup_printf ("%s@%s", empd->username, empd->krb_realm); g_dbus_message_set_body (message, g_variant_new ("(s)", name)); /* Sends the message: Have a 300 sec wait timeout */ reply = g_dbus_connection_send_message_with_reply_sync (connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 300 * 1000, NULL, NULL, &local_error); g_free (name); if (!local_error && reply) { if (g_dbus_message_to_gerror (reply, &local_error)) { g_object_unref (reply); reply = NULL; } } if (local_error) { g_dbus_error_strip_remote_error (local_error); g_propagate_error (error, local_error); } if (reply) { GVariant *body = g_dbus_message_get_body (reply); if (body) { g_variant_get (body, "(b)", &success); } g_object_unref (reply); } /* Free the message */ g_object_unref (message); g_object_unref (connection); return success && !local_error; }
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"); rest_argc = 0; for (i = 1; i < argc; i++) { /* The non-option is the command, take it out of the arguments */ if (argv[i][0] != '-') { rest_argv_start = i; rest_argc = argc - i; argc = i; break; } } arg_context = xdg_app_context_new (); g_option_context_add_group (context, xdg_app_context_get_options (arg_context)); if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error)) return FALSE; if (rest_argc == 0) return usage_error (context, "APP must be specified", error); app = argv[rest_argv_start]; if (opt_branch) branch = opt_branch; if (!xdg_app_is_valid_name (app)) return xdg_app_fail (error, "'%s' is not a valid application name", app); if (!xdg_app_is_valid_branch (branch)) return xdg_app_fail (error, "'%s' is not a valid branch name", branch); app_ref = xdg_app_build_app_ref (app, branch, opt_arch); app_deploy = xdg_app_find_deploy_for_ref (app_ref, cancellable, error); 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)) 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 (); 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); 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; }