summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@redhat.com>2015-03-27 08:44:50 -0400
committerDan Winship <danw@redhat.com>2015-04-02 10:06:35 -0400
commit57c0322b0b7e95bb4286934acc4298148f38a128 (patch)
tree2838106c9aadb56863be0caf933fc20b8473127e
parentd2a090417ff7d08cd3efa235db208db73f0e2cb6 (diff)
downloadNetworkManager-57c0322b0b7e95bb4286934acc4298148f38a128.tar.gz
libnm-core: add _nm_dbus_proxy_call_sync(), _nm_dbus_proxy_call_finish()
Add versions of g_dbus_proxy_call_sync() and g_dbus_proxy_call_finish() that also typecheck the response and return an error if it is incorrect.
-rw-r--r--libnm-core/nm-core-internal.h14
-rw-r--r--libnm-core/nm-dbus-utils.c87
2 files changed, 101 insertions, 0 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 002f183f01..43021a8fdf 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -151,4 +151,18 @@ gulong _nm_dbus_signal_connect_data (GDBusProxy *proxy,
#define _nm_dbus_signal_connect(proxy, name, signature, handler, data) \
_nm_dbus_signal_connect_data (proxy, name, signature, handler, data, NULL, (GConnectFlags) 0)
+GVariant *_nm_dbus_proxy_call_finish (GDBusProxy *proxy,
+ GAsyncResult *res,
+ const GVariantType *reply_type,
+ GError **error);
+
+GVariant *_nm_dbus_proxy_call_sync (GDBusProxy *proxy,
+ const gchar *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ gint timeout_msec,
+ GCancellable *cancellable,
+ GError **error);
+
#endif
diff --git a/libnm-core/nm-dbus-utils.c b/libnm-core/nm-dbus-utils.c
index aa1fdd9387..2fdedfac6e 100644
--- a/libnm-core/nm-dbus-utils.c
+++ b/libnm-core/nm-dbus-utils.c
@@ -174,3 +174,90 @@ _nm_dbus_signal_connect_data (GDBusProxy *proxy,
*
* Returns: the signal handler ID, as with _nm_signal_connect_data().
*/
+
+
+static void
+typecheck_response (GVariant **response,
+ const GVariantType *reply_type,
+ GError **error)
+{
+ if (*response && reply_type && !g_variant_is_of_type (*response, reply_type)) {
+ /* This is the same error code that g_dbus_connection_call() returns if
+ * @reply_type doesn't match.
+ */
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Method returned type '%s', but expected '%s'",
+ g_variant_get_type_string (*response),
+ g_variant_type_peek_string (reply_type));
+ g_clear_pointer (response, g_variant_unref);
+ }
+}
+
+/**
+ * _nm_dbus_proxy_call_finish:
+ * @proxy: A #GDBusProxy.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to
+ * g_dbus_proxy_call().
+ * @reply_type: (allow-none): the expected type of the reply, or %NULL
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes an operation started with g_dbus_proxy_call(), as with
+ * g_dbus_proxy_call_finish(), except thatif @reply_type is non-%NULL, then it
+ * will also check that the response matches that type signature, and return
+ * an error if not.
+ *
+ * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
+ * return values. Free with g_variant_unref().
+ */
+GVariant *
+_nm_dbus_proxy_call_finish (GDBusProxy *proxy,
+ GAsyncResult *res,
+ const GVariantType *reply_type,
+ GError **error)
+{
+ GVariant *ret;
+
+ ret = g_dbus_proxy_call_finish (proxy, res, error);
+ typecheck_response (&ret, reply_type, error);
+ return ret;
+}
+
+/**
+ * _nm_dbus_proxy_call_sync:
+ * @proxy: A #GDBusProxy.
+ * @method_name: Name of method to invoke.
+ * @parameters: (allow-none): A #GVariant tuple with parameters for the signal
+ * or %NULL if not passing parameters.
+ * @reply_type: (allow-none): the expected type of the reply, or %NULL
+ * @flags: Flags from the #GDBusCallFlags enumeration.
+ * @timeout_msec: The timeout in milliseconds (with %G_MAXINT meaning
+ * "infinite") or -1 to use the proxy default timeout.
+ * @cancellable: (allow-none): A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronously invokes the @method_name method on @proxy, as with
+ * g_dbus_proxy_call_sync(), except that if @reply_type is non-%NULL, then the
+ * reply to the call will be checked against it, and an error returned if it
+ * does not match.
+ *
+ * Returns: %NULL if @error is set. Otherwise a #GVariant tuple with
+ * return values. Free with g_variant_unref().
+ */
+GVariant *
+_nm_dbus_proxy_call_sync (GDBusProxy *proxy,
+ const gchar *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ gint timeout_msec,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GVariant *ret;
+
+ ret = g_dbus_proxy_call_sync (proxy, method_name, parameters,
+ flags, timeout_msec,
+ cancellable, error);
+ typecheck_response (&ret, reply_type, error);
+ return ret;
+}