static void deactivate_dbus_based_screensaver(const char *d_service, const char *d_path, const char *d_interface) { if (!connection) screensaver_connect(); if (!connection) return; if (is_dbus_based_screensaver_active(d_service, d_path, d_interface)) { // screen saver is active already, deactivating timer makes no sense return; } GDBusMessage *msg = g_dbus_message_new_method_call(d_service, d_path, d_interface, "SimulateUserActivity"); if (!msg) return; GError *error = NULL; g_dbus_connection_send_message(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error); if (error != NULL) { trace_error("%s, can't send message, %s\n", __func__, error->message); g_clear_error(&error); goto err; } // workaround Plasma 5 issue by calling GetSessionIdleTime after SimulateUserActivity if (config.quirks.plasma5_screensaver) { msg = g_dbus_message_new_method_call(d_service, d_path, d_interface, "GetSessionIdleTime"); error = NULL; g_dbus_connection_send_message(connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error); if (error != NULL) { 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; } err: g_object_unref(msg); }
/* The GNOME 3 Shell holds an X grab when we're in the overview; * ask it to bounce out before we try locking the screen. */ static void request_shell_exit_overview (GSGrab *grab) { GDBusMessage *message; /* Shouldn't happen, but... */ if (!grab->priv->session_bus) return; message = g_dbus_message_new_method_call ("org.gnome.Shell", "/org/gnome/Shell", "org.freedesktop.DBus.Properties", "Set"); g_dbus_message_set_body (message, g_variant_new ("(ssv)", "org.gnome.Shell", "OverviewActive", g_variant_new ("b", FALSE))); g_dbus_connection_send_message (grab->priv->session_bus, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); }
// 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; }
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); }
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; }
// 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; }
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; }
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); }
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; }
static CloudSpyDispatcherInvocation * cloud_spy_dispatcher_invocation_new (GDBusMethodInfo * method, GVariant * parameters, GSimpleAsyncResult * res) { CloudSpyDispatcherInvocation * invocation; invocation = g_slice_new (CloudSpyDispatcherInvocation); invocation->magic = &cloud_spy_dispatcher_magic; invocation->ref_count = 1; invocation->method = g_dbus_method_info_ref (method); invocation->parameters = g_variant_ref (parameters); invocation->res = res; invocation->call_message = g_dbus_message_new_method_call (NULL, "/org/boblycat/frida/Foo", "org.boblycat.Frida.Foo", method->name); g_dbus_message_set_serial (invocation->call_message, 1); return invocation; }
/* 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 gint gdkevent_poll (GPollFD *ufds, guint nfds, gint timeout_) { GDBusMessage *message; GVariant *body; GError *error = NULL; GTimeVal now; long diff; gint ret; g_get_current_time(&now); diff = time_val_difference(&now, &last_time); /* Log if the delay was more than a tenth of a second */ if (diff > (G_USEC_PER_SEC / 10)) { message = g_dbus_message_new_method_call(NULL, "/", "org.perfkit.Agent.GdkEvent", "Delay"); body = g_variant_new("(dd)", TV2DOUBLE(last_time), TV2DOUBLE(now)); g_dbus_message_set_body(message, body); if (!g_dbus_connection_send_message(connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { CRITICAL(Gdk, "Error sending message: %s", error->message); g_error_free(error); } } ret = poll_func(ufds, nfds, timeout_); g_get_current_time(&now); last_time = now; return ret; }
static void writeback_cancel_remote_operation (GCancellable *cancellable, WritebackFileData *data) { TrackerWritebackDispatcherPrivate *priv; GDBusMessage *message; gchar *uris[2]; priv = TRACKER_WRITEBACK_DISPATCHER_GET_PRIVATE (data->self); uris[0] = g_file_get_uri (data->file); uris[1] = NULL; message = g_dbus_message_new_method_call (TRACKER_WRITEBACK_SERVICE, TRACKER_WRITEBACK_PATH, TRACKER_WRITEBACK_INTERFACE, "CancelTasks"); g_dbus_message_set_body (message, g_variant_new ("(^as)", uris)); g_dbus_connection_send_message (priv->d_connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_free (uris[0]); }
static void send_close (FilechooserPortalData *data) { GDBusMessage *message; GError *error = NULL; message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.FileChooser", "Close"); g_dbus_message_set_body (message, g_variant_new ("(o)", data->portal_handle)); if (!g_dbus_connection_send_message (data->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { g_warning ("unable to send FileChooser Close message: %s", error->message); g_error_free (error); } g_object_unref (message); }
gboolean eas_gdbus_call_finish (struct eas_gdbus_client *client, GAsyncResult *result, guint cancel_serial, const gchar *out_params, va_list *ap, GError **error) { GDBusMessage *reply; gchar *out_params_type = (gchar *) out_params; gboolean success = FALSE; GVariant *v; reply = g_dbus_connection_send_message_with_reply_finish(client->connection, result, error); if (cancel_serial) { GDBusMessage *message; message = g_dbus_message_new_method_call (EAS_SERVICE_NAME, EAS_SERVICE_COMMON_OBJECT_PATH, EAS_SERVICE_COMMON_INTERFACE, "cancel_request"); g_dbus_message_set_body (message, g_variant_new ("(su)", client->account_uid, cancel_serial)); g_dbus_connection_send_message (client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); g_object_unref (message); } if (!reply) return FALSE; /* g_variant_is_of_type() will fail to match a DBus return of (sas) with a format string of (s^as), where the ^ is required to make it convert to a strv instead of something more complicated. So we remove all ^ characters from the string that we show to g_variant_is_of_type(). Ick. */ if (out_params && strchr (out_params, '^')) { gchar *x, *y; out_params_type = g_strdup (out_params); x = y = strchr (out_params_type, '^'); y++; while (*y) { if (*y == '^') y++; else *(x++) = *(y++); } *x = 0; } switch (g_dbus_message_get_message_type (reply)) { case G_DBUS_MESSAGE_TYPE_METHOD_RETURN: /* An empty (successful) response will give a NULL GVariant here */ v = g_dbus_message_get_body (reply); if (!out_params) { if (v) goto inval; else { success = TRUE; break; } } if (!g_variant_is_of_type (v, G_VARIANT_TYPE (out_params_type))) { inval: g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "ActiveSync DBus call returned invalid response type %s", v?g_variant_get_type_string (v):"()"); goto out; g_object_unref (reply); } g_variant_get_va (v, out_params, NULL, ap); success = TRUE; break; case G_DBUS_MESSAGE_TYPE_ERROR: g_dbus_message_to_gerror (reply, error); break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "EAS DBus call returned weird message type %d", g_dbus_message_get_message_type (reply)); break; } out: if (out_params_type != out_params) g_free (out_params_type); g_object_unref (reply); return success; }
/** * fu_util_refresh_internal: **/ static gboolean fu_util_refresh_internal (FuUtilPrivate *priv, const gchar *data_fn, const gchar *sig_fn, GError **error) { GVariant *body; gint fd; gint fd_sig; _cleanup_object_unref_ GDBusMessage *request = NULL; _cleanup_object_unref_ GUnixFDList *fd_list = NULL; /* open file */ fd = open (data_fn, O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", data_fn); return FALSE; } fd_sig = open (sig_fn, O_RDONLY); if (fd_sig < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", sig_fn); return FALSE; } /* set out of band file descriptor */ fd_list = g_unix_fd_list_new (); g_unix_fd_list_append (fd_list, fd, NULL); g_unix_fd_list_append (fd_list, fd_sig, NULL); request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, "UpdateMetadata"); g_dbus_message_set_unix_fd_list (request, fd_list); /* g_unix_fd_list_append did a dup() already */ close (fd); close (fd_sig); /* send message */ body = g_variant_new ("(hh)", fd, fd_sig); g_dbus_message_set_body (request, body); g_dbus_connection_send_message_with_reply (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, fu_util_update_cb, priv); g_main_loop_run (priv->loop); if (priv->message == NULL) { g_dbus_error_strip_remote_error (priv->error); g_propagate_error (error, priv->error); return FALSE; } if (g_dbus_message_to_gerror (priv->message, error)) { g_dbus_error_strip_remote_error (*error); return FALSE; } 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 eas_gdbus_call (struct eas_gdbus_client *client, const gchar *object, const gchar *interface, const gchar *method, EasProgressFn progress_fn, gpointer progress_data, const gchar *in_params, const gchar *out_params, GCancellable *cancellable, GError **error, ...) { GDBusMessage *message; struct _eas_call_data call; GMainContext *ctxt; GVariant *v = NULL; va_list ap; gboolean success; guint cancel_handler_id; guint32 serial = 0; va_start (ap, error); message = g_dbus_message_new_method_call (EAS_SERVICE_NAME, object, interface, method); v = g_variant_new_va (in_params, NULL, &ap); g_dbus_message_set_body (message, v); call.cancelled = FALSE; call.result = NULL; ctxt = g_main_context_new (); call.loop = g_main_loop_new (ctxt, FALSE); g_main_context_push_thread_default (ctxt); g_dbus_connection_send_message_with_reply (client->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000000, &serial, cancellable, _call_done, (gpointer) &call); g_object_unref (message); if (cancellable) cancel_handler_id = g_cancellable_connect (cancellable, G_CALLBACK (_call_cancel), (gpointer) &call, NULL); /* Ignore error; it's not the end of the world if progress info is lost, and it should never happen anyway */ if (progress_fn) eas_client_add_progress_info_to_table (client, serial, progress_fn, progress_data, NULL); g_main_loop_run (call.loop); if (cancellable) g_cancellable_disconnect (cancellable, cancel_handler_id); success = eas_gdbus_call_finish (client, call.result, call.cancelled ? serial : 0, out_params, &ap, error); if (serial && progress_fn) { EasProgressCallbackInfo *cbinfo; g_mutex_lock (client->progress_lock); cbinfo = g_hash_table_lookup (client->progress_fns_table, GUINT_TO_POINTER (serial)); if (cbinfo && cbinfo->calling) { g_debug ("Progress for call %u is running; wait for it to complete", serial); g_hash_table_steal (client->progress_fns_table, GUINT_TO_POINTER (serial)); do { g_cond_wait (client->progress_cond, client->progress_lock); } while (cbinfo->calling); g_free (cbinfo); } else if (cbinfo) { g_hash_table_remove (client->progress_fns_table, GUINT_TO_POINTER (serial)); } g_mutex_unlock (client->progress_lock); } va_end (ap); g_main_context_pop_thread_default (ctxt); g_main_context_unref (ctxt); g_main_loop_unref (call.loop); g_object_unref (call.result); return success; }
/** * fu_util_install_internal: **/ static gboolean fu_util_install_internal (FuUtilPrivate *priv, const gchar *id, const gchar *filename, GError **error) { GVariant *body; GVariantBuilder builder; gint retval; gint fd; _cleanup_object_unref_ GDBusMessage *request = NULL; _cleanup_object_unref_ GUnixFDList *fd_list = NULL; /* set options */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); g_variant_builder_add (&builder, "{sv}", "reason", g_variant_new_string ("user-action")); g_variant_builder_add (&builder, "{sv}", "filename", g_variant_new_string (filename)); if (priv->flags & FU_PROVIDER_UPDATE_FLAG_OFFLINE) { g_variant_builder_add (&builder, "{sv}", "offline", g_variant_new_boolean (TRUE)); } if (priv->flags & FU_PROVIDER_UPDATE_FLAG_ALLOW_OLDER) { g_variant_builder_add (&builder, "{sv}", "allow-older", g_variant_new_boolean (TRUE)); } if (priv->flags & FU_PROVIDER_UPDATE_FLAG_ALLOW_REINSTALL) { g_variant_builder_add (&builder, "{sv}", "allow-reinstall", g_variant_new_boolean (TRUE)); } /* open file */ fd = open (filename, O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", filename); 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, "Install"); 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 ("(sha{sv})", id, fd > -1 ? 0 : -1, &builder); g_dbus_message_set_body (request, body); g_dbus_connection_send_message_with_reply (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, fu_util_update_cb, priv); g_main_loop_run (priv->loop); if (priv->message == NULL) { g_dbus_error_strip_remote_error (priv->error); g_propagate_error (error, priv->error); return FALSE; } if (g_dbus_message_to_gerror (priv->message, error)) { g_dbus_error_strip_remote_error (*error); return FALSE; } /* TRANSLATORS: update completed, no errors */ g_print ("%s\n", _("Done!")); return TRUE; }
/** * 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; }
static void gdkevent_dispatcher (GdkEvent *event, gpointer data) { GDBusMessage *message; GError *error = NULL; message = g_dbus_message_new_method_call(NULL, "/", "org.perfkit.Agent.GdkEvent", "Event"); switch (event->type) { case GDK_TOUCH_BEGIN: case GDK_TOUCH_END: case GDK_TOUCH_UPDATE: case GDK_TOUCH_CANCEL: case GDK_NOTHING: break; case GDK_DELETE: gdkevent_handle_any(event, connection); break; case GDK_DESTROY: gdkevent_handle_destroy(event, connection); break; case GDK_EXPOSE: gdkevent_handle_expose(event, message, connection); break; case GDK_MOTION_NOTIFY: gdkevent_handle_motion_notfiy(event, connection); break; case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: gdkevent_handle_button(event, connection); break; case GDK_KEY_PRESS: case GDK_KEY_RELEASE: gdkevent_handle_key(event, connection); break; case GDK_ENTER_NOTIFY: case GDK_LEAVE_NOTIFY: gdkevent_handle_crossing(event, connection); break; case GDK_FOCUS_CHANGE: gdkevent_handle_focus(event, connection); break; case GDK_CONFIGURE: gdkevent_handle_configure(event, connection); break; case GDK_MAP: case GDK_UNMAP: gdkevent_handle_any(event, connection); break; case GDK_PROPERTY_NOTIFY: case GDK_SELECTION_CLEAR: case GDK_SELECTION_REQUEST: case GDK_SELECTION_NOTIFY: case GDK_PROXIMITY_IN: case GDK_PROXIMITY_OUT: case GDK_DRAG_ENTER: case GDK_DRAG_LEAVE: case GDK_DRAG_MOTION: case GDK_DRAG_STATUS: case GDK_DROP_START: case GDK_DROP_FINISHED: case GDK_CLIENT_EVENT: case GDK_VISIBILITY_NOTIFY: #if !GTK_CHECK_VERSION(2, 91, 0) case GDK_NO_EXPOSE: #endif case GDK_SCROLL: case GDK_WINDOW_STATE: case GDK_SETTING: case GDK_OWNER_CHANGE: case GDK_GRAB_BROKEN: case GDK_DAMAGE: case GDK_EVENT_LAST: default: /* * TODO: Handle more of these specificaly. */ gdkevent_handle_any(event, connection); break; } if (!g_dbus_connection_send_message(connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { CRITICAL(Gdk, "Error sending message: %s", error->message); g_error_free(error); } gtk_main_do_event(event); }
gboolean gtk_file_chooser_native_portal_show (GtkFileChooserNative *self) { FilechooserPortalData *data; GtkWindow *transient_for; GDBusConnection *connection; char *parent_window_str; GDBusMessage *message; GVariantBuilder opt_builder; GtkFileChooserAction action; gboolean multiple; const char *method_name; if (!gtk_should_use_portal ()) return FALSE; connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); if (connection == NULL) return FALSE; action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self)); multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (self)); if (action == GTK_FILE_CHOOSER_ACTION_OPEN) method_name = "OpenFile"; else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) method_name = "SaveFile"; else { g_warning ("GTK_FILE_CHOOSER_ACTION_%s is not supported by GtkFileChooserNativePortal", action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ? "SELECT_FOLDER" : "CREATE_FOLDER"); return FALSE; } data = g_new0 (FilechooserPortalData, 1); data->self = g_object_ref (self); data->connection = connection; message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.FileChooser", method_name); parent_window_str = NULL; transient_for = gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG (self)); if (transient_for != NULL && gtk_widget_is_visible (GTK_WIDGET (transient_for))) { GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (transient_for)); #ifdef GDK_WINDOWING_X11 if (GDK_IS_X11_WINDOW(window)) parent_window_str = g_strdup_printf ("x11:%x", (guint32)gdk_x11_window_get_xid (window)); #endif } if (gtk_native_dialog_get_modal (GTK_NATIVE_DIALOG (self))) data->modal = TRUE; if (data->modal && transient_for != NULL) { data->grab_widget = gtk_invisible_new_for_screen (gtk_widget_get_screen (GTK_WIDGET (transient_for))); gtk_grab_add (GTK_WIDGET (data->grab_widget)); } g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&opt_builder, "{sv}", "multiple", g_variant_new_boolean (multiple)); if (self->accept_label) g_variant_builder_add (&opt_builder, "{sv}", "accept_label", g_variant_new_string (self->accept_label)); if (self->cancel_label) g_variant_builder_add (&opt_builder, "{sv}", "cancel_label", g_variant_new_string (self->cancel_label)); g_variant_builder_add (&opt_builder, "{sv}", "modal", g_variant_new_boolean (data->modal)); g_variant_builder_add (&opt_builder, "{sv}", "filters", get_filters (GTK_FILE_CHOOSER (self))); if (GTK_FILE_CHOOSER_NATIVE (self)->current_name) g_variant_builder_add (&opt_builder, "{sv}", "current_name", g_variant_new_string (GTK_FILE_CHOOSER_NATIVE (self)->current_name)); if (GTK_FILE_CHOOSER_NATIVE (self)->current_folder) { gchar *path; path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_folder); g_variant_builder_add (&opt_builder, "{sv}", "current_folder", g_variant_new_bytestring (path)); g_free (path); } if (GTK_FILE_CHOOSER_NATIVE (self)->current_file) { gchar *path; path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_file); g_variant_builder_add (&opt_builder, "{sv}", "current_file", g_variant_new_bytestring (path)); g_free (path); } if (GTK_FILE_CHOOSER_NATIVE (self)->choices) g_variant_builder_add (&opt_builder, "{sv}", "choices", serialize_choices (GTK_FILE_CHOOSER_NATIVE (self))); g_dbus_message_set_body (message, g_variant_new ("(ss@a{sv})", parent_window_str ? parent_window_str : "", gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (self)), g_variant_builder_end (&opt_builder))); g_free (parent_window_str); g_dbus_connection_send_message_with_reply (data->connection, message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, G_MAXINT, NULL, NULL, open_file_msg_cb, data); g_object_unref (message); self->mode_data = data; return TRUE; }
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; }
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; }
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; }