X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgdbusmethodinvocation.c;h=5bd850b095a4852a07558ebb8d30a6c4f342dafa;hb=174ebaefcc2b1b94f4a628e60f150b7209230dbf;hp=2e6b5e69581055888c867fc117cec2329ed389ca;hpb=30132c44c18d9a08e4c6a9b4834366bd8628ecfa;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c index 2e6b5e6..5bd850b 100644 --- a/gio/gdbusmethodinvocation.c +++ b/gio/gdbusmethodinvocation.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA. + * Public License along with this library; if not, see . * * Author: David Zeuthen */ @@ -32,6 +30,10 @@ #include "gdbuserror.h" #include "gdbusprivate.h" +#ifdef G_OS_UNIX +#include "gunixfdlist.h" +#endif + #include "glibintl.h" /** @@ -81,7 +83,8 @@ struct _GDBusMethodInvocation gchar *object_path; gchar *interface_name; gchar *method_name; - const GDBusMethodInfo *method_info; + GDBusMethodInfo *method_info; + GDBusPropertyInfo *property_info; GDBusConnection *connection; GDBusMessage *message; GVariant *parameters; @@ -99,6 +102,8 @@ g_dbus_method_invocation_finalize (GObject *object) g_free (invocation->object_path); g_free (invocation->interface_name); g_free (invocation->method_name); + if (invocation->method_info) + g_dbus_method_info_unref (invocation->method_info); g_object_unref (invocation->connection); g_object_unref (invocation->message); g_variant_unref (invocation->parameters); @@ -159,6 +164,11 @@ g_dbus_method_invocation_get_object_path (GDBusMethodInvocation *invocation) * * Gets the name of the D-Bus interface the method was invoked on. * + * If this method call is a property Get, Set or GetAll call that has + * been redirected to the method call handler then + * "org.freedesktop.DBus.Properties" will be returned. See + * #GDBusInterfaceVTable for more information. + * * Returns: A string. Do not free, it is owned by @invocation. * * Since: 2.26 @@ -176,6 +186,11 @@ g_dbus_method_invocation_get_interface_name (GDBusMethodInvocation *invocation) * * Gets information about the method call, if any. * + * If this method invocation is a property Get, Set or GetAll call that + * has been redirected to the method call handler then %NULL will be + * returned. See g_dbus_method_invocation_get_property_info() and + * #GDBusInterfaceVTable for more information. + * * Returns: A #GDBusMethodInfo or %NULL. Do not free, it is owned by @invocation. * * Since: 2.26 @@ -188,6 +203,33 @@ g_dbus_method_invocation_get_method_info (GDBusMethodInvocation *invocation) } /** + * g_dbus_method_invocation_get_property_info: + * @invocation: A #GDBusMethodInvocation + * + * Gets information about the property that this method call is for, if + * any. + * + * This will only be set in the case of an invocation in response to a + * property Get or Set call that has been directed to the method call + * handler for an object on account of its property_get() or + * property_set() vtable pointers being unset. + * + * See #GDBusInterfaceVTable for more information. + * + * If the call was GetAll, %NULL will be returned. + * + * Returns: (transfer none): a #GDBusPropertyInfo or %NULL + * + * Since: 2.38 + */ +const GDBusPropertyInfo * +g_dbus_method_invocation_get_property_info (GDBusMethodInvocation *invocation) +{ + g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), NULL); + return invocation->property_info; +} + +/** * g_dbus_method_invocation_get_method_name: * @invocation: A #GDBusMethodInvocation. * @@ -230,9 +272,9 @@ g_dbus_method_invocation_get_connection (GDBusMethodInvocation *invocation) * descriptor passing, that cannot be properly expressed in the * #GVariant API. * - * See and for an example of how to use this - * low-level API to send and receive UNIX file descriptors. + * See this [server][gdbus-server] and [client][gdbus-unix-fd-client] + * for an example of how to use this low-level API to send and receive + * UNIX file descriptors. * * Returns: (transfer none): #GDBusMessage. Do not free, it is owned by @invocation. * @@ -249,9 +291,10 @@ g_dbus_method_invocation_get_message (GDBusMethodInvocation *invocation) * g_dbus_method_invocation_get_parameters: * @invocation: A #GDBusMethodInvocation. * - * Gets the parameters of the method invocation. + * Gets the parameters of the method invocation. If there are no input + * parameters then this will return a GVariant with 0 children rather than NULL. * - * Returns: A #GVariant. Do not free, it is owned by @invocation. + * Returns: (transfer none): A #GVariant tuple. Do not unref this because it is owned by @invocation. * * Since: 2.26 */ @@ -281,11 +324,12 @@ g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation) /* < internal > * _g_dbus_method_invocation_new: - * @sender: The bus name that invoked the method or %NULL if @connection is not a bus connection. + * @sender: (allow-none): The bus name that invoked the method or %NULL if @connection is not a bus connection. * @object_path: The object path the method was invoked on. * @interface_name: The name of the D-Bus interface the method was invoked on. * @method_name: The name of the method that was invoked. - * @method_info: Information about the method call or %NULL. + * @method_info: (allow-none): Information about the method call or %NULL. + * @property_info: (allow-none): Information about the property or %NULL. * @connection: The #GDBusConnection the method was invoked on. * @message: The D-Bus message as a #GDBusMessage. * @parameters: The parameters as a #GVariant tuple. @@ -298,15 +342,16 @@ g_dbus_method_invocation_get_user_data (GDBusMethodInvocation *invocation) * Since: 2.26 */ GDBusMethodInvocation * -_g_dbus_method_invocation_new (const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - const GDBusMethodInfo *method_info, - GDBusConnection *connection, - GDBusMessage *message, - GVariant *parameters, - gpointer user_data) +_g_dbus_method_invocation_new (const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + const GDBusMethodInfo *method_info, + const GDBusPropertyInfo *property_info, + GDBusConnection *connection, + GDBusMessage *message, + GVariant *parameters, + gpointer user_data) { GDBusMethodInvocation *invocation; @@ -323,7 +368,10 @@ _g_dbus_method_invocation_new (const gchar *sender, invocation->object_path = g_strdup (object_path); invocation->interface_name = g_strdup (interface_name); invocation->method_name = g_strdup (method_name); - invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info); + if (method_info) + invocation->method_info = g_dbus_method_info_ref ((GDBusMethodInfo *)method_info); + if (property_info) + invocation->property_info = g_dbus_property_info_ref ((GDBusPropertyInfo *)property_info); invocation->connection = g_object_ref (connection); invocation->message = g_object_ref (message); invocation->parameters = g_variant_ref (parameters); @@ -334,23 +382,10 @@ _g_dbus_method_invocation_new (const gchar *sender, /* ---------------------------------------------------------------------------------------------------- */ -/** - * 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) +static void +g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocation, + GVariant *parameters, + GUnixFDList *fd_list) { GDBusMessage *reply; GError *error; @@ -372,8 +407,8 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, { 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_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; @@ -381,6 +416,67 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, 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 (); @@ -400,10 +496,16 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, 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_warning ("Error sending message: %s", error->message); g_error_free (error); } g_object_unref (reply); @@ -412,11 +514,56 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, g_object_unref (invocation); } +/** + * g_dbus_method_invocation_return_value: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @parameters: (allow-none): 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) +{ + g_dbus_method_invocation_return_value_internal (invocation, parameters, NULL); +} + +#ifdef G_OS_UNIX +/** + * g_dbus_method_invocation_return_value_with_unix_fd_list: + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @parameters: (allow-none): A #GVariant tuple with out parameters for the method or %NULL if not passing any parameters. + * @fd_list: (allow-none): A #GUnixFDList or %NULL. + * + * Like g_dbus_method_invocation_return_value() but also takes a #GUnixFDList. + * + * This method is only available on UNIX. + * + * This method will free @invocation, you cannot use it afterwards. + * + * Since: 2.30 + */ +void +g_dbus_method_invocation_return_value_with_unix_fd_list (GDBusMethodInvocation *invocation, + GVariant *parameters, + GUnixFDList *fd_list) +{ + g_dbus_method_invocation_return_value_internal (invocation, parameters, fd_list); +} +#endif + /* ---------------------------------------------------------------------------------------------------- */ /** * g_dbus_method_invocation_return_error: - * @invocation: A #GDBusMethodInvocation. + * @invocation: (transfer full): A #GDBusMethodInvocation. * @domain: A #GQuark for the #GError error domain. * @code: The error code. * @format: printf()-style format. @@ -428,12 +575,11 @@ g_dbus_method_invocation_return_value (GDBusMethodInvocation *invocation, * will be returned on the wire. In a nutshell, if the given error is * registered using g_dbus_error_register_error() the name given * during registration is used. Otherwise, a name of the form - * org.gtk.GDBus.UnmappedGError.Quark... is - * used. This provides transparent mapping of #GError between - * applications using GDBus. + * `org.gtk.GDBus.UnmappedGError.Quark...` is used. This provides + * transparent mapping of #GError between applications using GDBus. * * If you are writing an application intended to be portable, - * always register errors with g_dbus_error_register_error() + * always register errors with g_dbus_error_register_error() * or use g_dbus_method_invocation_return_dbus_error(). * * This method will free @invocation, you cannot use it afterwards. @@ -463,7 +609,7 @@ g_dbus_method_invocation_return_error (GDBusMethodInvocation *invocation, /** * g_dbus_method_invocation_return_error_valist: - * @invocation: A #GDBusMethodInvocation. + * @invocation: (transfer full): A #GDBusMethodInvocation. * @domain: A #GQuark for the #GError error domain. * @code: The error code. * @format: printf()-style format. @@ -498,7 +644,7 @@ g_dbus_method_invocation_return_error_valist (GDBusMethodInvocation *invocation, /** * g_dbus_method_invocation_return_error_literal: - * @invocation: A #GDBusMethodInvocation. + * @invocation: (transfer full): A #GDBusMethodInvocation. * @domain: A #GQuark for the #GError error domain. * @code: The error code. * @message: The error message. @@ -527,7 +673,7 @@ g_dbus_method_invocation_return_error_literal (GDBusMethodInvocation *invocation /** * g_dbus_method_invocation_return_gerror: - * @invocation: A #GDBusMethodInvocation. + * @invocation: (transfer full): A #GDBusMethodInvocation. * @error: A #GError. * * Like g_dbus_method_invocation_return_error() but takes a #GError @@ -555,8 +701,30 @@ g_dbus_method_invocation_return_gerror (GDBusMethodInvocation *invocation, } /** + * g_dbus_method_invocation_take_error: (skip) + * @invocation: (transfer full): A #GDBusMethodInvocation. + * @error: (transfer full): A #GError. + * + * Like g_dbus_method_invocation_return_gerror() but takes ownership + * of @error so the caller does not need to free it. + * + * This method will free @invocation, you cannot use it afterwards. + * + * Since: 2.30 + */ +void +g_dbus_method_invocation_take_error (GDBusMethodInvocation *invocation, + GError *error) +{ + g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation)); + g_return_if_fail (error != NULL); + g_dbus_method_invocation_return_gerror (invocation, error); + g_error_free (error); +} + +/** * g_dbus_method_invocation_return_dbus_error: - * @invocation: A #GDBusMethodInvocation. + * @invocation: (transfer full): A #GDBusMethodInvocation. * @error_name: A valid D-Bus error name. * @error_message: A valid D-Bus error message. * @@ -583,7 +751,7 @@ g_dbus_method_invocation_return_dbus_error (GDBusMethodInvocation *invocation, g_print ("========================================================================\n" "GDBus-debug:Return:\n" " >>>> METHOD ERROR %s\n" - " message `%s'\n" + " message '%s'\n" " in response to %s.%s()\n" " on object %s\n" " to name %s\n"