diff options
author | Dan Winship <danw@redhat.com> | 2015-03-27 08:44:50 -0400 |
---|---|---|
committer | Dan Winship <danw@redhat.com> | 2015-04-02 10:06:35 -0400 |
commit | 57c0322b0b7e95bb4286934acc4298148f38a128 (patch) | |
tree | 2838106c9aadb56863be0caf933fc20b8473127e | |
parent | d2a090417ff7d08cd3efa235db208db73f0e2cb6 (diff) | |
download | NetworkManager-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.h | 14 | ||||
-rw-r--r-- | libnm-core/nm-dbus-utils.c | 87 |
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; +} |