From 2c82651ed5c3591fc31e3e774352fe80225d210b Mon Sep 17 00:00:00 2001 From: Aleksy Barcz Date: Thu, 15 Mar 2018 12:43:28 +0100 Subject: [PATCH] kdbus: make access error behaviour consistent with dbus-daemon Bugfix. When used with dbus-daemon, when an AccessDenied or ServiceUnknown error occurs, gdbus returns a dbus error message to the sender (synchronously or asynchronously) and doesn't set GError. Up to now the kdbus implementation didn't return any error message and did set GError, which made the following low-level functions behaviour inconsistent between dbus-daemon and kdbus: g_dbus_connection_send_message_with_reply_sync g_dbus_connection_send_message_with_reply g_dbus_connection_send_message_with_reply_finish This patch makes this behaviour consistent. Any code that relied on the inconsistent behaviour should be corrected. The high-level function interface, returning GVariants is NOT affected by this change. Change-Id: I60cd4822ccef0e0fc0d7b99244f4ceb03512b97f --- gio/gkdbus.c | 89 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/gio/gkdbus.c b/gio/gkdbus.c index a09aef0..b3885d2 100755 --- a/gio/gkdbus.c +++ b/gio/gkdbus.c @@ -3533,6 +3533,55 @@ compute_msg_size (GDBusMessage *message, return sizeof (struct kdbus_msg) + items_size; } +typedef struct +{ + GKDBusWorker *worker; + GDBusMessage *message; +} SyntheticReplyData; + +static gboolean +deliver_synthetic_reply (gpointer user_data) +{ + SyntheticReplyData *data; + GKDBusWorker *worker; + GDBusMessage *message; + + data = user_data; + worker = data->worker; + message = data->message; + + (* worker->message_received_callback) (message, worker->user_data); + + g_object_unref (message); + g_free (data); + + return FALSE; +} + +static GDBusMessage* +create_access_error_reply (GDBusMessage *message, + GError *error) +{ + GDBusMessage *error_reply; + gchar *dbus_error_name; + dbus_error_name = g_dbus_error_encode_gerror (error); + error_reply = g_dbus_message_new_method_error (message, dbus_error_name, "%s", error->message); + g_free (dbus_error_name); + return error_reply; +} + +static void +send_error_message (GKDBusWorker *worker, + GDBusMessage *message) +{ + SyntheticReplyData *reply_data; + reply_data = g_new0 (SyntheticReplyData, 1); + reply_data->worker = worker; + reply_data->message = message; + g_main_context_invoke (worker->context, deliver_synthetic_reply, reply_data); +} + + /* * _g_kdbus_send */ @@ -3557,6 +3606,8 @@ _g_kdbus_send (GKDBusWorker *worker, gsize header_size; gsize msg_size; + GDBusMessage *access_error_message; + g_return_val_if_fail (G_IS_KDBUS_WORKER (worker), FALSE); send = NULL; @@ -3735,6 +3786,19 @@ _g_kdbus_send (GKDBusWorker *worker, break; } + + access_error_message = create_access_error_reply(message, *error); + g_clear_error(error); /* we send back an error reply, so error must be NULL */ + result = TRUE; + if (out_reply != NULL) + { + *out_reply = access_error_message; + } + else + { + send_error_message(worker, access_error_message); + } + goto out; } } @@ -4011,31 +4075,6 @@ g_kdbus_ready (gint fd, return G_SOURCE_CONTINUE; } -typedef struct -{ - GKDBusWorker *worker; - GDBusMessage *message; -} SyntheticReplyData; - -static gboolean -deliver_synthetic_reply (gpointer user_data) -{ - SyntheticReplyData *data; - GKDBusWorker *worker; - GDBusMessage *message; - - data = user_data; - worker = data->worker; - message = data->message; - - (* worker->message_received_callback) (message, worker->user_data); - - g_object_unref (message); - g_free (data); - - return FALSE; -} - void _g_kdbus_worker_unfreeze (GKDBusWorker *worker) { -- 2.7.4