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); }
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]); }
/** * g_dbus_method_invocation_return_value: * @invocation: A #GDBusMethodInvocation. * @parameters: A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters. * * Finishes handling a D-Bus method call by returning @parameters. * If the @parameters GVariant is floating, it is consumed. * * It is an error if @parameters is not of the right format. * * This method will free @invocation, you cannot use it afterwards. * * Since: 2.26 */ void g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, GVariant *parameters) { GDBusMessage *reply; GError *error; g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); if (parameters == NULL) parameters = g_variant_new_tuple (NULL, 0); /* if we have introspection data, check that the signature of @parameters is correct */ if (invocation->method_info != NULL) { GVariantType *type; type = _g_dbus_compute_complete_signature (invocation->method_info->out_args); if (!g_variant_is_of_type (parameters, type)) { gchar *type_string = g_variant_type_dup_string (type); g_warning (_("Type of return value is incorrect, got `%s', expected `%s'"), g_variant_get_type_string (parameters), type_string); g_variant_type_free (type); g_free (type_string); goto out; } g_variant_type_free (type); } if (G_UNLIKELY (_g_dbus_debug_return ())) { _g_dbus_debug_print_lock (); g_print ("========================================================================\n" "GDBus-debug:Return:\n" " >>>> METHOD RETURN\n" " in response to %s.%s()\n" " on object %s\n" " to name %s\n" " reply-serial %d\n", invocation->interface_name, invocation->method_name, invocation->object_path, invocation->sender, g_dbus_message_get_serial (invocation->message)); _g_dbus_debug_print_unlock (); } reply = g_dbus_message_new_method_reply (invocation->message); g_dbus_message_set_body (reply, parameters); error = NULL; if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { g_warning (_("Error sending message: %s"), error->message); g_error_free (error); } g_object_unref (reply); out: g_object_unref (invocation); }
static void g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation, GVariant *parameters, GUnixFDList *fd_list) { GDBusMessage *reply; GError *error; g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); if (parameters == NULL) parameters = g_variant_new_tuple (NULL, 0); /* if we have introspection data, check that the signature of @parameters is correct */ if (invocation->method_info != NULL) { GVariantType *type; type = _g_dbus_compute_complete_signature (invocation->method_info->out_args); if (!g_variant_is_of_type (parameters, type)) { gchar *type_string = g_variant_type_dup_string (type); g_warning ("Type of return value is incorrect: expected '%s', got '%s''", type_string, g_variant_get_type_string (parameters)); g_variant_type_free (type); g_free (type_string); goto out; } g_variant_type_free (type); } /* property_info is only non-NULL if set that way from * GDBusConnection, so this must be the case of async property * handling on either 'Get', 'Set' or 'GetAll'. */ if (invocation->property_info != NULL) { if (g_str_equal (invocation->method_name, "Get")) { GVariant *nested; if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(v)"))) { g_warning ("Type of return value for property 'Get' call should be '(v)' but got '%s'", g_variant_get_type_string (parameters)); goto out; } /* Go deeper and make sure that the value inside of the * variant matches the property type. */ g_variant_get (parameters, "(v)", &nested); if (!g_str_equal (g_variant_get_type_string (nested), invocation->property_info->signature)) { g_warning ("Value returned from property 'Get' call for '%s' should be '%s' but is '%s'", invocation->property_info->name, invocation->property_info->signature, g_variant_get_type_string (nested)); g_variant_unref (nested); goto out; } g_variant_unref (nested); } else if (g_str_equal (invocation->method_name, "GetAll")) { if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) { g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", g_variant_get_type_string (parameters)); goto out; } /* Could iterate the list of properties and make sure that all * of them are actually on the interface and with the correct * types, but let's not do that for now... */ } else if (g_str_equal (invocation->method_name, "Set")) { if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT)) { g_warning ("Type of return value for property 'Set' call should be '()' but got '%s'", g_variant_get_type_string (parameters)); goto out; } } else g_assert_not_reached (); } if (G_UNLIKELY (_g_dbus_debug_return ())) { _g_dbus_debug_print_lock (); g_print ("========================================================================\n" "GDBus-debug:Return:\n" " >>>> METHOD RETURN\n" " in response to %s.%s()\n" " on object %s\n" " to name %s\n" " reply-serial %d\n", invocation->interface_name, invocation->method_name, invocation->object_path, invocation->sender, g_dbus_message_get_serial (invocation->message)); _g_dbus_debug_print_unlock (); } reply = g_dbus_message_new_method_reply (invocation->message); g_dbus_message_set_body (reply, parameters); #ifdef G_OS_UNIX if (fd_list != NULL) g_dbus_message_set_unix_fd_list (reply, fd_list); #endif error = NULL; if (!g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error)) { g_warning ("Error sending message: %s", error->message); g_error_free (error); } g_object_unref (reply); out: g_object_unref (invocation); }
static void handle_method_call (GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { if (g_strcmp0 (method_name, "HelloWorld") == 0) { const gchar *greeting; g_variant_get (parameters, "(&s)", &greeting); if (g_strcmp0 (greeting, "Return Unregistered") == 0) { g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED, "As requested, here's a GError not registered (G_IO_ERROR_FAILED_HANDLED)"); } else if (g_strcmp0 (greeting, "Return Registered") == 0) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_MATCH_RULE_NOT_FOUND, "As requested, here's a GError that is registered (G_DBUS_ERROR_MATCH_RULE_NOT_FOUND)"); } else if (g_strcmp0 (greeting, "Return Raw") == 0) { g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.SomeErrorName", "As requested, here's a raw D-Bus error"); } else { gchar *response; response = g_strdup_printf ("You greeted me with '%s'. Thanks!", greeting); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", response)); g_free (response); } } else if (g_strcmp0 (method_name, "EmitSignal") == 0) { GError *local_error; gdouble speed_in_mph; gchar *speed_as_string; g_variant_get (parameters, "(d)", &speed_in_mph); speed_as_string = g_strdup_printf ("%g mph!", speed_in_mph); local_error = NULL; g_dbus_connection_emit_signal (connection, NULL, object_path, interface_name, "VelocityChanged", g_variant_new ("(ds)", speed_in_mph, speed_as_string), &local_error); g_assert_no_error (local_error); g_free (speed_as_string); g_dbus_method_invocation_return_value (invocation, NULL); } else if (g_strcmp0 (method_name, "GimmeStdout") == 0) { #ifdef G_OS_UNIX if (g_dbus_connection_get_capabilities (connection) & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING) { GDBusMessage *reply; GUnixFDList *fd_list; GError *error; fd_list = g_unix_fd_list_new (); error = NULL; g_unix_fd_list_append (fd_list, STDOUT_FILENO, &error); g_assert_no_error (error); reply = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); g_dbus_message_set_unix_fd_list (reply, fd_list); error = NULL; g_dbus_connection_send_message (connection, reply, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, /* out_serial */ &error); g_assert_no_error (error); g_object_unref (invocation); g_object_unref (fd_list); g_object_unref (reply); } else { g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.Failed", "Your message bus daemon does not support file descriptor passing (need D-Bus >= 1.3.0)"); } #else g_dbus_method_invocation_return_dbus_error (invocation, "org.gtk.GDBus.NotOnUnix", "Your OS does not support file descriptor passing"); #endif } }
static void test_once (Fixture *f, gconstpointer context) { GDBusMessage *message; gboolean pipe_res; pipe_res = g_unix_open_pipe (f->server_to_client, FD_CLOEXEC, &f->error); g_assert (pipe_res); pipe_res = g_unix_open_pipe (f->client_to_server, FD_CLOEXEC, &f->error); g_assert (pipe_res); f->server_iostream = my_io_stream_new_for_fds (f->client_to_server[0], f->server_to_client[1]); f->iostream = my_io_stream_new_for_fds (f->server_to_client[0], f->client_to_server[1]); g_dbus_connection_new (f->server_iostream, f->guid, (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER | G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS), NULL /* auth observer */, NULL /* cancellable */, on_new_conn, &f->server_conn); g_dbus_connection_new (f->iostream, NULL, G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL /* auth observer */, NULL /* cancellable */, on_new_conn, &f->connection); while (f->server_conn == NULL || f->connection == NULL) g_main_context_iteration (NULL, TRUE); /* * queue a message - it'll sometimes be sent while the close is pending, * triggering the bug */ message = g_dbus_message_new_signal ("/", "com.example.Foo", "Bar"); g_dbus_connection_send_message (f->connection, message, 0, NULL, &f->error); g_assert_no_error (f->error); g_object_unref (message); /* close the connection (deliberately or via last-unref) */ if (g_strcmp0 (context, "unref") == 0) { g_clear_object (&f->connection); } else { g_dbus_connection_close_sync (f->connection, NULL, &f->error); g_assert_no_error (f->error); } /* either way, wait for the connection to close */ while (!g_dbus_connection_is_closed (f->server_conn)) g_main_context_iteration (NULL, TRUE); /* clean up before the next run */ g_clear_object (&f->iostream); g_clear_object (&f->server_iostream); g_clear_object (&f->connection); g_clear_object (&f->server_conn); g_clear_error (&f->error); }
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; }
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); }