diff options
author | Ryan Lortie <desrt@desrt.ca> | 2005-03-09 23:12:24 +0000 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2005-03-09 23:12:24 +0000 |
commit | b61b94a14488f22ab7f136dc0a9f6c7787d3f510 (patch) | |
tree | 1878d5c76eddd11c13585ae213c1b66c1d7065a3 | |
parent | 59948748b24ca6f266b1eb957849e3d3127242bd (diff) |
This commit was manufactured by cvs2svn to create tag 'dbus-0.23.3'.dbus-0.23.3
-rw-r--r-- | ChangeLog | 1508 | ||||
-rw-r--r-- | NEWS | 41 | ||||
-rw-r--r-- | bus/policy.c | 5 | ||||
-rw-r--r-- | bus/session.conf.in | 2 | ||||
-rw-r--r-- | configure.in | 78 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 466 | ||||
-rw-r--r-- | dbus/dbus-object-tree.c | 459 | ||||
-rw-r--r-- | dbus/dbus-pending-call.c | 18 | ||||
-rw-r--r-- | dbus/dbus-server-protected.h | 22 | ||||
-rw-r--r-- | dbus/dbus-server-unix.c | 39 | ||||
-rw-r--r-- | dbus/dbus-server.c | 317 | ||||
-rw-r--r-- | dbus/dbus-transport-unix.c | 6 | ||||
-rw-r--r-- | dbus/dbus-transport.c | 221 | ||||
-rw-r--r-- | glib/dbus-gproxy.c | 842 | ||||
-rw-r--r-- | mono/Arguments.cs | 12 | ||||
-rw-r--r-- | mono/Connection.cs | 13 | ||||
-rw-r--r-- | mono/DBusType/ObjectPath.cs | 20 | ||||
-rw-r--r-- | mono/DBusType/String.cs | 21 | ||||
-rw-r--r-- | mono/Service.cs | 22 | ||||
-rw-r--r-- | python/dbus_bindings.pyx.in | 722 |
20 files changed, 971 insertions, 3863 deletions
@@ -1,3 +1,9 @@ +2005-03-9 Joe Shaw <joeshaw@novell.com> + + * NEWS: Update for 0.23.3 + + * configure.in: Release 0.23.3 + 2005-03-09 Joe Shaw <joeshaw@novell.com> * dbus/dbus-object-tree.c @@ -5,61 +11,6 @@ and we try to unregister a path that's not registered, still go through the process of unlocking and don't just return. -2005-03-09 Colin Walters <walters@verbum.org> - - * glib/dbus-gproxy.c (dbus_g_proxy_invoke): New method; calls - to this are generated for client-side wrappers. Invokes a - D-BUS method and returns reply values. - - * glib/dbus-binding-tool-glib.c (write_args_sig_for_direction): New - function; writes signature string for argument direction. - (write_args_for_direction): Change to pass input values directly - instead of via address, and fix indentation. - (generate_client_glue): Change to invoke dbus_g_proxy_invoke. Also - make generated wrappers inlineable. - - * dbus/dbus-message.c (dbus_message_iter_get_fixed_array): Add - note about using dbus_type_is_fixed. - - * dbus/dbus-marshal-basic.c (_dbus_type_is_fixed): Moved to - dbus/dbus-signature.c as dbus_type_is_fixed. - - All callers updated. - - * dbus/dbus-signature.c (dbus_type_is_fixed): Moved here - from dbus/dbus-marshal-basic.c:_dbus_type_is_fixed. - - * dbus/dbus-signature.h: Prototype. - - * glib/dbus-binding-tool-glib.c (compute_marshaller_name): Fix - error printf code. - - * test/glib/test-dbus-glib.c (main): Be sure to clear error as - appropriate instead of just freeing it. - (main): Free returned strings using g_free. - - * test/glib/Makefile.am (test-service-glib-glue.h) - (test-service-glib-bindings.h): Add dependency on dbus-binding-tool. - - * glib/dbus-gvalue.c (MAP_BASIC): Refactored from MAP_BASIC_INIT; - simply maps a simple D-BUS type to GType. - (dbus_dbus_type_to_gtype): Function which maps D-BUS type to - GType. - (dbus_gvalue_init): Just invoke dbus_dbus_type_to_gtype and - initialize the value with it. - (dbus_gvalue_binding_type_from_type): Unused, delete. - (dbus_gvalue_demarshal): Switch to hardcoding demarshalling for - various types instead of unmarshalling to value data directly. - Remove can_convert boolean. - (dbus_gvalue_marshal): Remove duplicate initialization; switch to - returning directly instead of using can_convert boolean. - (dbus_gvalue_store): New function; not related to D-BUS per-se. - Stores a GValue in a pointer to a value of its corresponding C - type. - - * glib/dbus-gvalue.h: Remove dbus_gvalue_binding_type_from_type, - add dbus_gvalue_store. - 2005-03-08 Joe Shaw <joeshaw@novell.com> Fix a bunch of lifecycle and memory management problems @@ -115,632 +66,50 @@ 2005-03-08 Joe Shaw <joeshaw@novell.com> - * dbus/dbus-connection.c (dbus_connection_send_with_reply): - After we attach our pending call to the connection, unref - it. Fixes a leak. - - * mono/Connection.cs (set_RawConnection): Disconnect our - filter and match callbacks from the old connection and - reconnect them to the new connection, if any. - - * mono/DBusType/Array.cs: "Code" is a static member, so - don't use "this" to refer to it. Fix for stricter checking - in Mono 1.1.4. - - * mono/DBusType/ObjectPath.cs (Append): Don't leak the - object path that we pass into unmanaged code. - - * mono/DBusType/String.cs (Append): Don't leak the string - that we pass into unmanged code. - -2005-03-07 John (J5) Palmieri <johnp@redhat.com> - * NEWS: Update for 0.31 - - * configure.in: Release 0.31 - add LT_CURRENT, LT_REVISION, LT_AGE for easy soname bumping - - * qt/Makefile.am: fixed build - - * dbus/Makefile.am: soname bump for libdbus - - * glib/Makefile.am: soname bump for libdbus-glib - -2005-03-05 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-sysdeps.c: - (pseudorandom_generate_random_bytes_buffer): fix to have no return - value - (_dbus_generate_random_bytes_buffer): fix return value - - * dbus/dbus-sysdeps-util.c: s/GETPWNAME/GETPWNAM/ so configure - checks actually work, from Tom Parker <fdo@tevp.net> - -2005-03-01 Colin Walters <walters@verbum.org> - - * test/glib/test-dbus-glib.c (lose, lose_gerror): Utility - functions copied from dbus-glib-tool.c. - (main): Convert lots of error code to use them. - Also add some testing for introspection bits. - -2005-03-01 Colin Walters <walters@verbum.org> - - * doc/TODO: Remove introspection signature TODO. - -2005-02-27 Colin Walters <walters@verbum.org> - - * glib/dbus-gidl.c (property_info_get_type, arg_info_get_type): - Change return value to const char * instead of int so we can do - full signatures. - (struct PropertyInfo, struct ArgInfo): Store char *. - (property_info_new, arg_info_new): Update parameters, strdup. - (property_info_unref, arg_info_unref): Free. - - * glib/dbus-gidl.h: Update prototypes. - - * glib/dbus-gparser.c (basic_type_from_string): Delete. - (validate_signature): New function, just validates signature and - sets GError. - (parse_property, parse_arg): Invoke validate_signature. Store - signature instead of just type code. - - * glib/dbus-gvalue.c (base_type_from_signature): New utility - function to return a primary type for a signature, dropping - information about types in container types. - (dbus_gvalue_genmarshal_name_from_type) - (dbus_gvalue_binding_type_from_type) - (dbus_gvalue_ctype_from_type): Update to take full signature - instead of type code. - (dbus_gtype_to_dbus_type): Moved here from glib/dbus-gobject.c. - - * glib/dbus-gvalue.h: Update prototypes for above. - - * glib/dbus-gobject.c (gtype_to_dbus_type): Moved to - glib/dbus-gvalue.c as dbus_gtype_to_dbus_type. - (introspect_properties, introspect_signals, write_interface): - Update to handle signatures, and remove usage of - _dbus_gutils_type_to_string. - (handle_introspect): Print out type codes instead of e.g. "string" - in hardcoded introspection XML; also use x_AS_STRING constants - instead of hardcoding in string. - - * glib/dbus-glib-tool.c (pretty_print): Handle signature change - to string. Remove usage of _dbus_gutils_type_to_string. - - * glib/dbus-gutils.c (_dbus_gutils_type_to_string): Delete. - - * glib/dbus-gutils.h (_dbus_gutils_type_to_string): Update for - deletion. - - * glib/dbus-binding-tool-glib.c (compute_marshaller) - (compute_marshaller_name, generate_glue): Handle signature change - to string. - (write_formal_parameters, write_args_for_direction): Ditto, and - remove FIXME. - - * tools/dbus-tree-view.c (type_to_string): Delete. - (info_set_func_text): Update to print full signatures. - - * test/glib/test-service-glib.xml: Change types to new - introspection format. - -2005-02-26 Havoc Pennington <hp@redhat.com> - - * doc/TODO: remove the "guid" item - - * test/glib/test-profile.c (no_bus_thread_func): use open_private - (with_bus_thread_func): use open_private - - * dbus/dbus-connection.c (dbus_connection_open_private): new - function that works like the old dbus_connection_open() - (dbus_connection_open): now returns an existing connection if - possible - - * dbus/dbus-server-unix.c (handle_new_client_fd_and_unlock): pass - through the GUID to the transport - - * dbus/dbus-server.c (_dbus_server_init_base): keep around the - GUID in hex-encoded form. - - * dbus/dbus-server-debug-pipe.c (_dbus_transport_debug_pipe_new): - pass GUID argument in to the transport - - * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd): add - guid argument - - * dbus/dbus-transport.c (_dbus_transport_init_base): add guid argument - - * dbus/dbus-auth.c (_dbus_auth_server_new): add guid argument - -2005-02-25 Havoc Pennington <hp@redhat.com> - - * doc/dbus-specification.xml: document the GUID thing - - * dbus/dbus-server.c (_dbus_server_init_base): initialize a - globally unique ID for the server, and put a "guid=hexencoded" - field in the address - - * dbus/dbus-bus.c: fix missing #include of dbus-threads-internal.h - - * dbus/dbus-message.c: ditto - - * dbus/dbus-dataslot.c: ditto - - * dbus/dbus-list.c: ditto - - * dbus/dbus-internals.h: wait, just include - dbus-threads-internal.h here - - * dbus/dbus-string.c (_dbus_string_copy_to_buffer): move back for - use in main library - - * dbus/dbus-sysdeps.c (_dbus_generate_random_bytes_buffer): new function - -2005-02-24 Colin Walters <walters@verbum.org> - - * test/glib/Makefile.am (EXTRA_DIST): Add test-service-glib.xml - -2005-02-24 John (J5) Palmieir <johnp@redhat.com> - - * glib/Makefile.am: added dbus-gobject.h to sources list - so distcheck doesn't fail - -2005-02-24 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-server.c, dbus/dbus-server-unix.c: change semantics so - you must disconnect before unref, since locking and other things - are screwed up otherwise. Fix assorted other locking stuff. - - * dbus/dbus-signature.c (dbus_signature_iter_get_element_type): - fix compilation - - * dbus/dbus-threads-internal.h: move the mutex/condvar wrappers - into a private header and don't export from the library - - * throughout - call _dbus_thread_stuff vs. dbus_thread_stuff - -2005-02-24 Colin Walters <walters@verbum.org> - - * dbus/dbus-signature.c: New file; implements various functions - related to type signatures. Includes an interator for parsing, - validation functions. - (dbus_type_is_basic): Moved here from - dbus-marshal-basic.c:_dbus_type_is_basic. - (dbus_type_is_container): Moved here from - dbus-marshal-basic.c:_dbus_type_is_container. - - All callers of _dbus_type_is_container and _dbus_type_is_basic - updated, and include dbus-signature.h. - - * dbus/dbus-signature.h: New file; prototypes for the above. - - * dbus/Makefile.am (DBUS_LIB_SOURCES): Add dbus-signature.c, - dbus-signature.h. - - * dbus/dbus-marshal-basic.c (map_type_char_to_type): New utility - function factored out of _dbus_first_type_in_signature. - (_dbus_first_type_in_signature_c_str): New function; returns first - type code for a type signature character. - - * dbus/dbus-marshal-basic.h: Prototype _dbus_first_type_in_signature_c_str, - handle function moves. - - * dbus/dbus-marshal-recursive.h: Export _dbus_type_signature_next. - - * dbus/dbus-marshal-recursive.c (_dbus_type_signature_next): New - function; skips to next complete type in type signature. - Implemented using previous skip_one_complete_type. Now - skip_one_complete_type just delegates to - _dbus_type_signature_next. - - * dbus/dbus-marshal-basic.c (_dbus_type_is_basic): Moved - to dbus-signature.c - (_dbus_type_is_container): Ditto. - - * doc/dbus-specification.xml: Update introspection sample to - use real type signatures. - - * dbus/dbus-test.h: Prototype signature test. - - * dbus/dbus-test.c (dbus_internal_do_not_use_run_tests): Run - signature tests. - - * dbus/dbus-protocol.h (DBUS_ERROR_INVALID_SIGNATURE): New error. - -2005-02-23 John (J5) Palmieri <johnp@redhat.com> + * dbus/dbus-connection.c (dbus_connection_send_with_reply): + After we attach our pending call to the connection, unref + it. Fixes a leak. - * python/dbus_bindings.pyx.in (PendingCall::get_reply): - s/dbus_pending_call_get_reply/dbus_pending_call_steal_reply + * dbus/dbus-pending-call.c (dbus_pending_call_get_reply): + Add this back. Accidentally broke API/ABI compat. -2005-02-21 Colin Walters <walters@verbum.org> + * mono/Connection.cs (set_RawConnection): Disconnect our + filter and match callbacks from the old connection and + reconnect them to the new connection, if any. - * dbus/dbus-test-main.c (main): Take optional specific test - argument. - - * dbus/dbus-test.c (run_test): New function, runs a test function - with no data directory. - (run_data_test): Like above, but takes data directory. - (dbus_internal_do_not_use_run_tests): Take - specific test argument. Replace lots of cut n' paste code - with run_test and run_data_test. - - * dbus/dbus-test.h: Update prototype for - dbus_internal_do_not_use_run_tests. - -2005-02-20 Havoc Pennington <hp@redhat.com> - - Fix bugs reported by Daniel P. Berrange - - * dbus/dbus-server.c (_dbus_server_unref_unlocked): new function - (protected_change_watch): new function - (_dbus_server_toggle_watch, _dbus_server_remove_watch) - (_dbus_server_add_watch): change to work like the - dbus-connection.c equivalents; like those, probably kind of - busted, but should at least mostly work for now - (dbus_server_disconnect): drop the lock if we were already - disconnected, patch from Daniel P. Berrange - - * dbus/dbus-server.c (_dbus_server_toggle_timeout) - (_dbus_server_remove_timeout, _dbus_server_add_timeout): all the - same stuff - - * doc/TODO: todo about unscrewing this mess - -2005-02-19 Colin Walters <walters@verbum.org> - - * glib/dbus-binding-tool-glib.c - (dbus_binding_tool_output_glib_server): Fix iochannel refcounting. - - * glib/dbus-glib-tool.c: Include dbus-glib-tool.h, as well - as errno.h and sys/stat.h. - (lose): New function, prints error with - newline and exits. - (lose_gerror): Similar, but takes GError for message. - (main): Add --output argument to specify output file to write to, - instead of always printing to stdout. In this mode, determine - timestamps on source files to see whether any are newer than the - target file. If not, exit. Also convert a number of error - messages to use lose (since it's shorter), and switch to using - g_io_channel_shutdown. - -2005-02-19 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gobject.c - (_dbus_glib_marshal_dbus_message_to_gvalue_array): add docs - - * glib/dbus-glib.c: fix doxygen warnings - - * glib/dbus-gparser.c (parse_annotation): error if an annotation - is found on an <arg> - -2005-02-17 Colin Walters <walters@verbum.org> - - * glib/dbus-gobject.h: Don't export - _dbus_glib_marshal_dbus_message_to_gvalue_array. - - * glib/dbus-gobject.c (_dbus_glib_marshal_dbus_message_to_gvalue_array): Do rename. - (invoke_object_method): Handle it. - - * glib/dbus-gproxy.c (marshal_dbus_message_to_g_marshaller): - Handle rename. - -2005-02-17 Colin Walters <walters@verbum.org> - - * bus/.cvsignore, doc/.cvsignore - * test/data/valid-service-files/.cvsignore, test/glib/.cvsignore: - Update. - -2005-02-17 Colin Walters <walters@verbum.org> - - * dbus/dbus-protocol.h (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS): - Rename to DBUS_SERVICE_DBUS. - (DBUS_PATH_ORG_FREEDESKTOP_DBUS): Rename to DBUS_PATH_DBUS. - (DBUS_PATH_ORG_FREEDESKTOP_LOCAL): Rename to DBUS_PATH_LOCAL. - Change the value from "org.freedesktop.Local" - to "org.freedesktop.DBus.Local". - (DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS): Rename to DBUS_INTERFACE_DBUS. - (DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE): Rename to - DBUS_INTERFACE_INTROSPECTABLE. - Change the value from "org.freedesktop.Introspectable" - to "org.freedesktop.DBus.Introspectable". - (DBUS_INTERFACE_ORG_FREEDESKTOP_PROPERTIES): Rename to - DBUS_INTERFACE_PROPERTIES. - Change the value from "org.freedesktop.Properties" - to "org.freedesktop.DBus.Properties". - (DBUS_INTERFACE_ORG_FREEDESKTOP_PEER): Rename to - DBUS_INTERFACE_PEER. - Change the value from "org.freedesktop.Peer" - to "org.freedesktop.DBus.Peer". - (DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL): - DBUS_INTERFACE_LOCAL. - Change the value from "org.freedesktop.Local" - to "org.freedesktop.DBus.Local". - - All other users of those constants have been changed. - - * bus/driver.c (bus_driver_handle_introspect): Use constants. - - * glib/dbus-gobject.c (handle_introspect): Use constants. - - * doc/dbus-faq.xml, doc/dbus-specification.xml: Update for rename. - -2005-02-17 Colin Walters <walters@verbum.org> - - * glib/dbus-gparser.c (struct Parser): Add in_annotation boolean. - (parse_node, parse_interface, parse_method, parse_signal) - (parse_property, parse_annotation): Lose if we're currently in an - annotation. - (parse_annotation): New function. - (parser_start_element, parser_end_element): Handle annotation. - (parse_method, parse_interface): Remove support for c_name attribute, - switch to annotations. - - * glib/dbus-gidl.h (interface_info_get_binding_names) - (method_info_get_binding_names) - (interface_info_get_binding_name, method_info_get_binding_name) - (interface_info_set_binding_name, method_info_set_binding_name): - Remove. - (interface_info_get_annotations, method_info_get_annotations) - (interface_info_get_annotation, method_info_get_annotation) - (interface_info_add_annotation, method_info_add_annotation): - Prototype. - - * glib/dbus-gidl.c (struct InterfaceInfo): Substitute "annotations" - for "bindings". - (struct MethodInfo): Ditto. - Straightfoward conversion of binding methods into annotation methods - as prototyped. - - * glib/dbus-glib-tool.c (pretty_print): Print annotations. - - * glib/dbus-binding-tool-glib.h (DBUS_GLIB_ANNOTATION_C_SYMBOL): Define. - - * glib/dbus-binding-tool-glib.c (gather_marshallers, generate_glue): - Use new annotation API. - - * doc/introspect.dtd: Fix a number of DTD syntax errors. Add - annotation element. - - * doc/dbus-specification.xml: Discuss introspection annotations, - include list of well-known annotations. - - * test/glib/test-service-glib.xml: Make validate against new DTD. - -2005-02-17 Colin Walters <walters@verbum.org> - - This patch is based on initial work from - Paul Kuliniewicz <kuliniew@purdue.edu>. - - * glib/dbus-gvalue.c (dbus_gvalue_init): New function; move - initialization of GValue from dbus type to here. - (dbus_gvalue_genmarshal_name_from_type): New function; generates a string - for the "glib-genmarshal" program from a DBus type. - (dbus_gvalue_binding_type_from_type): New function; turns a DBus type - into the C name for it we use in the glib bindings. - (dbus_gvalue_ctype_from_type): New function; maps a DBus type into a - glib C type (not GValue). - (dbus_gvalue_demarshal): invoke dbus_gvalue_init. - - * glib/dbus-gutils.c (_dbus_gutils_wincaps_to_uscore): Moved here - from dbus-gobject.c. - - * glib/dbus-gutils.h: Prototype it. - - * glib/dbus-gproxy.c: Include new dbus-gobject.h. - (marshal_dbus_message_to_g_marshaller): Use new shared function - dbus_glib_marshal_dbus_message_to_gvalue_array. - - * glib/dbus-gparser.c (parse_interface, parse_method): Handle c_name attribute. - Will be changed once we have annotations. - - * glib/dbus-gobject.c: Change info_hash_mutex from GStaticMutex to - GStaticRWLock. Callers updated. - (wincaps_to_uscore): Move to dbus-gutils.c. Callers updated. - (string_table_next): New function for iterating over zero-terminated - string value array. - (string_table_lookup): New function; retrieves specific entry in - array. - (get_method_data): New function; look up method data in object data chunk. - (object_error_domain_prefix_from_object_info) - (object_error_code_from_object_info): New functions, but not implemented yet. - (method_interface_from_object_info): New function; retrieve interface name. - (method_name_from_object_info): New function; retrieve method name. - (method_arg_info_from_object_info): New function; retrieve argument data. - (arg_iterate): New function; iterates over serialized argument data. - (method_dir_signature_from_object_info): New function; returns a - GString holding type signature for arguments for just one - direction (input or output). - (method_input_signature_from_object_info) - (method_output_signature_from_object_info): New functions. - (dbus_glib_marshal_dbus_message_to_gvalue_array): New shared function; - converts dbus message arguments into a GValue array. Used for both - signal handling and method invocation. - (struct DBusGlibWriteIterfaceData): New utility structure. - (write_interface): New function; generate introspection XML for - an interface. - (introspect_interfaces): New function; gathers all interface->methods, - generates introspection XML for them. - (handle_introspect): Invoke introspect_interfaces. - (get_object_property): Be sure to zero-initalize stack-allocated GValue. - (lookup_object_and_method): New function; examines an incoming message - and attempts to match it up (via interface, method name, and argument - signature) with a known object and method. - (gerror_domaincode_to_dbus_error_name): New function; converts a - GError domain and code into a DBus error name. Needs GError data - added to object introspection to work well. - (gerror_to_dbus_error_message): Creates a DBusMessage error return from - GError. - (invoke_object_method): New function to invoke an object method - looked up via lookup_object_and_method. Parses the incoming - message, turns it into a GValue array, then invokes the marshaller - specified in the DBusGMethodInfo. Creates a new message with - either return values or error message as appropriate. - (gobject_message_function): Invoke lookup_object_and_method and - invoke_object_method. - - * glib/dbus-glib-tool.c: Include dbus-binding-tool-glib.h. - (enum DBusBindingOutputMode): New enum for binding output modes. - (pretty_print): Print binding names. - (dbus_binding_tool_error_quark): GError bits. - (version): Fix typo. - (main): Create GIOChannel for output. Parse new --mode argument, - possible values are "pretty-print", "glib-server", "glib-client". - Use mode to invoke appropriate function. - - * glib/dbus-gobject.h: Prototype dbus_glib_marshal_dbus_message_to_gvalue_array. - - * glib/dbus-glib-tool.h: New header, just includes GError bits - for now. - - * glib/dbus-gidl.c (struct InterfaceInfo): Add bindings hashtable; - maps binding style to name. - (struct MethodInfo): Ditto. - (get_hash_keys, get_hash_key): Utility function, returns keys for - a GHashTable. - (interface_info_new, method_info_new): Initialize bindings. - (interface_info_unref, method_info_unref): Destroy bindings. - (method_info_get_binding_names, method_info_get_binding_name) - (interface_info_get_binding_names, interface_info_get_binding_name): - Functions for retrieving binding names. - (method_info_set_binding_name, interface_info_set_binding_name): - Functions for setting binding names. - - * glib/dbus-binding-tool-glib.h: New file, has prototypes - for glib binding generation. - - * glib/dbus-binding-tool-glib.c: New file, implements server-side - and client-side glib glue generation. - - * glib/Makefile.am (dbus_binding_tool_SOURCES): Add - dbus-binding-tool-glib.c, dbus-binding-tool-glib.h, - dbus-glib-tool.h. - - * dbus/dbus-glib.h (struct DBusGMethodMarshaller): Remove in favor - of using GClosureMarshal directly. - (struct DBusGObjectInfo): Add n_infos member. - - * test/glib/test-service-glib.xml: New file; contains introspection data - for MyTestObject used in test-service-glib.c. - - * test/glib/test-service-glib.c (enum MyObjectError): New GError enum. - (my_object_do_nothing, my_object_increment, my_object_throw_error) - (my_object_uppercase, my_object_many_args): New test methods. - (main): Use dbus_g_object_class_install_info to include generated object - info. - - * test/glib/Makefile.am: Generate server-side glue for test-service-glib.c, - as well as client-side bindings. - - * test/glib/test-dbus-glib.c: Include test-service-glib-bindings.h. - (main): Activate TestSuiteGLibService; test invoke a bunch of its methods - using both the dbus_gproxy stuff directly as well as the generated bindings. - -2005-02-15 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-connection.c (dbus_connection_dispatch): always - complete a pending call, don't run filters first. - - * glib/dbus-gproxy.c (dbus_g_proxy_end_call): change to use - dbus_pending_call_steal_reply - - * dbus/dbus-pending-call.c (dbus_pending_call_block): just call - _dbus_connection_block_pending_call - (dbus_pending_call_get_reply): change to steal_reply and return a - ref - - * dbus/dbus-connection.c - (dbus_connection_send_with_reply_and_block): port to work in terms - of DBusPendingCall - (_dbus_connection_block_pending_call): replace block_for_reply - with this - -2005-02-14 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-userdb-util.c (_dbus_user_database_lookup_group): - properly handle looking up group information by name; fix - from j@bootlab.org - -2005-02-13 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-connection.c (dbus_connection_return_message) - (dbus_connection_borrow_message): hold dispatch lock while message - is outstanding - (_dbus_connection_block_for_reply): hold dispatch lock while we - block for the reply, so nobody steals our reply - (dbus_connection_pop_message): hold the dispatch lock while we - pluck the message - -2005-02-13 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-connection.c (_dbus_connection_acquire_dispatch) - (_dbus_connection_release_dispatch) - (_dbus_connection_acquire_io_path) - (_dbus_connection_release_io_path): make the mutex and condvar - control access to the "acquired" flag. Drop the connection lock - while waiting on the condvar. Hopefully these are baby steps in - roughly the right direction. - -2005-02-13 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-connection.c: use separate mutexes for the condition - variables; this is some kind of baseline for sanity, but the - condition variables still aren't used correctly afaict - -2005-02-13 Havoc Pennington <hp@redhat.com> + * mono/DBusType/ObjectPath.cs (ctor): Don't leak the + object path that we get back from unmanaged code. + (Append): Don't leak the object path that we pass + into unmanaged code. - * dbus/dbus-object-tree.c (handle_default_introspect_and_unlock): - fix a double-unlock + * mono/DBusType/String.cs (ctor): Don't leak the string + that we get back from unmanaged code. + (Append): Don't leak the string that we pass into + unmanaged code. - * dbus/dbus-connection.c - (_dbus_connection_detach_pending_call_unlocked): add this - - Initial semi-correct pass through to fix thread locking; there are - still some issues with the condition variable paths I'm pretty - sure - - * dbus/dbus-server.c: add a mutex on DBusServer and appropriate - lock/unlock calls - - * dbus/dbus-connection.c (_dbus_connection_do_iteration_unlocked): - rename to add _unlocked - (struct DBusConnection): move "dispatch_acquired" and - "io_path_acquired" to use only one bit each. - (CONNECTION_LOCK, CONNECTION_UNLOCK): add checks with !DBUS_DISABLE_CHECKS - (dbus_connection_set_watch_functions): hacky fix to reentrancy - (_dbus_connection_add_watch, _dbus_connection_remove_watch) - (_dbus_connection_toggle_watch, _dbus_connection_add_timeout) - (_dbus_connection_remove_timeout) - (_dbus_connection_toggle_timeout): drop lock when calling out to - user functions; done in a hacky/bad way. - (_dbus_connection_send_and_unlock): add a missing unlock - (_dbus_connection_block_for_reply): add a missing unlock - - * dbus/dbus-transport.c (_dbus_transport_get_is_authenticated): - drop lock in a hacky probably unsafe way to call out to user - function - -2005-02-12 Havoc Pennington <hp@redhat.com> - - * tools/dbus-tree-view.c (info_set_func_text): display more - details on args - - * bus/driver.c (bus_driver_handle_list_services): list the bus - driver - - * glib/dbus-gparser.c (parse_arg): generate an arg name if none is supplied +2005-02-22 Joe Shaw <joeshaw@novell.com> - * glib/dbus-gidl.c (signal_info_get_n_args): new function - (method_info_get_n_args): new function + * python/dbus_bindings.pyx.in: API changed, so call + dbus_pending_call_steal_reply() rather than + dbus_pending_call_get_reply(). Bug and patch from + Jan de Groot. -2005-02-12 Havoc Pennington <hp@redhat.com> +2005-02-18 Joe Shaw <joeshaw@novell.com> + + * NEWS: Update for 0.23.2 + + * configure.in: Release 0.23.2 - * bus/driver.c (bus_driver_handle_introspect): add introspection - for bus driver +2005-02-16 Joe Shaw <joeshaw@novell.com> -2005-02-12 Havoc Pennington <hp@redhat.com> + * dbus/dbus-connection-internal.h, dbus/dbus-connection.[ch], + dbus/dbus-pending-call.[ch], dbus/dbus-server-protected.h, + dbus/dbus-server-unix.c, dbus/dbus-server.c, + dbus/dbus-transport-unix.c, dbus/dbus-transport.c: Backport + a ton of thread-related fixes from HEAD to this branch. - * bus/driver.c: put the signature of each bus driver method in the - table of handlers and check it on incoming calls; this isn't - really useful, but going to add introspect support in a minute. + * glib/dbus-gproxy.c: Update dbus_pending_call_get_reply() to + dbus_pending_call_steal_reply(). 2005-02-11 Joe Shaw <joeshaw@novell.com> @@ -752,91 +121,11 @@ * mono/Service.cs: Remove the code, add code which calls the methods now on the Connection class. -2005-02-11 John (J5) Palmieri <johnp@redhat.com> - - * python/dbus.py (class Sender): added to support dbus signals better - (Bus::add_signal_receiver): added expand_args parameter which defaults - to True. When expand args is True the signal handler will pass the - message arguments as parameters to the signal handler. If False - revert to previous behavior where the signal handler must get the - argument list from the message. This is to help port applications - like HAL that have a tendancy to send variable length argument lists. - self._match_rule_to_receivers is now a dict of dicts. - (Bus::remove_signal_receiver): pop handler off the dict intead of - removing it from a list - (Bus::_signal_func): change signal handlers so that interface, - signal_name, service, path and message are packed into a Sender - object and that is passed to the handler. If expand_args is True - extract the args list from the message and append it to the parameter - list - - * python/dbus_bindings.pyx.in (class Signature): added to support - signiature types - (MessageIter::__init__): changed iteration limit to match D-BUS - (MessageIter::get*): added INT16, UINT16, SIGNATURE, DICT_ENTRY, - STRUCT and VARIENT type support - (MessageIter::python_value_to_dbus_sig): made recursive to support - recursive types - (MessageIter::append*): added Signature, dict, tuple - support - - * python/examples/example-client.py: added examples of getting tuples - and dicts - - * python/examples/example-service.py: added examples of sending tuples - and dicts - - * python/examples/example-signal-recipient.py: Fixed to handle new - signal callback format - -2005-02-10 Havoc Pennington <hp@redhat.com> - - * test/glib/test-dbus-glib.c (main): fix so this test doesn't fail - (call dbus_g_proxy_add_signal) - - * dbus/dbus-server-unix.c (_dbus_server_new_for_tcp_socket): - escape the hostname - (_dbus_server_new_for_domain_socket): escape the path - - * dbus/dbus-address.c (dbus_address_escape_value): new - (dbus_address_unescape_value): new - (dbus_parse_address): unescape values - - * dbus/dbus-string.c (_dbus_string_append_byte_as_hex): new function - - * doc/dbus-specification.xml: explain how to escape values in - addresses - -2005-02-10 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message-factory.c (generate_special): modify test to - avoid using a non-basic dict key - - * dbus/dbus-marshal-validate-util.c: add test for the below - - * doc/dbus-specification.xml: require that dict keys are a basic - type - - * dbus/dbus-marshal-validate.c - (_dbus_validate_signature_with_reason): require that dict key is a - basic type - -2005-02-10 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-object-tree.c (handle_default_introspect_and_unlock): - change to be _and_unlock instead of _unlocked - - * dbus/dbus-connection.c - (_dbus_connection_send_preallocated_unlocked_no_update): rename to - have no_update so we can find this bug quickly in future - -2005-02-10 Havoc Pennington <hp@redhat.com> +2005-02-11 Joe Shaw <joeshaw@novell.com> - * dbus/dbus-message-util.c (verify_test_message): tests for string - array + * NEWS: Update for 0.23.1 - * dbus/dbus-message.c (dbus_message_append_args_valist): add - support for arrays of string/signature/path + * configure.in: Release 0.23.1 2005-02-10 Joe Shaw <joeshaw@novell.com> @@ -862,713 +151,14 @@ we don't get unmanaged code calling back into a GCed delegate. (RemoveFilter); Added. -2005-02-09 John (J5) Palmieri <johnp@redhat.com> - - * dbus/dbus-message.c (dbus_message_iter_open_container): - - Removed check for iterator type being an array because - get_arg_type does not work with writer iterators - - Pass NULL to _dbus_type_writer_recurse if signiture is NULL - -2005-02-07 Havoc Pennington <hp@redhat.com> - - * doc/dbus-specification.xml: some more language cleanups; add - stuff about how to deal with invalid protocol and extension - points; add _ to allowed chars in auth commands; add EXTENSION_ - auth command prefix - -2005-02-06 Havoc Pennington <hp@redhat.com> - - * s/expected/required/ in a couple places for clarity - -2005-02-07 Colin Walters <walters@verbum.org> - - * bus/selinux.c (bus_selinux_allows_send): Handle NULL for - sender or proposed_recipient. - -2005-02-06 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message-factory.c (generate_special): more tests - - * dbus/dbus-marshal-validate.c (validate_body_helper): detect - array length that exceeds the maximum - -2005-02-05 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message-factory.c (generate_special): more test cases, - increasing coverage - - * dbus/dbus-marshal-validate.c (validate_body_helper): return the - reason why a signature was invalid - - * dbus/dbus-marshal-header.c (load_and_validate_field): fix to - skip the length of the string before we look at it in validation - - * dbus/dbus-string-util.c (_dbus_string_test): add tests for - equal_substring - - * dbus/dbus-message.c (_dbus_message_loader_new): default - max_message_length to DBUS_MAXIMUM_MESSAGE_LENGTH - -2005-02-05 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-marshal-validate.c (validate_body_helper): fix crash - if the signature of a variant was empty - (_dbus_validate_signature_with_reason): catch "(a)" (array inside - struct with no element type) - - * dbus/dbus-message-factory.c (generate_uint32_changed): add more - mangled messages to break things - -2005-02-04 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gproxy.c (dbus_g_proxy_disconnect_signal): use - g_quark_try_string() so it actually can return 0 - (dbus_g_proxy_connect_signal): ditto - -2005-02-04 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gproxy.c (dbus_g_proxy_emit_remote_signal): fix a - bogus warning - (tristring_from_message): assert cleanly on null path/interface - (should not be possible though I decided later) - (dbus_g_proxy_dispose): move proxy manager unregistration here - (DBUS_G_PROXY_DESTROYED): add this macro, and use it in a bunch of - g_return_if_fail() checks - -2005-02-04 Havoc Pennington <hp@redhat.com> - - * doc/Makefile.am (EXTRA_DIST): add DTDs to makefile - - * doc/introspect.dtd: add introspect.dtd from David A. Wheeler - (with some minor changes) - - * doc/dbus-specification.xml: add deprecated attribute to - introspection format - 2005-01-31 Havoc Pennington <hp@redhat.com> + + * bus/policy.c (bus_policy_allow_user): change default "user is + allowed" to be "user has same uid as the bus itself"; any + allow/deny rules will override. - * glib/dbus-gproxy.c: rewrite how signals work again, this time I - think it's sort of right - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * tools/dbus-viewer.c: kind of half-ass hook up the option menu. - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * tools/dbus-names-model.c: dynamically watch NameOwnerChanged - - * autogen.sh: change to autotools 1.9 - - * glib/dbus-gproxy.c: completely change how signals work - (dbus_g_proxy_add_signal): new function to specify signature of a - signal - (dbus_g_proxy_emit_received): marshal the dbus message to GValues, - and g_warning if the incoming message has the wrong signature. - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * tools/dbus-names-model.c (have_names_notify): fix this - - * dbus/dbus-message.c (_dbus_message_iter_get_args_valist): clean - up the string array handling a bit - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * glib/dbus-glib.c (dbus_g_pending_call_set_notify): new function - (dbus_g_pending_call_cancel): new function - - * dbus/dbus-glib.h: move GType decls for connection/message here; - * dbus/dbus-glib.c: move all the g_type and ref/unref stuff in - here, just kind of rationalizing how we handle all that - - * tools/dbus-names-model.c: new file for a tree model listing the - services on a bus - - * tools/dbus-tree-view.c (model_new): use proper typing on the - model rows - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gmain.c: add a custom GSource back that just checks - whether the message queue has anything in it; otherwise, there are - cases where we won't see messages in the queue since there was no - IO visible to the glib main loop - - * dbus/dbus-connection-internal.h (_DBUS_DEFAULT_TIMEOUT_VALUE): - increase default message timeout to 25 seconds - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * test/glib/test-profile.c (no_bus_stop_server): remove the - warning about the g_warning that I just fixed - - * glib/dbus-gmain.c: rewrite the main loop stuff to avoid the - custom source, seems to be a lot easier to understand and work - better. - -2005-01-30 Havoc Pennington <hp@redhat.com> - - I think this main loop thing is conceptually broken, but here are - some band aids. I'll maybe rewrite it in a minute. - - * glib/dbus-gmain.c (add_timeout): timeout stuff doesn't use the - custom GSource, so don't pass it in; confusing - (gsource_server_finalize, gsource_connection_finalize): add - finalize handlers that remove all the watches. - -2005-01-30 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gobject.c (introspect_properties): fix the XML - generated - - * dbus/dbus-message.c (dbus_message_unref): add an in_cache flag - which effectively detects the use of freed messages - - * glib/dbus-gobject.c (handle_introspect): modify and return the - reply message instead of the incoming message - - * dbus/dbus-object-tree.c (handle_default_introspect_unlocked): - gee, maybe it should SEND THE XML instead of just making a string - and freeing it again ;-) - - * tools/dbus-print-message.c (print_message): improve printing of - messages - - * configure.in: add debug-glib.service to the output - -2005-01-30 Havoc Pennington <hp@redhat.com> - - dbus-viewer introspected and displayed the bus driver - - * dbus/dbus-object-tree.c - (object_tree_test_iteration): add tests for a handler registered on "/" - - * dbus/dbus-object-tree.c - (_dbus_decompose_path): fix to handle path "/" properly - (run_decompose_tests): add tests for path decomposition - - * glib/dbus-gutils.c (_dbus_gutils_split_path): fix to handle "/" - properly - - * glib/dbus-gobject.c (handle_introspect): fix quotes - - * test/glib/run-test.sh: support launching the bus, then running - dbus-viewer - - * test/glib/test-service-glib.c (main): put in a trivial gobject - subclass and register it on the connection - - * bus/driver.c (bus_driver_handle_introspect): implement - introspection of the bus driver service - - * dbus/dbus-protocol.h: add #defines for the XML namespace, - identifiers, doctype decl - - * bus/driver.c (bus_driver_handle_get_service_owner): handle - attempts to get owner of DBUS_SERVICE_ORG_FREEDESKTOP_DBUS by - returning the service unchanged. - (bus_driver_handle_message): remove old check for reply_serial in - method calls, now the message type deals with that - (bus_driver_handle_message): handle NULL interface - - * glib/dbus-gproxy.c (dbus_g_proxy_get_bus_name): new function - - * glib/dbus-gloader-expat.c (description_load_from_string): allow - -1 for len - - * tools/dbus-viewer.c: add support for introspecting a service on - a bus - - * glib/dbus-gproxy.c (dbus_g_pending_call_ref): add - (dbus_g_pending_call_unref): add - -2005-01-29 Havoc Pennington <hp@redhat.com> - - * tools/dbus-tree-view.c: add support for displaying properties. - (run dbus-viewer with an introspect xml file as arg, then resize - the window so the tree elements show up, not sure what that is) - - * glib/dbus-gobject.c (handle_introspect): return - org.freedesktop.Properties and org.freedesktop.Introspectable - interfaces when we are introspected. - - * doc/dbus-specification.xml: allow empty interface name when - Get/Set a property - -2005-01-29 Havoc Pennington <hp@redhat.com> - - * glib/Makefile.am: rename dbus-glib-tool to dbus-binding-tool; - though it uses glib, it could be extended for any binding in - principle - - * glib/dbus-gobject.c (gobject_message_function): change to the - new way properties work - - * dbus/dbus-protocol.h: add the new interfaces - - * doc/dbus-specification.xml: document the introspection format, - Introspectable interface, and add an org.freedesktop.Properties - interface. - - * glib/dbus-gparser.c: add support for a <property> element - - * glib/dbus-gidl.c: add PropertyInfo - - * glib/dbus-gobject.c (handle_introspect): put the outermost - <node> outside the signal and property descriptions. - (introspect_properties): export properties as <property> rather - than as method calls - -2005-01-28 Havoc Pennington <hp@redhat.com> - - * doc/TODO, doc/dbus-specification.xml: spec and TODO tweaks - related to authentication protocol - -2005-01-28 John (J5) Palmieri <johnp@redhat.com> - - * python/dbus_bindings.pyx.in: Updated to handle new D-BUS type system - - BUS_ACTIVATION -> BUS_STARTER - - DBUS_BUS_ACTIVATION -> DBUS_BUS_STARTER - - class MessageIter (__init__): Added recursion checking - so we throw a nice error instead of just disconnecting from the - bus. - (get): Added arg_type parameter for recursion. - Removed the nil type - Added signiture type placeholder (not implemented) - Added struct type placeholder (not implemented) - Added varient type placeholder (not implemented) - Commented out dict type for now - (get_element_type): renamed from get_array_type - (get_*): changed to use the dbus_message_iter_get_basic API - (get_*_array): removed in favor of recursive get_array method - (get_array): new recursive method which calls get to marshal - the elements of the array - (value_to_dbus_sig): New method returns the corrasponding - dbus signiture to a python value - (append): Comment out dict handling for now - Handle lists with the new recursive API - Comment out None handling for now - (append_nil): removed - (append_*): changed to use dbus_message_iter_append_basic API - (append_*_array): removed in favor of recursive append_array - method - (__str__): Make it easier to print out recursive iterators - for debugging - - class Message (__str__): moved type inspection to the - MessageIter class' __str__ method - (get_iter): Added an append parameter wich defaults to False - If True use the new API's to create an append iterator - - * python/dbus.py: Update to use new bindings API - - TYPE_ACTIVATION -> TYPE_STARTER - - class Bus (_get_match_rule): GetServiceOwner -> GetNameOwner - - class ActivationBus -> class StarterBus - - class RemoteObject (__call__): get an append iterator - - (_dispatch_dbus_method_call): get an append iterator - - class Object (emit_signal): get an append iterator - - * python/examples/: Fixed up the examples to work with the new API - -2005-01-28 Joe Shaw <joeshaw@novell.com> - - * configure.in: Bump version up to 0.30. - - * HACKING: Add a release item to bump the version number up after - a release. - -2005-01-28 Havoc Pennington <hp@redhat.com> - - * doc/dbus-specification.xml: update to describe 16-bit types and - dict entries - - * dbus/dbus-marshal-basic.c (_dbus_unpack_uint16): fix broken - assertion - - * dbus/dbus-protocol.h (DBUS_TYPE_DICT_ENTRY): add DICT_ENTRY as a - type - - * dbus/dbus-marshal-recursive.c: implement - -2005-01-27 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-arch-deps.h.in: add 16/32-bit types - - * configure.in: find the right type for 16 and 32 bit ints as well - as 64 - - * dbus/dbus-protocol.h (DBUS_TYPE_INT16, DBUS_TYPE_UINT16): add - the 16-bit types so people don't have to stuff them in 32-bit or - byte arrays. - -2005-01-27 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message.c: byteswap the message if you init an - iterator to read/write from it - - * dbus/dbus-marshal-byteswap.c: new file implementing - _dbus_marshal_byteswap() - - * dbus/dbus-marshal-basic.c: add _dbus_swap_array() - -2005-01-26 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-marshal-validate-util.c: break this out (and fix - build, apparently - nobody noticed?) - -2005-01-26 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-marshal-recursive.h: remove todo comment - -2005-01-25 Joe Shaw <joeshaw@novell.com> - - * Land the mono binding changes to conform to the new APIs. - - * mono/Makefile.am: Remove Custom.cs, DBusType/Custom.cs, - DBusType/Dict.cs, and DBusType/Nil.cs from the build. - - * mono/Arguments.cs (GetCodeAsString): Added. Returns the dbus - type code as a string. - (InitAppending): Rename dbus_message_append_iter_init() to - dbus_message_iter_init_append(). - - * mono/BusDriver.cs: Rename ServiceEventHandler to - NameOwnerChangedHandler. Rename GetServiceOwner to GetOwner. - Rename ServiceOwnerChanged to NameOwnerChanged. - - * mono/Connection.cs: Rename BaseService to UniqueName, and the - underlying C call. - - * mono/Custom.cs: Removed. The CUSTOM type has been removed. - - * mono/Service.cs: Rename Exists to HasOwner, internally rename - dbus_bus_acquire_service() to dbus_bus_request_name(). - - * mono/DBusType/Array.cs (ctor): Use Type.GetElementType() instead - of Type.UnderlyingSystemType to get the correct element type for - the array. - (ctor): Update code for new APIs: use dbus_message_iter_recurse(), - dbus_message_get_{element|arg}_type() instead of - dbus_message_iter_init_array_iterator(). - (Append): Replace dbus_message_iter_append_array() with - dbus_message_iter_open_container() and - dbus_message_iter_close_container(). - - * mono/DBusType/Custom.cs, mono/DBusType/Nil.cs: Removed. These - types have been removed. - - * mono/DBusType/*.cs: Replace calls of - dbus_message_iter_get_[type]() to dbus_message_iter_get_basic(), - but specify the type in the DllImport extern declaration. Ditto - for dbus_message_iter_append_[type]() -> - dbus_message_iter_append_basic(). - - * mono/example/BusListener.cs: Update for ServiceEventHandler -> - NameOwnerChangedHandler. - -2005-01-25 John (J5) Palmieri <johnp@redhat.com> - - * python/dbus_bindings.pyx.in: Rename of methods and bindings - - get_base_service -> get_unique_name - - bus_get_base_service -> bus_get_unique_name - - dbus_bus_get_base_service -> dbus_bus_get_unique_name - - ACTIVATION_REPLY_ACTIVATED -> DBUS_START_REPLY_SUCCESS - - ACTIVATION_REPLY_ALREADY_ACTIVE -> DBUS_START_REPLY_ALREADY_RUNNING - - bus_activate_service -> bus_start_service_by_name - - dbus_bus_activate_service -> dbus_bus_start_service_by_name - - bus_acquire_service -> bus_request_name - - dbus_bus_acquire_service -> dbus_bus_request_name - - bus_service_exists -> bus_name_has_owner - - dbus_bus_service_exists -> dbus_bus_name_has_owner - - * python/dbus.py: Rename of methods - - activate_service -> start_service_by_name - - bus_acquire_service -> bus_request_name - - ACTIVATION_REPLY_ACTIVATED -> START_REPLY_SUCCESS - - ACTIVATION_REPLY_ALREADY_ACTIVE -> START_REPLY_ALREADY_RUNNING - - -2005-01-24 Joe Shaw <joeshaw@novell.com> - - * dbus/dbus-connection.c (dbus_connection_dispatch): Print out the - signature for the method that can't be found. - - * dbus/dbus-message.c (dbus_message_iter_init): To check to see if - the message has any arguments, we need to call - _dbus_type_reader_get_current_type(), not - _dbus_type_reader_has_next(). - -2005-01-24 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message-factory.c: more testing of message validation - - * dbus/dbus-protocol.h (DBUS_MINIMUM_HEADER_SIZE): move to this - header - -2005-01-23 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-message-factory.c, dbus/dbus-message-util.c: - get this all working, not many tests in the framework yet though - -2005-01-22 Havoc Pennington <hp@redhat.com> - - * doc/dbus-faq.xml, doc/dbus-tutorial: add a FAQ and update - tutorial, based on work from David Wheeler. - -2005-01-21 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-bus.c: add more return_if_fail checks - - * dbus/dbus-message.c (load_message): have the "no validation" - mode (have to edit the code to toggle the mode for now though) - - * dbus/dbus-marshal-header.c (_dbus_header_load): have a mode that - skips all validation; I want to use this at least for benchmark - baseline, I'm not sure if it should be a publicly-available switch. - -2005-01-21 Havoc Pennington <hp@redhat.com> - - * glib/dbus-gmain.c: don't put the GLib bindings in the same - toplevel doxygen group as the low-level API stuff - - * dbus/dbus.h: note that libdbus is the low-level API - -2005-01-20 Havoc Pennington <hp@redhat.com> - - * update-dbus-docs.sh: script to update docs on the web site, only - works for me though. neener. - -2005-01-20 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-sysdeps.c (_dbus_poll): amazingly, trying to compile - code can reveal bugs in it - -2005-01-20 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-sysdeps.c (_dbus_poll): fix several bugs in the - select() version, patches from Tor Lillqvist - -2005-01-20 Havoc Pennington <hp@redhat.com> - - * doc/dbus-tutorial.xml: replace > with > - - * bus/services.c (bus_registry_acquire_service): validate the name - and return a better error if it's no good. - - * doc/dbus-specification.xml: note NO_AUTO_START change - - * dbus/dbus-protocol.h (DBUS_HEADER_FLAG_NO_AUTO_START): change - from AUTO_START, we're toggling the default - - * bus/dispatch.c: adapt the tests to change of auto-start default - -2005-01-18 Havoc Pennington <hp@redhat.com> - - * rename dbus-daemon-1 to dbus-daemon throughout - -2005-01-18 Havoc Pennington <hp@redhat.com> - - * Throughout, grand renaming to strip out the use of "service", - just say "name" instead (or "bus name" when ambiguous). Did not - change the internal code of the message bus itself, only the - programmer-facing API and messages. - - * doc/dbus-specification.xml: further update the message bus section - - * bus/config-parser.c (all_are_equiv): fix bug using freed string - in error case - -2005-01-17 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-types.h: remove 16-bit types since we don't use them - ever - - * dbus/dbus-marshal-validate.c (_dbus_validate_path): disallow any - "invalid name character" not only non-ASCII - - * doc/dbus-specification.xml: further update spec, message bus - parts are still out-of-date but the marshaling etc. stuff is now - accurate-ish - -2005-01-17 Havoc Pennington <hp@redhat.com> - - * doc/dbus-specification.xml: partially update spec - -2005-01-17 Havoc Pennington <hp@redhat.com> - - * Throughout, align variant bodies according to the contained - type, rather than always to 8. Should save a fair bit of space in - message headers. - - * dbus/dbus-marshal-validate.c (_dbus_validate_body_with_reason): - fix handling of case where p == end - - * doc/TODO: remove the dbus_bool_t item and variant alignment items - -2005-01-17 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-types.h: hardcode dbus_bool_t to 32 bits - - * Throughout: modify DBUS_TYPE_BOOLEAN to be a 32-bit type instead - of an 8-bit type. Now dbus_bool_t is the type to use whenever you - are marshaling/unmarshaling a boolean. - -2005-01-16 Havoc Pennington <hp@redhat.com> - - This is about it on what can be disabled/deleted from libdbus - easily, back below 150K anyhow. Deeper cuts are more work than - just turning the code off as I've done here. - - * dbus/dbus-marshal-basic.c (_dbus_pack_int32): we don't need the - signed int convenience funcs - - * dbus/dbus-internals.c (_dbus_verbose_real): omit when not in - verbose mode - - * dbus/dbus-string-util.c, dbus/dbus-string.c: more breaking - things out of libdbus - - * dbus/dbus-sysdeps.c, dbus/dbus-sysdeps-util.c: same - - * dbus/dbus-hash.c: purge the TWO_STRINGS crap (well, make it - tests-enabled-only, though it should probably be deleted) - - * dbus/dbus-message-util.c: same stuff - - * dbus/dbus-auth-util.c: same stuff - -2005-01-16 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-userdb-util.c: split out part of dbus-userdb.c - - * dbus/dbus-sysdeps.c (_dbus_uid_from_string): move here to pave - way for stripping down dbus-userdb.c stuff included in libdbus. - Rename _dbus_parse_uid for consistency. - -2005-01-16 Havoc Pennington <hp@redhat.com> - - * dbus/dbus-internals.c (_dbus_real_assert): print the function - name the assertion failed in - - * dbus/dbus-internals.h (_dbus_return_if_fail) - (_dbus_return_val_if_fail): assert that the name of the function - containing the check doesn't start with '_', since we only want to - use checks on public functions - - * dbus/dbus-connection.c (_dbus_connection_ref_unlocked): change - checks to assertions - - * dbus/dbus-marshal-header.c (_dbus_header_set_field_basic): - change checks to asserts for private function - - * dbus/dbus-message.c (_dbus_message_set_serial): checks - to asserts for private function - - * dbus/dbus-marshal-recursive.c (skip_one_complete_type): remove - broken assertion that was breaking make check - (_dbus_type_reader_array_is_empty): remove this rather than fix - it, was only used in assertions - -2005-01-16 Havoc Pennington <hp@redhat.com> - - * test/unused-code-gc.py: hacky script to find code that's used - only by the bus (not libdbus) or used only by tests or not used at - all. It has some false alarms, but looks like we can clean up a - lot of size from libdbus. - - * dbus/dbus-sysdeps.c, dbus/dbus-sysdeps-utils.c, - dbus/Makefile.am: initially move 10K of binary size out of libdbus - -2005-01-16 Havoc Pennington <hp@redhat.com> - - * Add and fix docs according to Doxygen warnings throughout - source. - - * dbus/dbus-marshal-recursive.c - (_dbus_type_reader_array_is_empty): change this to just call - array_reader_get_array_len() and make it static - - * dbus/dbus-message.c (dbus_message_iter_get_element_type): rename - from get_array_type - (dbus_message_iter_init_append): rename from append_iter_init - - * dbus/dbus-marshal-recursive.c - (_dbus_type_reader_get_element_type): rename from - _dbus_type_reader_get_array_type - -2005-01-15 Havoc Pennington <hp@redhat.com> - - * test/glib/test-profile.c (with_bus_server_filter): fix crash - - * dbus/dbus-marshal-basic.c (_dbus_unpack_uint32): inline as macro - when DBUS_DISABLE_ASSERT - (_dbus_marshal_set_basic): be sure we align for the string length - - * dbus/dbus-marshal-recursive.c (skip_one_complete_type): make - this look faster - - * dbus/dbus-string.c (_dbus_string_get_const_data_len): add an - inline macro version - (_dbus_string_set_byte): provide inline macro version - -2005-01-15 Havoc Pennington <hp@redhat.com> - - * Land the new message args API and type system. - - This patch is huge, but the public API change is not - really large. The set of D-BUS types has changed somewhat, - and the arg "getters" are more geared toward language bindings; - they don't make a copy, etc. - - There are also some known issues. See these emails for details - on this huge patch: - http://lists.freedesktop.org/archives/dbus/2004-December/001836.html - http://lists.freedesktop.org/archives/dbus/2005-January/001922.html - - * dbus/dbus-marshal-*: all the new stuff - - * dbus/dbus-message.c: basically rewritten - - * dbus/dbus-memory.c (check_guards): with "guards" enabled, init - freed blocks to be all non-nul bytes so using freed memory is less - likely to work right - - * dbus/dbus-internals.c (_dbus_test_oom_handling): add - DBUS_FAIL_MALLOC=N environment variable, so you can do - DBUS_FAIL_MALLOC=0 to skip the out-of-memory checking, or - DBUS_FAIL_MALLOC=10 to make it really, really, really slow and - thorough. - - * qt/message.cpp: port to the new message args API - (operator<<): use str.utf8() rather than str.unicode() - (pretty sure this is right from the Qt docs?) - - * glib/dbus-gvalue.c: port to the new message args API - - * bus/dispatch.c, bus/driver.c: port to the new message args API - - * dbus/dbus-string.c (_dbus_string_init_const_len): initialize the - "locked" flag to TRUE and align_offset to 0; I guess we never - looked at these anyhow, but seems cleaner. - - * dbus/dbus-string.h (_DBUS_STRING_ALLOCATION_PADDING): - move allocation padding macro to this header; use it to implement - (_DBUS_STRING_STATIC): ability to declare a static string. - - * dbus/dbus-message.c (_dbus_message_has_type_interface_member): - change to return TRUE if the interface is not set. - - * dbus/dbus-string.[hc]: move the D-BUS specific validation stuff - to dbus-marshal-validate.[hc] - - * dbus/dbus-marshal-basic.c (_dbus_type_to_string): move here from - dbus-internals.c - - * dbus/Makefile.am: cut over from dbus-marshal.[hc] - to dbus-marshal-*.[hc] - - * dbus/dbus-object-tree.c (_dbus_decompose_path): move this - function here from dbus-marshal.c + * bus/session.conf.in: don't allow all users, since now by default + the user that ran the bus can connect. 2005-01-12 Joe Shaw <joeshaw@novell.com> @@ -1,29 +1,22 @@ -D-BUS 0.31 (07 Mar 2005) +D-BUS 0.23.3 (9 Mar 2005) === +- add back dbus_pending_call_get_reply() which was removed accidentally. +- fix a memory leak in return messages +- fix many memory leaks and lifecycle issues in the mono bindings. -- land the new message args API and recursive type system -- add docs and fixed Doxygen warnings throught source -- split out some functions not needed in libdbus to *-util.c source files -- take out type convienience functions -- libdbus now back below 150K -- booleans are now 32-bit instead of 8-bit -- specification updated -- grand renaming to strip out the use of "service" - just say "name" instead (or "bus name" when ambiguous) -- rename dbus-daemon-1 to dbus-daemon throughout -- rename activation to auto-start -- auto-start on by default now -- note that libdbus is the low-level API -- python bindings updated to the new API -- mono bindings updated to the new API -- add 16 bit types -- dictionaries are now ARRAYS of DICT_ENTRY -- dbus-glib-tool renamed to dbus-binding-tool -- massive rewrite of the glib bindings -- saner names for the dbus interface, object path and service defines -- new functions for handling type signitures -- bump sonames for libdbus and libdbus-glib -- various small fixes +D-BUS 0.23.2 (18 Feb 2005) +=== +- shuffle some code around in the mono bindings to deterministically + finalize classes so that delegates are unregistered correctly. +- backport a bunch of thread locking-related fixes from HEAD. + +D-BUS 0.23.1 (11 Feb 2005) +=== +- fix a bug in which the bus daemon wouldn't recognize that a service + owner quit +- fix a bug in the mono bindings that would cause unmanaged code to + call back into a delegate that had been garbage collected and + crashed. D-BUS 0.23 (11 Jan 2005) === diff --git a/bus/policy.c b/bus/policy.c index 7759dfad..c0244bdc 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -453,8 +453,9 @@ bus_policy_allow_user (BusPolicy *policy, uid); return FALSE; } - - allowed = FALSE; + + /* Default to "user owning bus" or root can connect */ + allowed = uid == _dbus_getuid (); allowed = list_allows_user (allowed, &policy->default_rules, diff --git a/bus/session.conf.in b/bus/session.conf.in index 8b6d65f7..1a6dfda5 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -19,8 +19,6 @@ <allow eavesdrop="true"/> <!-- Allow anyone to own anything --> <allow own="*"/> - <!-- Allow any user to connect --> - <allow user="*"/> </policy> <!-- This is included last so local configuration can override what's diff --git a/configure.in b/configure.in index 28a186cc..6eb1d432 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ AC_PREREQ(2.52) AC_INIT(dbus/dbus.h) -AM_INIT_AUTOMAKE(dbus, 0.32) +AM_INIT_AUTOMAKE(dbus, 0.23.3) AM_CONFIG_HEADER(config.h) @@ -17,18 +17,6 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext d ## must come before we use the $USE_MAINTAINER_MODE variable later AM_MAINTAINER_MODE -# libtool versioning - this applies to libhal and libhal-storage -# -# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details -# -LT_CURRENT=1 -LT_REVISION=0 -LT_AGE=0 -AC_SUBST(LT_CURRENT) -AC_SUBST(LT_REVISION) -AC_SUBST(LT_AGE) - - AC_PROG_CC AC_PROG_CXX AC_ISC_POSIX @@ -381,53 +369,6 @@ AC_SUBST(DBUS_INT64_CONSTANT) AC_SUBST(DBUS_UINT64_CONSTANT) AC_SUBST(DBUS_HAVE_INT64) -### see what 32-bit int is called -AC_MSG_CHECKING([32-bit integer type]) - -case 4 in -$ac_cv_sizeof_short) - dbusint32=int - ;; -$ac_cv_sizeof_int) - dbusint32=int - ;; -$ac_cv_sizeof_long) - dbusint32=long - ;; -esac - -if test -z "$dbusint32" ; then - DBUS_INT32_TYPE="no_int32_type_detected" - AC_MSG_ERROR([No 32-bit integer type found]) -else - DBUS_INT32_TYPE="$dbusint32" - AC_MSG_RESULT($DBUS_INT32_TYPE) -fi - -AC_SUBST(DBUS_INT32_TYPE) - -### see what 16-bit int is called -AC_MSG_CHECKING([16-bit integer type]) - -case 2 in -$ac_cv_sizeof_short) - dbusint16=short - ;; -$ac_cv_sizeof_int) - dbusint16=int - ;; -esac - -if test -z "$dbusint16" ; then - DBUS_INT16_TYPE="no_int16_type_detected" - AC_MSG_ERROR([No 16-bit integer type found]) -else - DBUS_INT16_TYPE="$dbusint16" - AC_MSG_RESULT($DBUS_INT16_TYPE) -fi - -AC_SUBST(DBUS_INT16_TYPE) - ## byte order AC_C_BIGENDIAN @@ -831,13 +772,6 @@ fi AM_CONDITIONAL(HAVE_GLIB, test x$have_glib = xyes) AM_CONDITIONAL(HAVE_GLIB_THREADS, test x$have_glib_threads = xyes) -if test x$have_glib = xyes; then - GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0` -else - GLIB_GENMARSHAL=glib-not-enabled-so-there-is-no-genmarshal -fi -AC_SUBST(GLIB_GENMARSHAL) - dnl GLib flags AC_SUBST(DBUS_GLIB_CFLAGS) AC_SUBST(DBUS_GLIB_LIBS) @@ -854,7 +788,6 @@ if test x$have_glib = xno ; then have_gtk=no else PKG_CHECK_MODULES(DBUS_GTK, gtk+-2.0, have_gtk=yes, have_gtk=no) - PKG_CHECK_MODULES(DBUS_GTK_THREADS, gtk+-2.0 gthread-2.0, have_gtk_threads=yes, have_gtk_threads=no) fi if test x$have_gtk = xno ; then @@ -876,8 +809,6 @@ AM_CONDITIONAL(HAVE_GTK, test x$have_gtk = xyes) dnl Gtk flags AC_SUBST(DBUS_GTK_CFLAGS) AC_SUBST(DBUS_GTK_LIBS) -AC_SUBST(DBUS_GTK_THREADS_CFLAGS) -AC_SUBST(DBUS_GTK_THREADS_LIBS) # Qt detection AC_PATH_PROG(QT_MOC, moc, no) @@ -1133,7 +1064,7 @@ AC_SUBST(TEST_$1) TEST_PATH(SERVICE_DIR, data/valid-service-files) TEST_PATH(SERVICE_BINARY, test-service) -TEST_PATH(GLIB_SERVICE_BINARY, glib/test-service-glib) +TEST_PATH(GLIB_SERVICE_BINARY, test-service-glib) TEST_PATH(EXIT_BINARY, test-exit) TEST_PATH(SEGFAULT_BINARY, test-segfault) TEST_PATH(SLEEP_FOREVER_BINARY, test-sleep-forever) @@ -1210,7 +1141,7 @@ bus/system.conf bus/session.conf bus/messagebus bus/rc.messagebus -bus/dbus-daemon.1 +bus/dbus-daemon-1.1 Makefile dbus/Makefile glib/Makefile @@ -1238,7 +1169,6 @@ test/data/valid-config-files/debug-allow-all.conf test/data/valid-config-files/debug-allow-all-sha1.conf test/data/valid-service-files/debug-echo.service test/data/valid-service-files/debug-segfault.service -test/data/valid-service-files/debug-glib.service ]) ### FIXME it's bizarre that have_qt and have_glib are used @@ -1264,8 +1194,6 @@ echo " cppflags: ${CPPFLAGS} cxxflags: ${CXXFLAGS} 64-bit int: ${DBUS_INT64_TYPE} - 32-bit int: ${DBUS_INT32_TYPE} - 16-bit int: ${DBUS_INT16_TYPE} Doxygen: ${DOXYGEN} xmlto: ${XMLTO}" diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index db76ba22..89f789b3 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -38,7 +38,7 @@ #include "dbus-string.h" #include "dbus-pending-call.h" #include "dbus-object-tree.h" -#include "dbus-threads-internal.h" +#include "dbus-marshal.h" #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -61,14 +61,14 @@ #define CONNECTION_LOCK(connection) do { \ if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \ - _dbus_mutex_lock ((connection)->mutex); \ + dbus_mutex_lock ((connection)->mutex); \ TOOK_LOCK_CHECK (connection); \ } while (0) #define CONNECTION_UNLOCK(connection) do { \ if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \ RELEASING_LOCK_CHECK (connection); \ - _dbus_mutex_unlock ((connection)->mutex); \ + dbus_mutex_unlock ((connection)->mutex); \ } while (0) #define DISPATCH_STATUS_NAME(s) \ @@ -125,8 +125,8 @@ * * When a connection is disconnected, you are guaranteed to get a * signal "Disconnected" from the interface - * #DBUS_INTERFACE_LOCAL, path - * #DBUS_PATH_LOCAL. + * #DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, path + * #DBUS_PATH_ORG_FREEDESKTOP_LOCAL. * * You may not drop the last reference to a #DBusConnection * until that connection has been disconnected. @@ -233,10 +233,6 @@ struct DBusConnection * for the global linked list mempool lock */ DBusObjectTree *objects; /**< Object path handlers registered with this connection */ - - char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */ - - unsigned int shareable : 1; /**< #TRUE if connection can go in shared_connections once we know the GUID */ unsigned int dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */ unsigned int io_path_acquired : 1; /**< Someone has transport io path (can use the transport to read/write messages) */ @@ -927,7 +923,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, CONNECTION_UNLOCK (connection); _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->io_path_mutex); + dbus_mutex_lock (connection->io_path_mutex); _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n", _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds); @@ -940,16 +936,16 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, { _dbus_verbose ("%s waiting %d for IO path to be acquirable\n", _DBUS_FUNCTION_NAME, timeout_milliseconds); - _dbus_condvar_wait_timeout (connection->io_path_cond, - connection->io_path_mutex, - timeout_milliseconds); + dbus_condvar_wait_timeout (connection->io_path_cond, + connection->io_path_mutex, + timeout_milliseconds); } else { while (connection->io_path_acquired) { _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); + dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); } } } @@ -964,7 +960,7 @@ _dbus_connection_acquire_io_path (DBusConnection *connection, _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired); _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->io_path_mutex); + dbus_mutex_unlock (connection->io_path_mutex); CONNECTION_LOCK (connection); @@ -988,7 +984,7 @@ _dbus_connection_release_io_path (DBusConnection *connection) HAVE_LOCK_CHECK (connection); _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->io_path_mutex); + dbus_mutex_lock (connection->io_path_mutex); _dbus_assert (connection->io_path_acquired); @@ -996,10 +992,10 @@ _dbus_connection_release_io_path (DBusConnection *connection) _DBUS_FUNCTION_NAME, connection->io_path_acquired); connection->io_path_acquired = FALSE; - _dbus_condvar_wake_one (connection->io_path_cond); + dbus_condvar_wake_one (connection->io_path_cond); _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->io_path_mutex); + dbus_mutex_unlock (connection->io_path_mutex); } /** @@ -1118,32 +1114,32 @@ _dbus_connection_new_for_transport (DBusTransport *transport) if (connection == NULL) goto error; - mutex = _dbus_mutex_new (); + mutex = dbus_mutex_new (); if (mutex == NULL) goto error; - io_path_mutex = _dbus_mutex_new (); + io_path_mutex = dbus_mutex_new (); if (io_path_mutex == NULL) goto error; - dispatch_mutex = _dbus_mutex_new (); + dispatch_mutex = dbus_mutex_new (); if (dispatch_mutex == NULL) goto error; - message_returned_cond = _dbus_condvar_new (); + message_returned_cond = dbus_condvar_new (); if (message_returned_cond == NULL) goto error; - dispatch_cond = _dbus_condvar_new (); + dispatch_cond = dbus_condvar_new (); if (dispatch_cond == NULL) goto error; - io_path_cond = _dbus_condvar_new (); + io_path_cond = dbus_condvar_new (); if (io_path_cond == NULL) goto error; - disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, - DBUS_INTERFACE_LOCAL, + disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected"); if (disconnect_message == NULL) @@ -1179,7 +1175,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport) connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ connection->objects = objects; connection->exit_on_disconnect = FALSE; - connection->shareable = FALSE; #ifndef DBUS_DISABLE_CHECKS connection->generation = _dbus_current_generation; #endif @@ -1209,22 +1204,22 @@ _dbus_connection_new_for_transport (DBusTransport *transport) _dbus_list_free_link (disconnect_link); if (io_path_cond != NULL) - _dbus_condvar_free (io_path_cond); + dbus_condvar_free (io_path_cond); if (dispatch_cond != NULL) - _dbus_condvar_free (dispatch_cond); + dbus_condvar_free (dispatch_cond); if (message_returned_cond != NULL) - _dbus_condvar_free (message_returned_cond); + dbus_condvar_free (message_returned_cond); if (mutex != NULL) - _dbus_mutex_free (mutex); + dbus_mutex_free (mutex); if (io_path_mutex != NULL) - _dbus_mutex_free (io_path_mutex); + dbus_mutex_free (io_path_mutex); if (dispatch_mutex != NULL) - _dbus_mutex_free (dispatch_mutex); + dbus_mutex_free (dispatch_mutex); if (connection != NULL) dbus_free (connection); @@ -1368,301 +1363,6 @@ _dbus_connection_handle_watch (DBusWatch *watch, return retval; } -_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); -static DBusHashTable *shared_connections = NULL; - -static void -shared_connections_shutdown (void *data) -{ - _DBUS_LOCK (shared_connections); - - _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0); - _dbus_hash_table_unref (shared_connections); - shared_connections = NULL; - - _DBUS_UNLOCK (shared_connections); -} - -static dbus_bool_t -connection_lookup_shared (DBusAddressEntry *entry, - DBusConnection **result) -{ - _dbus_verbose ("checking for existing connection\n"); - - *result = NULL; - - _DBUS_LOCK (shared_connections); - - if (shared_connections == NULL) - { - _dbus_verbose ("creating shared_connections hash table\n"); - - shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING, - dbus_free, - NULL); - if (shared_connections == NULL) - { - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL)) - { - _dbus_hash_table_unref (shared_connections); - shared_connections = NULL; - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - _dbus_verbose (" successfully created shared_connections\n"); - - _DBUS_UNLOCK (shared_connections); - return TRUE; /* no point looking up in the hash we just made */ - } - else - { - const char *guid; - - guid = dbus_address_entry_get_value (entry, "guid"); - - if (guid != NULL) - { - *result = _dbus_hash_table_lookup_string (shared_connections, - guid); - - if (*result) - { - /* The DBusConnection can't have been disconnected - * between the lookup and this code, because the - * disconnection will take the shared_connections lock to - * remove the connection. It can't have been finalized - * since you have to disconnect prior to finalize. - * - * Thus it's safe to ref the connection. - */ - dbus_connection_ref (*result); - - _dbus_verbose ("looked up existing connection to server guid %s\n", - guid); - } - } - - _DBUS_UNLOCK (shared_connections); - return TRUE; - } -} - -static dbus_bool_t -connection_record_shared_unlocked (DBusConnection *connection, - const char *guid) -{ - char *guid_key; - char *guid_in_connection; - - /* A separate copy of the key is required in the hash table, because - * we don't have a lock on the connection when we are doing a hash - * lookup. - */ - - _dbus_assert (connection->server_guid == NULL); - _dbus_assert (connection->shareable); - - guid_key = _dbus_strdup (guid); - if (guid_key == NULL) - return FALSE; - - guid_in_connection = _dbus_strdup (guid); - if (guid_in_connection == NULL) - { - dbus_free (guid_key); - return FALSE; - } - - _DBUS_LOCK (shared_connections); - _dbus_assert (shared_connections != NULL); - - if (!_dbus_hash_table_insert_string (shared_connections, - guid_key, connection)) - { - dbus_free (guid_key); - dbus_free (guid_in_connection); - _DBUS_UNLOCK (shared_connections); - return FALSE; - } - - connection->server_guid = guid_in_connection; - - _dbus_verbose ("stored connection to %s to be shared\n", - connection->server_guid); - - _DBUS_UNLOCK (shared_connections); - - _dbus_assert (connection->server_guid != NULL); - - return TRUE; -} - -static void -connection_forget_shared_unlocked (DBusConnection *connection) -{ - HAVE_LOCK_CHECK (connection); - - if (connection->server_guid == NULL) - return; - - _dbus_verbose ("dropping connection to %s out of the shared table\n", - connection->server_guid); - - _DBUS_LOCK (shared_connections); - - if (!_dbus_hash_table_remove_string (shared_connections, - connection->server_guid)) - _dbus_assert_not_reached ("connection was not in the shared table"); - - dbus_free (connection->server_guid); - connection->server_guid = NULL; - - _DBUS_UNLOCK (shared_connections); -} - -static DBusConnection* -connection_try_from_address_entry (DBusAddressEntry *entry, - DBusError *error) -{ - DBusTransport *transport; - DBusConnection *connection; - - transport = _dbus_transport_open (entry, error); - - if (transport == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (error); - return NULL; - } - - connection = _dbus_connection_new_for_transport (transport); - - _dbus_transport_unref (transport); - - if (connection == NULL) - { - _DBUS_SET_OOM (error); - return NULL; - } - -#ifndef DBUS_DISABLE_CHECKS - _dbus_assert (!connection->have_connection_lock); -#endif - return connection; -} - -/* - * If the shared parameter is true, then any existing connection will - * be used (and if a new connection is created, it will be available - * for use by others). If the shared parameter is false, a new - * connection will always be created, and the new connection will - * never be returned to other callers. - * - * @param address the address - * @param shared whether the connection is shared or private - * @param error error return - * @returns the connection or #NULL on error - */ -static DBusConnection* -_dbus_connection_open_internal (const char *address, - dbus_bool_t shared, - DBusError *error) -{ - DBusConnection *connection; - DBusAddressEntry **entries; - DBusError tmp_error; - DBusError first_error; - int len, i; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - _dbus_verbose ("opening %s connection to: %s\n", - shared ? "shared" : "private", address); - - if (!dbus_parse_address (address, &entries, &len, error)) - return NULL; - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - - connection = NULL; - - dbus_error_init (&tmp_error); - dbus_error_init (&first_error); - for (i = 0; i < len; i++) - { - if (shared) - { - if (!connection_lookup_shared (entries[i], &connection)) - _DBUS_SET_OOM (&tmp_error); - } - - if (connection == NULL) - { - connection = connection_try_from_address_entry (entries[i], - &tmp_error); - - if (connection != NULL && shared) - { - const char *guid; - - connection->shareable = TRUE; - - guid = dbus_address_entry_get_value (entries[i], "guid"); - - /* we don't have a connection lock but we know nobody - * else has a handle to the connection - */ - - if (guid && - !connection_record_shared_unlocked (connection, guid)) - { - _DBUS_SET_OOM (&tmp_error); - dbus_connection_disconnect (connection); - dbus_connection_unref (connection); - connection = NULL; - } - - /* but as of now the connection is possibly shared - * since another thread could have pulled it from the table - */ - } - } - - if (connection) - break; - - _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); - - if (i == 0) - dbus_move_error (&tmp_error, &first_error); - else - dbus_error_free (&tmp_error); - } - - /* NOTE we don't have a lock on a possibly-shared connection object */ - - _DBUS_ASSERT_ERROR_IS_CLEAR (error); - _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); - - if (connection == NULL) - { - _DBUS_ASSERT_ERROR_IS_SET (&first_error); - dbus_move_error (&first_error, error); - } - else - { - dbus_error_free (&first_error); - } - - dbus_address_entries_free (entries); - return connection; -} - /** @} */ /** @@ -1672,19 +1372,16 @@ _dbus_connection_open_internal (const char *address, */ /** - * Gets a connection to a remote address. If a connection to the given - * address already exists, returns the existing connection with its - * reference count incremented. Otherwise, returns a new connection - * and saves the new connection for possible re-use if a future call - * to dbus_connection_open() asks to connect to the same server. + * Opens a new connection to a remote address. * - * Use dbus_connection_open_private() to get a dedicated connection - * not shared with other callers of dbus_connection_open(). + * @todo specify what the address parameter is. Right now + * it's just the name of a UNIX domain socket. It should be + * something more complex that encodes which transport to use. * - * If the open fails, the function returns #NULL, and provides a - * reason for the failure in the error parameter. Pass #NULL for the - * error parameter if you aren't interested in the reason for - * failure. + * If the open fails, the function returns #NULL, and provides + * a reason for the failure in the result parameter. Pass + * #NULL for the result parameter if you aren't interested + * in the reason for failure. * * @param address the address. * @param error address where an error can be returned. @@ -1695,44 +1392,31 @@ dbus_connection_open (const char *address, DBusError *error) { DBusConnection *connection; + DBusTransport *transport; _dbus_return_val_if_fail (address != NULL, NULL); _dbus_return_val_if_error_is_set (error, NULL); + + transport = _dbus_transport_open (address, error); + if (transport == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return NULL; + } + + connection = _dbus_connection_new_for_transport (transport); - connection = _dbus_connection_open_internal (address, - TRUE, - error); - - return connection; -} - -/** - * Opens a new, dedicated connection to a remote address. Unlike - * dbus_connection_open(), always creates a new connection. - * This connection will not be saved or recycled by libdbus. - * - * If the open fails, the function returns #NULL, and provides a - * reason for the failure in the error parameter. Pass #NULL for the - * error parameter if you aren't interested in the reason for - * failure. - * - * @param address the address. - * @param error address where an error can be returned. - * @returns new connection, or #NULL on failure. - */ -DBusConnection* -dbus_connection_open_private (const char *address, - DBusError *error) -{ - DBusConnection *connection; - - _dbus_return_val_if_fail (address != NULL, NULL); - _dbus_return_val_if_error_is_set (error, NULL); - - connection = _dbus_connection_open_internal (address, - FALSE, - error); + _dbus_transport_unref (transport); + + if (connection == NULL) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } +#ifndef DBUS_DISABLE_CHECKS + _dbus_assert (!connection->have_connection_lock); +#endif return connection; } @@ -1795,8 +1479,7 @@ _dbus_connection_last_unref (DBusConnection *connection) * you won't get the disconnected message. */ _dbus_assert (!_dbus_transport_get_is_connected (connection->transport)); - _dbus_assert (connection->server_guid == NULL); - + /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */ _dbus_object_tree_free_all_unlocked (connection->objects); @@ -1846,7 +1529,7 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_clear (&connection->incoming_messages); _dbus_counter_unref (connection->outgoing_counter); - + _dbus_transport_unref (connection->transport); if (connection->disconnect_message_link) @@ -1858,13 +1541,13 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_clear (&connection->link_cache); - _dbus_condvar_free (connection->dispatch_cond); - _dbus_condvar_free (connection->io_path_cond); + dbus_condvar_free (connection->dispatch_cond); + dbus_condvar_free (connection->io_path_cond); - _dbus_mutex_free (connection->io_path_mutex); - _dbus_mutex_free (connection->dispatch_mutex); + dbus_mutex_free (connection->io_path_mutex); + dbus_mutex_free (connection->dispatch_mutex); - _dbus_mutex_free (connection->mutex); + dbus_mutex_free (connection->mutex); dbus_free (connection); } @@ -1937,7 +1620,6 @@ dbus_connection_disconnect (DBusConnection *connection) _dbus_verbose ("Disconnecting %p\n", connection); CONNECTION_LOCK (connection); - _dbus_transport_disconnect (connection->transport); _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); @@ -2459,9 +2141,9 @@ dbus_connection_send_with_reply (DBusConnection *connection, if (!_dbus_connection_attach_pending_call_unlocked (connection, pending)) goto error; - + dbus_pending_call_unref (pending); - + if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) { _dbus_connection_detach_pending_call_and_unlock (connection, @@ -3079,12 +2761,12 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection) CONNECTION_UNLOCK (connection); _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->dispatch_mutex); + dbus_mutex_lock (connection->dispatch_mutex); while (connection->dispatch_acquired) { _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); - _dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); + dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); } _dbus_assert (!connection->dispatch_acquired); @@ -3092,7 +2774,7 @@ _dbus_connection_acquire_dispatch (DBusConnection *connection) connection->dispatch_acquired = TRUE; _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->dispatch_mutex); + dbus_mutex_unlock (connection->dispatch_mutex); CONNECTION_LOCK (connection); _dbus_connection_unref_unlocked (connection); @@ -3111,15 +2793,15 @@ _dbus_connection_release_dispatch (DBusConnection *connection) HAVE_LOCK_CHECK (connection); _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_lock (connection->dispatch_mutex); + dbus_mutex_lock (connection->dispatch_mutex); _dbus_assert (connection->dispatch_acquired); connection->dispatch_acquired = FALSE; - _dbus_condvar_wake_one (connection->dispatch_cond); + dbus_condvar_wake_one (connection->dispatch_cond); _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); - _dbus_mutex_unlock (connection->dispatch_mutex); + dbus_mutex_unlock (connection->dispatch_mutex); } static void @@ -3158,9 +2840,7 @@ _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) { _dbus_verbose ("Sending disconnect message from %s\n", _DBUS_FUNCTION_NAME); - - connection_forget_shared_unlocked (connection); - + /* We haven't sent the disconnect message already, * and all real messages have been queued up. */ @@ -3537,7 +3217,7 @@ dbus_connection_dispatch (DBusConnection *connection) if (connection->exit_on_disconnect && dbus_message_is_signal (message, - DBUS_INTERFACE_LOCAL, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) { _dbus_verbose ("Exiting on Disconnected signal\n"); diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index 1d6029af..f4fa82d4 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* dbus-object-tree.c DBusObjectTree (internals of DBusConnection) * - * Copyright (C) 2003, 2005 Red Hat Inc. + * Copyright (C) 2003 Red Hat Inc. * * Licensed under the Academic Free License version 2.1 * @@ -462,7 +462,7 @@ _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, _dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n", path[0] ? path[0] : "null", path[1] ? path[1] : "null"); - goto unlock; + goto unlock; } #else _dbus_assert (subtree != NULL); @@ -507,7 +507,6 @@ unlock: #endif { _dbus_connection_ref_unlocked (connection); - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); _dbus_connection_unlock (connection); } @@ -612,56 +611,22 @@ _dbus_object_tree_list_registered_unlocked (DBusObjectTree *tree, } static DBusHandlerResult -handle_default_introspect_and_unlock (DBusObjectTree *tree, - DBusMessage *message, - const char **path) +handle_default_introspect_unlocked (DBusObjectTree *tree, + DBusMessage *message, + const char **path) { DBusString xml; DBusHandlerResult result; char **children; int i; - DBusMessage *reply; - DBusMessageIter iter; - const char *v_STRING; - dbus_bool_t already_unlocked; - /* We have the connection lock here */ - - already_unlocked = FALSE; - - _dbus_verbose (" considering default Introspect() handler...\n"); - - reply = NULL; - if (!dbus_message_is_method_call (message, - DBUS_INTERFACE_INTROSPECTABLE, + DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE, "Introspect")) - { -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - _dbus_verbose (" using default Introspect() handler!\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (!_dbus_string_init (&xml)) - { -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - - return DBUS_HANDLER_RESULT_NEED_MEMORY; - } + return DBUS_HANDLER_RESULT_NEED_MEMORY; result = DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -669,9 +634,6 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree, if (!_dbus_object_tree_list_registered_unlocked (tree, path, &children)) goto out; - if (!_dbus_string_append (&xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) - goto out; - if (!_dbus_string_append (&xml, "<node>\n")) goto out; @@ -687,44 +649,12 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree, if (!_dbus_string_append (&xml, "</node>\n")) goto out; - - reply = dbus_message_new_method_return (message); - if (reply == NULL) - goto out; - - dbus_message_iter_init_append (reply, &iter); - v_STRING = _dbus_string_get_const_data (&xml); - if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &v_STRING)) - goto out; - -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - already_unlocked = TRUE; - - if (!_dbus_connection_send_and_unlock (tree->connection, reply, NULL)) - goto out; - } result = DBUS_HANDLER_RESULT_HANDLED; out: -#ifdef DBUS_BUILD_TESTS - if (tree->connection) -#endif - { - if (!already_unlocked) - { - _dbus_verbose ("unlock %s %d\n", _DBUS_FUNCTION_NAME, __LINE__); - _dbus_connection_unlock (tree->connection); - } - } - _dbus_string_free (&xml); dbus_free_string_array (children); - if (reply) - dbus_message_unref (reply); return result; } @@ -763,10 +693,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); _dbus_verbose ("No memory to get decomposed path\n"); @@ -778,10 +705,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); _dbus_verbose ("No path field in message\n"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -844,10 +768,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); /* FIXME you could unregister the subtree in another thread * before we invoke the callback, and I can't figure out a @@ -876,19 +797,14 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, { /* This hardcoded default handler does a minimal Introspect() */ - result = handle_default_introspect_and_unlock (tree, message, - (const char**) path); + result = handle_default_introspect_unlocked (tree, message, + (const char**) path); } - else - { + #ifdef DBUS_BUILD_TESTS - if (tree->connection) + if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } - } + _dbus_connection_unlock (tree->connection); while (list != NULL) { @@ -1021,112 +937,11 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree, #ifdef DBUS_BUILD_TESTS if (tree->connection) #endif - { - _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME); - _dbus_connection_unlock (tree->connection); - } + _dbus_connection_unlock (tree->connection); return result; } - - -/** Set to 1 to get a bunch of spew about disassembling the path string */ -#define VERBOSE_DECOMPOSE 0 - -/** - * Decompose an object path. A path of just "/" is - * represented as an empty vector of strings. - * The path need not be nul terminated. - * - * @param data the path data - * @param len the length of the path string - * @param path address to store new object path - * @param path_len length of stored path - */ -dbus_bool_t -_dbus_decompose_path (const char* data, - int len, - char ***path, - int *path_len) -{ - char **retval; - int n_components; - int i, j, comp; - - _dbus_assert (data != NULL); - -#if VERBOSE_DECOMPOSE - _dbus_verbose ("Decomposing path \"%s\"\n", - data); -#endif - - n_components = 0; - if (len > 1) /* if path is not just "/" */ - { - i = 0; - while (i < len) - { - if (data[i] == '/') - n_components += 1; - ++i; - } - } - - retval = dbus_new0 (char*, n_components + 1); - - if (retval == NULL) - return FALSE; - - comp = 0; - if (n_components == 0) - i = 1; - else - i = 0; - while (comp < n_components) - { - _dbus_assert (i < len); - - if (data[i] == '/') - ++i; - j = i; - - while (j < len && data[j] != '/') - ++j; - - /* Now [i, j) is the path component */ - _dbus_assert (i < j); - _dbus_assert (data[i] != '/'); - _dbus_assert (j == len || data[j] == '/'); - -#if VERBOSE_DECOMPOSE - _dbus_verbose (" (component in [%d,%d))\n", - i, j); -#endif - - retval[comp] = _dbus_memdup (&data[i], j - i + 1); - if (retval[comp] == NULL) - { - dbus_free_string_array (retval); - return FALSE; - } - retval[comp][j-i] = '\0'; -#if VERBOSE_DECOMPOSE - _dbus_verbose (" (component %d = \"%s\")\n", - comp, retval[comp]); -#endif - - ++comp; - i = j; - } - _dbus_assert (i == len); - - *path = retval; - if (path_len) - *path_len = n_components; - - return TRUE; -} - + /** @} */ #ifdef DBUS_BUILD_TESTS @@ -1137,31 +952,22 @@ static char* flatten_path (const char **path) { DBusString str; + int i; char *s; if (!_dbus_string_init (&str)) return NULL; - if (path[0] == NULL) + i = 0; + while (path[i]) { if (!_dbus_string_append_byte (&str, '/')) goto nomem; - } - else - { - int i; - - i = 0; - while (path[i]) - { - if (!_dbus_string_append_byte (&str, '/')) - goto nomem; - - if (!_dbus_string_append (&str, path[i])) - goto nomem; - - ++i; - } + + if (!_dbus_string_append (&str, path[i])) + goto nomem; + + ++i; } if (!_dbus_string_steal_data (&str, &s)) @@ -1300,7 +1106,7 @@ do_register (DBusObjectTree *tree, { DBusObjectPathVTable vtable = { test_unregister_function, test_message_function, NULL }; - + tree_test_data[i].message_handled = FALSE; tree_test_data[i].handler_unregistered = FALSE; tree_test_data[i].handler_fallback = fallback; @@ -1387,82 +1193,17 @@ do_test_dispatch (DBusObjectTree *tree, } static size_t -string_array_length (const char **array) +string_array_length (char **array) { size_t i; for (i = 0; array[i]; i++) ; return i; } -typedef struct -{ - const char *path; - const char *result[20]; -} DecomposePathTest; - -static DecomposePathTest decompose_tests[] = { - { "/foo", { "foo", NULL } }, - { "/foo/bar", { "foo", "bar", NULL } }, - { "/", { NULL } }, - { "/a/b", { "a", "b", NULL } }, - { "/a/b/c", { "a", "b", "c", NULL } }, - { "/a/b/c/d", { "a", "b", "c", "d", NULL } }, - { "/foo/bar/q", { "foo", "bar", "q", NULL } }, - { "/foo/bar/this/is/longer", { "foo", "bar", "this", "is", "longer", NULL } } -}; - -static dbus_bool_t -run_decompose_tests (void) -{ - int i; - - i = 0; - while (i < _DBUS_N_ELEMENTS (decompose_tests)) - { - char **result; - int result_len; - int expected_len; - - if (!_dbus_decompose_path (decompose_tests[i].path, - strlen (decompose_tests[i].path), - &result, &result_len)) - return FALSE; - - expected_len = string_array_length (decompose_tests[i].result); - - if (result_len != (int) string_array_length ((const char**)result) || - expected_len != result_len || - path_contains (decompose_tests[i].result, - (const char**) result) != STR_EQUAL) - { - int real_len = string_array_length ((const char**)result); - _dbus_warn ("Expected decompose of %s to have len %d, returned %d, appears to have %d\n", - decompose_tests[i].path, expected_len, result_len, - real_len); - _dbus_warn ("Decompose resulted in elements: { "); - i = 0; - while (i < real_len) - { - _dbus_warn ("\"%s\"%s", result[i], - (i + 1) == real_len ? "" : ", "); - ++i; - } - _dbus_warn ("}\n"); - _dbus_assert_not_reached ("path decompose failed\n"); - } - - dbus_free_string_array (result); - - ++i; - } - - return TRUE; -} static dbus_bool_t object_tree_test_iteration (void *data) { - const char *path0[] = { NULL }; const char *path1[] = { "foo", NULL }; const char *path2[] = { "foo", "bar", NULL }; const char *path3[] = { "foo", "bar", "baz", NULL }; @@ -1472,46 +1213,19 @@ object_tree_test_iteration (void *data) const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL }; const char *path8[] = { "childless", NULL }; DBusObjectTree *tree; - TreeTestData tree_test_data[9]; + TreeTestData tree_test_data[8]; int i; dbus_bool_t exact_match; - if (!run_decompose_tests ()) - return FALSE; - tree = NULL; tree = _dbus_object_tree_new (NULL); if (tree == NULL) goto out; - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) - goto out; - - _dbus_assert (find_subtree (tree, path0, NULL)); - _dbus_assert (!find_subtree (tree, path1, NULL)); - _dbus_assert (!find_subtree (tree, path2, NULL)); - _dbus_assert (!find_subtree (tree, path3, NULL)); - _dbus_assert (!find_subtree (tree, path4, NULL)); - _dbus_assert (!find_subtree (tree, path5, NULL)); - _dbus_assert (!find_subtree (tree, path6, NULL)); - _dbus_assert (!find_subtree (tree, path7, NULL)); - _dbus_assert (!find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match); - _dbus_assert (find_handler (tree, path1, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path2, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path3, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path4, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path5, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path6, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match); - _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - - if (!do_register (tree, path1, TRUE, 1, tree_test_data)) + if (!do_register (tree, path1, TRUE, 0, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1521,7 +1235,6 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - _dbus_assert (find_handler (tree, path0, &exact_match) && exact_match); _dbus_assert (find_handler (tree, path1, &exact_match) && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) && !exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) && !exact_match); @@ -1531,7 +1244,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_handler (tree, path7, &exact_match) == tree->root && !exact_match); _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; _dbus_assert (find_subtree (tree, path1, NULL)); @@ -1543,10 +1256,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1556,10 +1268,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1569,10 +1280,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1581,8 +1291,7 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path6, NULL)); _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match); + _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match); @@ -1592,10 +1301,9 @@ object_tree_test_iteration (void *data) _dbus_assert (find_handler (tree, path7, &exact_match) != tree->root && !exact_match); _dbus_assert (find_handler (tree, path8, &exact_match) == tree->root && !exact_match); - if (!do_register (tree, path6, TRUE, 6, tree_test_data)) + if (!do_register (tree, path6, TRUE, 5, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1605,10 +1313,9 @@ object_tree_test_iteration (void *data) _dbus_assert (!find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1618,10 +1325,9 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path7, NULL)); _dbus_assert (!find_subtree (tree, path8, NULL)); - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; - _dbus_assert (find_subtree (tree, path0, NULL)); _dbus_assert (find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1630,8 +1336,7 @@ object_tree_test_iteration (void *data) _dbus_assert (find_subtree (tree, path6, NULL)); _dbus_assert (find_subtree (tree, path7, NULL)); _dbus_assert (find_subtree (tree, path8, NULL)); - - _dbus_assert (find_handler (tree, path0, &exact_match) == tree->root && exact_match); + _dbus_assert (find_handler (tree, path1, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path2, &exact_match) != tree->root && exact_match); _dbus_assert (find_handler (tree, path3, &exact_match) != tree->root && exact_match); @@ -1651,7 +1356,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path1, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 1); dbus_free_string_array (child_entries); } @@ -1659,7 +1364,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path2, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 2); dbus_free_string_array (child_entries); } @@ -1667,7 +1372,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, path8, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 0); dbus_free_string_array (child_entries); } @@ -1675,7 +1380,7 @@ object_tree_test_iteration (void *data) _dbus_object_tree_list_registered_unlocked (tree, root, &child_entries); if (child_entries != NULL) { - nb = string_array_length ((const char**)child_entries); + nb = string_array_length (child_entries); _dbus_assert (nb == 3); dbus_free_string_array (child_entries); } @@ -1697,40 +1402,25 @@ object_tree_test_iteration (void *data) if (tree == NULL) goto out; - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) + if (!do_register (tree, path1, TRUE, 0, tree_test_data)) goto out; - if (!do_register (tree, path1, TRUE, 1, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path6, TRUE, 5, tree_test_data)) goto out; - if (!do_register (tree, path6, TRUE, 6, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) - goto out; - - _dbus_object_tree_unregister_and_unlock (tree, path0); - - _dbus_assert (!find_subtree (tree, path0, NULL)); - _dbus_assert (find_subtree (tree, path1, NULL)); - _dbus_assert (find_subtree (tree, path2, NULL)); - _dbus_assert (find_subtree (tree, path3, NULL)); - _dbus_assert (find_subtree (tree, path4, NULL)); - _dbus_assert (find_subtree (tree, path5, NULL)); - _dbus_assert (find_subtree (tree, path6, NULL)); - _dbus_assert (find_subtree (tree, path7, NULL)); - _dbus_assert (find_subtree (tree, path8, NULL)); _dbus_object_tree_unregister_and_unlock (tree, path1); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1742,7 +1432,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path2); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (find_subtree (tree, path3, NULL)); @@ -1754,7 +1443,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path3); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1766,7 +1454,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path4); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1778,7 +1465,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path5); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1790,7 +1476,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path6); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1802,7 +1487,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path7); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1814,7 +1498,6 @@ object_tree_test_iteration (void *data) _dbus_object_tree_unregister_and_unlock (tree, path8); - _dbus_assert (!find_subtree (tree, path0, NULL)); _dbus_assert (!find_subtree (tree, path1, NULL)); _dbus_assert (!find_subtree (tree, path2, NULL)); _dbus_assert (!find_subtree (tree, path3, NULL)); @@ -1833,47 +1516,43 @@ object_tree_test_iteration (void *data) } /* Register it all again, and test dispatch */ - - if (!do_register (tree, path0, TRUE, 0, tree_test_data)) - goto out; - if (!do_register (tree, path1, FALSE, 1, tree_test_data)) + + if (!do_register (tree, path1, FALSE, 0, tree_test_data)) goto out; - if (!do_register (tree, path2, TRUE, 2, tree_test_data)) + if (!do_register (tree, path2, TRUE, 1, tree_test_data)) goto out; - if (!do_register (tree, path3, TRUE, 3, tree_test_data)) + if (!do_register (tree, path3, TRUE, 2, tree_test_data)) goto out; - if (!do_register (tree, path4, TRUE, 4, tree_test_data)) + if (!do_register (tree, path4, TRUE, 3, tree_test_data)) goto out; - if (!do_register (tree, path5, TRUE, 5, tree_test_data)) + if (!do_register (tree, path5, TRUE, 4, tree_test_data)) goto out; - if (!do_register (tree, path6, FALSE, 6, tree_test_data)) + if (!do_register (tree, path6, FALSE, 5, tree_test_data)) goto out; - if (!do_register (tree, path7, TRUE, 7, tree_test_data)) + if (!do_register (tree, path7, TRUE, 6, tree_test_data)) goto out; - if (!do_register (tree, path8, TRUE, 8, tree_test_data)) + if (!do_register (tree, path8, TRUE, 7, tree_test_data)) goto out; #if 0 spew_tree (tree); #endif - - if (!do_test_dispatch (tree, path0, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) - goto out; - if (!do_test_dispatch (tree, path1, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + + if (!do_test_dispatch (tree, path1, 0, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path2, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path2, 1, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path3, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path3, 2, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path4, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path4, 3, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path5, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path5, 4, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path6, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path6, 5, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path7, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path7, 6, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; - if (!do_test_dispatch (tree, path8, 8, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) + if (!do_test_dispatch (tree, path8, 7, tree_test_data, _DBUS_N_ELEMENTS (tree_test_data))) goto out; out: diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index 546f42a6..3844e473 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -291,6 +291,24 @@ dbus_pending_call_steal_reply (DBusPendingCall *pending) } /** + * Gets the reply, or returns #NULL if none has been received yet. The + * reference count is not incremented on the returned message, so you + * have to keep a reference count on the pending call (or add one + * to the message). + * + * @todo not thread safe? I guess it has to lock though it sucks + * @todo maybe to make this threadsafe, it should be steal_reply(), i.e. only one thread can ever get the message + * + * @param pending the pending call + * @returns the reply message or #NULL. + */ +DBusMessage* +dbus_pending_call_get_reply (DBusPendingCall *pending) +{ + return pending->reply; +} + +/** * Block until the pending call is completed. The blocking is as with * dbus_connection_send_with_reply_and_block(); it does not enter the * main loop or process other messages, it simply waits for the reply diff --git a/dbus/dbus-server-protected.h b/dbus/dbus-server-protected.h index 7d09f64b..c8aa8601 100644 --- a/dbus/dbus-server-protected.h +++ b/dbus/dbus-server-protected.h @@ -25,27 +25,15 @@ #include <config.h> #include <dbus/dbus-internals.h> -#include <dbus/dbus-threads-internal.h> #include <dbus/dbus-server.h> #include <dbus/dbus-timeout.h> #include <dbus/dbus-watch.h> #include <dbus/dbus-resources.h> #include <dbus/dbus-dataslot.h> -#include <dbus/dbus-string.h> DBUS_BEGIN_DECLS typedef struct DBusServerVTable DBusServerVTable; -typedef union DBusGUID DBusGUID; - -/** - * A server's globally unique ID - */ -union DBusGUID -{ - dbus_uint32_t as_uint32s[4]; - unsigned char as_bytes[16]; -}; /** * Virtual table to be implemented by all server "subclasses" @@ -67,11 +55,6 @@ struct DBusServer DBusAtomic refcount; /**< Reference count. */ const DBusServerVTable *vtable; /**< Virtual methods for this instance. */ DBusMutex *mutex; /**< Lock on the server object */ - - DBusGUID guid; /**< Globally unique ID of server */ - - DBusString guid_hex; /**< Hex-encoded version of GUID */ - DBusWatchList *watches; /**< Our watches */ DBusTimeoutList *timeouts; /**< Our timeouts */ @@ -119,7 +102,6 @@ void _dbus_server_toggle_timeout (DBusServer *server, dbus_bool_t enabled); void _dbus_server_ref_unlocked (DBusServer *server); -void _dbus_server_unref_unlocked (DBusServer *server); #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(server) @@ -142,14 +124,14 @@ void _dbus_server_unref_unlocked (DBusServer *server); #define SERVER_LOCK(server) do { \ if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \ - _dbus_mutex_lock ((server)->mutex); \ + dbus_mutex_lock ((server)->mutex); \ TOOK_LOCK_CHECK (server); \ } while (0) #define SERVER_UNLOCK(server) do { \ if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \ RELEASING_LOCK_CHECK (server); \ - _dbus_mutex_unlock ((server)->mutex); \ + dbus_mutex_unlock ((server)->mutex); \ } while (0) DBUS_END_DECLS diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index a72bccf1..e6e1c9a3 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -61,12 +61,6 @@ unix_finalize (DBusServer *server) _dbus_server_finalize_base (server); - if (unix_server->watch) - { - _dbus_watch_unref (unix_server->watch); - unix_server->watch = NULL; - } - dbus_free (unix_server->socket_name); dbus_free (server); } @@ -75,9 +69,6 @@ unix_finalize (DBusServer *server) * @todo unreffing the connection at the end may cause * us to drop the last ref to the connection before * disconnecting it. That is invalid. - * - * @todo doesn't this leak a server refcount if - * new_connection_function is NULL? */ /* Return value is just for memory, not other failures. */ static dbus_bool_t @@ -99,7 +90,7 @@ handle_new_client_fd_and_unlock (DBusServer *server, return TRUE; } - transport = _dbus_transport_new_for_fd (client_fd, &server->guid_hex, NULL); + transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL); if (transport == NULL) { close (client_fd); @@ -209,8 +200,6 @@ unix_disconnect (DBusServer *server) { DBusServerUnix *unix_server = (DBusServerUnix*) server; - HAVE_LOCK_CHECK (server); - if (unix_server->watch) { _dbus_server_remove_watch (server, @@ -228,8 +217,6 @@ unix_disconnect (DBusServer *server) _dbus_string_init_const (&tmp, unix_server->socket_name); _dbus_delete_file (&tmp, NULL); } - - HAVE_LOCK_CHECK (server); } static DBusServerVTable unix_vtable = { @@ -255,13 +242,12 @@ _dbus_server_new_for_fd (int fd, const DBusString *address) { DBusServerUnix *unix_server; - DBusServer *server; DBusWatch *watch; unix_server = dbus_new0 (DBusServerUnix, 1); if (unix_server == NULL) return NULL; - + watch = _dbus_watch_new (fd, DBUS_WATCH_READABLE, TRUE, @@ -281,25 +267,26 @@ _dbus_server_new_for_fd (int fd, return NULL; } - server = (DBusServer*) unix_server; - - SERVER_LOCK (server); +#ifndef DBUS_DISABLE_CHECKS + unix_server->base.have_server_lock = TRUE; +#endif if (!_dbus_server_add_watch (&unix_server->base, watch)) { - SERVER_UNLOCK (server); _dbus_server_finalize_base (&unix_server->base); _dbus_watch_unref (watch); dbus_free (unix_server); return NULL; } + +#ifndef DBUS_DISABLE_CHECKS + unix_server->base.have_server_lock = FALSE; +#endif unix_server->fd = fd; unix_server->watch = watch; - SERVER_UNLOCK (server); - return (DBusServer*) unix_server; } @@ -321,7 +308,6 @@ _dbus_server_new_for_domain_socket (const char *path, int listen_fd; DBusString address; char *path_copy; - DBusString path_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -331,12 +317,11 @@ _dbus_server_new_for_domain_socket (const char *path, return NULL; } - _dbus_string_init_const (&path_str, path); if ((abstract && !_dbus_string_append (&address, "unix:abstract=")) || (!abstract && !_dbus_string_append (&address, "unix:path=")) || - !_dbus_address_append_escaped (&address, &path_str)) + !_dbus_string_append (&address, path)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto failed_0; @@ -399,7 +384,6 @@ _dbus_server_new_for_tcp_socket (const char *host, DBusServer *server; int listen_fd; DBusString address; - DBusString host_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -412,9 +396,8 @@ _dbus_server_new_for_tcp_socket (const char *host, if (host == NULL) host = "localhost"; - _dbus_string_init_const (&host_str, host); if (!_dbus_string_append (&address, "tcp:host=") || - !_dbus_address_append_escaped (&address, &host_str) || + !_dbus_string_append (&address, host) || !_dbus_string_append (&address, ",port=") || !_dbus_string_append_int (&address, port)) { diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 0a3b522d..788aaad7 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ /* dbus-server.c DBusServer object * - * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. + * Copyright (C) 2002, 2003, 2004 Red Hat Inc. * * Licensed under the Academic Free License version 2.1 * @@ -52,55 +52,6 @@ * @{ */ -static void -init_guid (DBusGUID *guid) -{ - long now; - char *p; - int ts_size; - - _dbus_get_current_time (&now, NULL); - - guid->as_uint32s[0] = now; - - ts_size = sizeof (guid->as_uint32s[0]); - p = ((char*)guid->as_bytes) + ts_size; - - _dbus_generate_random_bytes_buffer (p, - sizeof (guid->as_bytes) - ts_size); -} - -/* this is a little fragile since it assumes the address doesn't - * already have a guid, but it shouldn't - */ -static char* -copy_address_with_guid_appended (const DBusString *address, - const DBusString *guid_hex) -{ - DBusString with_guid; - char *retval; - - if (!_dbus_string_init (&with_guid)) - return NULL; - - if (!_dbus_string_copy (address, 0, &with_guid, - _dbus_string_get_length (&with_guid)) || - !_dbus_string_append (&with_guid, ",guid=") || - !_dbus_string_copy (guid_hex, 0, - &with_guid, _dbus_string_get_length (&with_guid))) - { - _dbus_string_free (&with_guid); - return NULL; - } - - retval = NULL; - _dbus_string_steal_data (&with_guid, &retval); - - _dbus_string_free (&with_guid); - - return retval; /* may be NULL if steal_data failed */ -} - /** * Initializes the members of the DBusServer base class. * Chained up to by subclass constructors. @@ -115,33 +66,17 @@ _dbus_server_init_base (DBusServer *server, const DBusServerVTable *vtable, const DBusString *address) { - DBusString guid_raw; - server->vtable = vtable; server->refcount.value = 1; server->address = NULL; server->watches = NULL; server->timeouts = NULL; - - if (!_dbus_string_init (&server->guid_hex)) - return FALSE; - - init_guid (&server->guid); - - _dbus_string_init_const_len (&guid_raw, server->guid.as_bytes, - sizeof (server->guid.as_bytes)); - if (!_dbus_string_hex_encode (&guid_raw, 0, - &server->guid_hex, - _dbus_string_get_length (&server->guid_hex))) - goto failed; - server->address = copy_address_with_guid_appended (address, - &server->guid_hex); - if (server->address == NULL) + if (!_dbus_string_copy_data (address, &server->address)) goto failed; - - server->mutex = _dbus_mutex_new (); + + server->mutex = dbus_mutex_new (); if (server->mutex == NULL) goto failed; @@ -162,7 +97,7 @@ _dbus_server_init_base (DBusServer *server, failed: if (server->mutex) { - _dbus_mutex_free (server->mutex); + dbus_mutex_free (server->mutex); server->mutex = NULL; } if (server->watches) @@ -180,7 +115,6 @@ _dbus_server_init_base (DBusServer *server, dbus_free (server->address); server->address = NULL; } - _dbus_string_free (&server->guid_hex); return FALSE; } @@ -193,87 +127,23 @@ _dbus_server_init_base (DBusServer *server, */ void _dbus_server_finalize_base (DBusServer *server) -{ - /* We don't have the lock, but nobody should be accessing - * concurrently since they don't have a ref - */ -#ifndef DBUS_DISABLE_CHECKS - _dbus_assert (!server->have_server_lock); -#endif - _dbus_assert (server->disconnected); - +{ /* calls out to application code... */ _dbus_data_slot_list_free (&server->slot_list); dbus_server_set_new_connection_function (server, NULL, NULL, NULL); + if (!server->disconnected) + dbus_server_disconnect (server); + _dbus_watch_list_free (server->watches); _dbus_timeout_list_free (server->timeouts); - _dbus_mutex_free (server->mutex); + dbus_mutex_free (server->mutex); dbus_free (server->address); dbus_free_string_array (server->auth_mechanisms); - - _dbus_string_free (&server->guid_hex); -} - - -typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list, - DBusWatch *watch); -typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list, - DBusWatch *watch); -typedef void (* DBusWatchToggleFunction) (DBusWatchList *list, - DBusWatch *watch, - dbus_bool_t enabled); - -static dbus_bool_t -protected_change_watch (DBusServer *server, - DBusWatch *watch, - DBusWatchAddFunction add_function, - DBusWatchRemoveFunction remove_function, - DBusWatchToggleFunction toggle_function, - dbus_bool_t enabled) -{ - DBusWatchList *watches; - dbus_bool_t retval; - - HAVE_LOCK_CHECK (server); - - /* This isn't really safe or reasonable; a better pattern is the "do - * everything, then drop lock and call out" one; but it has to be - * propagated up through all callers - */ - - watches = server->watches; - if (watches) - { - server->watches = NULL; - _dbus_server_ref_unlocked (server); - SERVER_UNLOCK (server); - - if (add_function) - retval = (* add_function) (watches, watch); - else if (remove_function) - { - retval = TRUE; - (* remove_function) (watches, watch); - } - else - { - retval = TRUE; - (* toggle_function) (watches, watch, enabled); - } - - SERVER_LOCK (server); - server->watches = watches; - _dbus_server_unref_unlocked (server); - - return retval; - } - else - return FALSE; } /** @@ -288,9 +158,7 @@ _dbus_server_add_watch (DBusServer *server, DBusWatch *watch) { HAVE_LOCK_CHECK (server); - return protected_change_watch (server, watch, - _dbus_watch_list_add_watch, - NULL, NULL, FALSE); + return _dbus_watch_list_add_watch (server->watches, watch); } /** @@ -304,10 +172,7 @@ _dbus_server_remove_watch (DBusServer *server, DBusWatch *watch) { HAVE_LOCK_CHECK (server); - protected_change_watch (server, watch, - NULL, - _dbus_watch_list_remove_watch, - NULL, FALSE); + _dbus_watch_list_remove_watch (server->watches, watch); } /** @@ -324,70 +189,11 @@ _dbus_server_toggle_watch (DBusServer *server, DBusWatch *watch, dbus_bool_t enabled) { - _dbus_assert (watch != NULL); - HAVE_LOCK_CHECK (server); - protected_change_watch (server, watch, - NULL, NULL, - _dbus_watch_list_toggle_watch, - enabled); -} - - -typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list, - DBusTimeout *timeout); -typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list, - DBusTimeout *timeout); -typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list, - DBusTimeout *timeout, - dbus_bool_t enabled); - - -static dbus_bool_t -protected_change_timeout (DBusServer *server, - DBusTimeout *timeout, - DBusTimeoutAddFunction add_function, - DBusTimeoutRemoveFunction remove_function, - DBusTimeoutToggleFunction toggle_function, - dbus_bool_t enabled) -{ - DBusTimeoutList *timeouts; - dbus_bool_t retval; - HAVE_LOCK_CHECK (server); - - /* This isn't really safe or reasonable; a better pattern is the "do everything, then - * drop lock and call out" one; but it has to be propagated up through all callers - */ - - timeouts = server->timeouts; - if (timeouts) - { - server->timeouts = NULL; - _dbus_server_ref_unlocked (server); - SERVER_UNLOCK (server); - - if (add_function) - retval = (* add_function) (timeouts, timeout); - else if (remove_function) - { - retval = TRUE; - (* remove_function) (timeouts, timeout); - } - else - { - retval = TRUE; - (* toggle_function) (timeouts, timeout, enabled); - } - - SERVER_LOCK (server); - server->timeouts = timeouts; - _dbus_server_unref_unlocked (server); - - return retval; - } - else - return FALSE; + if (server->watches) /* null during finalize */ + _dbus_watch_list_toggle_watch (server->watches, + watch, enabled); } /** @@ -403,9 +209,9 @@ dbus_bool_t _dbus_server_add_timeout (DBusServer *server, DBusTimeout *timeout) { - return protected_change_timeout (server, timeout, - _dbus_timeout_list_add_timeout, - NULL, NULL, FALSE); + HAVE_LOCK_CHECK (server); + + return _dbus_timeout_list_add_timeout (server->timeouts, timeout); } /** @@ -418,10 +224,9 @@ void _dbus_server_remove_timeout (DBusServer *server, DBusTimeout *timeout) { - protected_change_timeout (server, timeout, - NULL, - _dbus_timeout_list_remove_timeout, - NULL, FALSE); + HAVE_LOCK_CHECK (server); + + _dbus_timeout_list_remove_timeout (server->timeouts, timeout); } /** @@ -438,10 +243,11 @@ _dbus_server_toggle_timeout (DBusServer *server, DBusTimeout *timeout, dbus_bool_t enabled) { - protected_change_timeout (server, timeout, - NULL, NULL, - _dbus_timeout_list_toggle_timeout, - enabled); + HAVE_LOCK_CHECK (server); + + if (server->timeouts) /* null during finalize */ + _dbus_timeout_list_toggle_timeout (server->timeouts, + timeout, enabled); } @@ -506,9 +312,7 @@ dbus_server_listen (const char *address, for (i = 0; i < len; i++) { - const char *method; - - method = dbus_address_entry_get_method (entries[i]); + const char *method = dbus_address_entry_get_method (entries[i]); if (strcmp (method, "unix") == 0) { @@ -674,7 +478,6 @@ DBusServer * dbus_server_ref (DBusServer *server) { _dbus_return_val_if_fail (server != NULL, NULL); - _dbus_return_val_if_fail (server->refcount.value > 0, NULL); #ifdef DBUS_HAVE_ATOMIC_INT _dbus_atomic_inc (&server->refcount); @@ -691,9 +494,9 @@ dbus_server_ref (DBusServer *server) /** * Decrements the reference count of a DBusServer. Finalizes the - * server if the reference count reaches zero. - * - * The server must be disconnected before the refcount reaches zero. + * server if the reference count reaches zero. The server connection + * will be closed as with dbus_server_disconnect() when the server is + * finalized. * * @param server the server. */ @@ -703,7 +506,6 @@ dbus_server_unref (DBusServer *server) dbus_bool_t last_unref; _dbus_return_if_fail (server != NULL); - _dbus_return_if_fail (server->refcount.value > 0); #ifdef DBUS_HAVE_ATOMIC_INT last_unref = (_dbus_atomic_dec (&server->refcount) == 1); @@ -720,9 +522,6 @@ dbus_server_unref (DBusServer *server) if (last_unref) { - /* lock not held! */ - _dbus_assert (server->disconnected); - _dbus_assert (server->vtable->finalize != NULL); (* server->vtable->finalize) (server); @@ -737,9 +536,6 @@ dbus_server_unref (DBusServer *server) void _dbus_server_ref_unlocked (DBusServer *server) { - _dbus_assert (server != NULL); - _dbus_assert (server->refcount.value > 0); - HAVE_LOCK_CHECK (server); #ifdef DBUS_HAVE_ATOMIC_INT @@ -752,42 +548,6 @@ _dbus_server_ref_unlocked (DBusServer *server) } /** - * Like dbus_server_unref() but does not acquire the lock (must already be held) - * - * @param server the server. - */ -void -_dbus_server_unref_unlocked (DBusServer *server) -{ - dbus_bool_t last_unref; - - _dbus_assert (server != NULL); - _dbus_assert (server->refcount.value > 0); - - HAVE_LOCK_CHECK (server); - -#ifdef DBUS_HAVE_ATOMIC_INT - last_unref = (_dbus_atomic_dec (&server->refcount) == 1); -#else - _dbus_assert (server->refcount.value > 0); - - server->refcount.value -= 1; - last_unref = (server->refcount.value == 0); -#endif - - if (last_unref) - { - _dbus_assert (server->disconnected); - - SERVER_UNLOCK (server); - - _dbus_assert (server->vtable->finalize != NULL); - - (* server->vtable->finalize) (server); - } -} - -/** * Releases the server's address and stops listening for * new clients. If called more than once, only the first * call has an effect. Does not modify the server's @@ -799,23 +559,18 @@ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); - _dbus_return_if_fail (server->refcount.value > 0); SERVER_LOCK (server); - _dbus_server_ref_unlocked (server); _dbus_assert (server->vtable->disconnect != NULL); - if (!server->disconnected) - { - /* this has to be first so recursive calls to disconnect don't happen */ - server->disconnected = TRUE; - - (* server->vtable->disconnect) (server); - } + if (server->disconnected) + return; + + (* server->vtable->disconnect) (server); + server->disconnected = TRUE; SERVER_UNLOCK (server); - dbus_server_unref (server); } /** @@ -1180,7 +935,6 @@ _dbus_server_test (void) if (server == NULL) _dbus_assert_not_reached ("Failed to listen for valid address."); - dbus_server_disconnect (server); dbus_server_unref (server); /* Try disconnecting before unreffing */ @@ -1189,6 +943,7 @@ _dbus_server_test (void) _dbus_assert_not_reached ("Failed to listen for valid address."); dbus_server_disconnect (server); + dbus_server_unref (server); } diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c index 4c07d5f3..2959886a 100644 --- a/dbus/dbus-transport-unix.c +++ b/dbus/dbus-transport-unix.c @@ -1114,13 +1114,13 @@ static DBusTransportVTable unix_vtable = { * boil down to a full duplex file descriptor. * * @param fd the file descriptor. - * @param server_guid non-#NULL if this transport is on the server side of a connection + * @param server #TRUE if this transport is on the server side of a connection * @param address the transport's address * @returns the new transport, or #NULL if no memory. */ DBusTransport* _dbus_transport_new_for_fd (int fd, - const DBusString *server_guid, + dbus_bool_t server, const DBusString *address) { DBusTransportUnix *unix_transport; @@ -1151,7 +1151,7 @@ _dbus_transport_new_for_fd (int fd, if (!_dbus_transport_init_base (&unix_transport->base, &unix_vtable, - server_guid, address)) + server, address)) goto failed_4; unix_transport->fd = fd; diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index b271d944..59eb8e44 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -75,22 +75,19 @@ live_messages_size_notify (DBusCounter *counter, } /** - * Initializes the base class members of DBusTransport. Chained up to - * by subclasses in their constructor. The server GUID is the - * globally unique ID for the server creating this connection - * and will be #NULL for the client side of a connection. The GUID - * is in hex format. + * Initializes the base class members of DBusTransport. + * Chained up to by subclasses in their constructor. * * @param transport the transport being created. * @param vtable the subclass vtable. - * @param server_guid non-#NULL if this transport is on the server side of a connection + * @param server #TRUE if this transport is on the server side of a connection * @param address the address of the transport * @returns #TRUE on success. */ dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, - const DBusString *server_guid, + dbus_bool_t server, const DBusString *address) { DBusMessageLoader *loader; @@ -102,8 +99,8 @@ _dbus_transport_init_base (DBusTransport *transport, if (loader == NULL) return FALSE; - if (server_guid) - auth = _dbus_auth_server_new (server_guid); + if (server) + auth = _dbus_auth_server_new (); else auth = _dbus_auth_client_new (); if (auth == NULL) @@ -120,7 +117,7 @@ _dbus_transport_init_base (DBusTransport *transport, return FALSE; } - if (server_guid) + if (server) { _dbus_assert (address == NULL); address_copy = NULL; @@ -145,9 +142,9 @@ _dbus_transport_init_base (DBusTransport *transport, transport->live_messages_size = counter; transport->authenticated = FALSE; transport->disconnected = FALSE; - transport->is_server = (server_guid != NULL); - transport->send_credentials_pending = !transport->is_server; - transport->receive_credentials_pending = transport->is_server; + transport->send_credentials_pending = !server; + transport->receive_credentials_pending = server; + transport->is_server = server; transport->address = address_copy; transport->unix_user_function = NULL; @@ -198,22 +195,33 @@ _dbus_transport_finalize_base (DBusTransport *transport) } /** - * Try to open a new transport for the given address entry. (This - * opens a client-side-of-the-connection transport.) + * Opens a new transport for the given address. (This opens a + * client-side-of-the-connection transport.) + * + * @todo error messages on bad address could really be better. + * DBusResultCode is a bit limiting here. * - * @param entry the address entry + * @param address the address. * @param error location to store reason for failure. * @returns new transport of #NULL on failure. */ DBusTransport* -_dbus_transport_open (DBusAddressEntry *entry, - DBusError *error) +_dbus_transport_open (const char *address, + DBusError *error) { DBusTransport *transport; + DBusAddressEntry **entries; + DBusError tmp_error; + DBusError first_error; + int len, i; const char *address_problem_type; const char *address_problem_field; const char *address_problem_other; - const char *method; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!dbus_parse_address (address, &entries, &len, error)) + return NULL; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -221,96 +229,125 @@ _dbus_transport_open (DBusAddressEntry *entry, address_problem_type = NULL; address_problem_field = NULL; address_problem_other = NULL; - - method = dbus_address_entry_get_method (entry); - _dbus_assert (method != NULL); - - if (strcmp (method, "unix") == 0) + + dbus_error_init (&tmp_error); + dbus_error_init (&first_error); + for (i = 0; i < len; i++) { - const char *path = dbus_address_entry_get_value (entry, "path"); - const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); - const char *abstract = dbus_address_entry_get_value (entry, "abstract"); + const char *method; + + method = dbus_address_entry_get_method (entries[i]); + + if (strcmp (method, "unix") == 0) + { + const char *path = dbus_address_entry_get_value (entries[i], "path"); + const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir"); + const char *abstract = dbus_address_entry_get_value (entries[i], "abstract"); - if (tmpdir != NULL) - { - address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"; - goto bad_address; - } + if (tmpdir != NULL) + { + address_problem_other = "cannot use the \"tmpdir\" option for an address to connect to, only in an address to listen on"; + goto bad_address; + } - if (path == NULL && abstract == NULL) - { - address_problem_type = "unix"; - address_problem_field = "path or abstract"; - goto bad_address; - } + if (path == NULL && abstract == NULL) + { + address_problem_type = "unix"; + address_problem_field = "path or abstract"; + goto bad_address; + } - if (path != NULL && abstract != NULL) - { - address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address"; - goto bad_address; - } + if (path != NULL && abstract != NULL) + { + address_problem_other = "can't specify both \"path\" and \"abstract\" options in an address"; + goto bad_address; + } - if (path) - transport = _dbus_transport_new_for_domain_socket (path, FALSE, - error); - else - transport = _dbus_transport_new_for_domain_socket (abstract, TRUE, - error); - } - else if (strcmp (method, "tcp") == 0) - { - const char *host = dbus_address_entry_get_value (entry, "host"); - const char *port = dbus_address_entry_get_value (entry, "port"); - DBusString str; - long lport; - dbus_bool_t sresult; + if (path) + transport = _dbus_transport_new_for_domain_socket (path, FALSE, + &tmp_error); + else + transport = _dbus_transport_new_for_domain_socket (abstract, TRUE, + &tmp_error); + } + else if (strcmp (method, "tcp") == 0) + { + const char *host = dbus_address_entry_get_value (entries[i], "host"); + const char *port = dbus_address_entry_get_value (entries[i], "port"); + DBusString str; + long lport; + dbus_bool_t sresult; - if (port == NULL) - { - address_problem_type = "tcp"; - address_problem_field = "port"; - goto bad_address; - } + if (port == NULL) + { + address_problem_type = "tcp"; + address_problem_field = "port"; + goto bad_address; + } - _dbus_string_init_const (&str, port); - sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); - _dbus_string_free (&str); + _dbus_string_init_const (&str, port); + sresult = _dbus_string_parse_int (&str, 0, &lport, NULL); + _dbus_string_free (&str); - if (sresult == FALSE || lport <= 0 || lport > 65535) - { - address_problem_other = "Port is not an integer between 0 and 65535"; - goto bad_address; - } + if (sresult == FALSE || lport <= 0 || lport > 65535) + { + address_problem_other = "Port is not an integer between 0 and 65535"; + goto bad_address; + } - transport = _dbus_transport_new_for_tcp_socket (host, lport, error); - } + transport = _dbus_transport_new_for_tcp_socket (host, lport, &tmp_error); + } #ifdef DBUS_BUILD_TESTS - else if (strcmp (method, "debug-pipe") == 0) - { - const char *name = dbus_address_entry_get_value (entry, "name"); + else if (strcmp (method, "debug-pipe") == 0) + { + const char *name = dbus_address_entry_get_value (entries[i], "name"); - if (name == NULL) + if (name == NULL) + { + address_problem_type = "debug-pipe"; + address_problem_field = "name"; + goto bad_address; + } + + transport = _dbus_transport_debug_pipe_new (name, &tmp_error); + } +#endif + else { - address_problem_type = "debug-pipe"; - address_problem_field = "name"; + address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")"; goto bad_address; } - - transport = _dbus_transport_debug_pipe_new (name, error); + + if (transport) + break; + + _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); + + if (i == 0) + dbus_move_error (&tmp_error, &first_error); + else + dbus_error_free (&tmp_error); + } + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); + + if (transport == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (&first_error); + dbus_move_error (&first_error, error); } -#endif else { - address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")"; - goto bad_address; + dbus_error_free (&first_error); } - - if (transport == NULL) - _DBUS_ASSERT_ERROR_IS_SET (error); + dbus_address_entries_free (entries); return transport; - + bad_address: + dbus_address_entries_free (entries); + if (address_problem_type != NULL) dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Address of type %s was missing argument %s", @@ -916,10 +953,10 @@ _dbus_transport_get_unix_user (DBusTransport *transport, { DBusCredentials auth_identity; - *uid = _DBUS_INT32_MAX; /* better than some root or system user in - * case of bugs in the caller. Caller should - * never use this value on purpose, however. - */ + *uid = _DBUS_INT_MAX; /* better than some root or system user in + * case of bugs in the caller. Caller should + * never use this value on purpose, however. + */ if (!transport->authenticated) return FALSE; diff --git a/glib/dbus-gproxy.c b/glib/dbus-gproxy.c index b5e977a4..744efdef 100644 --- a/glib/dbus-gproxy.c +++ b/glib/dbus-gproxy.c @@ -1,7 +1,7 @@ /* -*- mode: C; c-file-style: "gnu" -*- */ -/* dbus-gproxy.c Proxy for remote objects +/* dbus-gcall.c convenience routines for calling methods, etc. * - * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. + * Copyright (C) 2003, 2004 Red Hat, Inc. * * Licensed under the Academic Free License version 2.1 * @@ -22,14 +22,8 @@ */ #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> -#include <dbus/dbus-signature.h> #include "dbus-gutils.h" -#include "dbus-gmarshal.h" -#include "dbus-gvalue.h" -#include "dbus-gobject.h" #include <string.h> -#include <glib/gi18n.h> -#include <gobject/gvaluecollector.h> /** * @addtogroup DBusGLibInternals @@ -51,11 +45,9 @@ struct DBusGProxy GObject parent; /**< Parent instance */ DBusGProxyManager *manager; /**< Proxy manager */ - char *name; /**< Name messages go to or NULL */ + char *service; /**< Service messages go to or NULL */ char *path; /**< Path messages go to or NULL */ char *interface; /**< Interface messages go to or NULL */ - - GData *signal_signatures; /**< D-BUS signatures for each signal */ }; /** @@ -66,23 +58,24 @@ struct DBusGProxyClass GObjectClass parent_class; /**< Parent class */ }; -static void dbus_g_proxy_init (DBusGProxy *proxy); -static void dbus_g_proxy_class_init (DBusGProxyClass *klass); -static void dbus_g_proxy_finalize (GObject *object); -static void dbus_g_proxy_dispose (GObject *object); -static void dbus_g_proxy_destroy (DBusGProxy *proxy); -static void dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, - DBusMessage *message); +static void dbus_g_proxy_init (DBusGProxy *proxy); +static void dbus_g_proxy_class_init (DBusGProxyClass *klass); +static void dbus_g_proxy_finalize (GObject *object); +static void dbus_g_proxy_dispose (GObject *object); +static void dbus_g_proxy_destroy (DBusGProxy *proxy); +static void dbus_g_proxy_emit_received (DBusGProxy *proxy, + DBusMessage *message); + /** - * A list of proxies with a given name+path+interface, used to + * A list of proxies with a given service+path+interface, used to * route incoming signals. */ typedef struct { GSList *proxies; /**< The list of proxies */ - char name[4]; /**< name (empty string for none), nul byte, + char name[4]; /**< service (empty string for none), nul byte, * path, nul byte, * interface, nul byte */ @@ -92,7 +85,7 @@ typedef struct /** * DBusGProxyManager's primary task is to route signals to the proxies * those signals are emitted on. In order to do this it also has to - * track the owners of the names proxies are bound to. + * track the owners of the services proxies are bound to. */ struct DBusGProxyManager { @@ -107,10 +100,9 @@ struct DBusGProxyManager }; static DBusGProxyManager *dbus_g_proxy_manager_ref (DBusGProxyManager *manager); -static DBusHandlerResult dbus_g_proxy_manager_filter (DBusConnection *connection, - DBusMessage *message, - void *user_data); - +static DBusHandlerResult dbus_g_proxy_manager_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data); /** Lock the DBusGProxyManager */ #define LOCK_MANAGER(mgr) (g_static_mutex_lock (&(mgr)->lock)) @@ -301,48 +293,48 @@ tristring_equal (gconstpointer a, static char* tristring_alloc_from_strings (size_t padding_before, - const char *name, + const char *service, const char *path, const char *interface) { - size_t name_len, iface_len, path_len, len; + size_t service_len, iface_len, path_len, len; char *tri; - if (name) - name_len = strlen (name); + if (service) + service_len = strlen (service); else - name_len = 0; + service_len = 0; path_len = strlen (path); iface_len = strlen (interface); - tri = g_malloc (padding_before + name_len + path_len + iface_len + 3); + tri = g_malloc (padding_before + service_len + path_len + iface_len + 3); len = padding_before; - if (name) - memcpy (&tri[len], name, name_len); + if (service) + memcpy (&tri[len], service, service_len); - len += name_len; + len += service_len; tri[len] = '\0'; len += 1; - g_assert (len == (padding_before + name_len + 1)); + g_assert (len == (padding_before + service_len + 1)); memcpy (&tri[len], path, path_len); len += path_len; tri[len] = '\0'; len += 1; - g_assert (len == (padding_before + name_len + path_len + 2)); + g_assert (len == (padding_before + service_len + path_len + 2)); memcpy (&tri[len], interface, iface_len); len += iface_len; tri[len] = '\0'; len += 1; - g_assert (len == (padding_before + name_len + path_len + iface_len + 3)); + g_assert (len == (padding_before + service_len + path_len + iface_len + 3)); return tri; } @@ -351,7 +343,7 @@ static char* tristring_from_proxy (DBusGProxy *proxy) { return tristring_alloc_from_strings (0, - proxy->name, + proxy->service, proxy->path, proxy->interface); } @@ -359,18 +351,10 @@ tristring_from_proxy (DBusGProxy *proxy) static char* tristring_from_message (DBusMessage *message) { - const char *path; - const char *interface; - - path = dbus_message_get_path (message); - interface = dbus_message_get_interface (message); - - g_assert (path); - g_assert (interface); - return tristring_alloc_from_strings (0, dbus_message_get_sender (message), - path, interface); + dbus_message_get_path (message), + dbus_message_get_interface (message)); } static DBusGProxyList* @@ -379,7 +363,7 @@ g_proxy_list_new (DBusGProxy *first_proxy) DBusGProxyList *list; list = (void*) tristring_alloc_from_strings (G_STRUCT_OFFSET (DBusGProxyList, name), - first_proxy->name, + first_proxy->service, first_proxy->path, first_proxy->interface); list->proxies = NULL; @@ -403,9 +387,9 @@ g_proxy_get_match_rule (DBusGProxy *proxy) { /* FIXME Escaping is required here */ - if (proxy->name) + if (proxy->service) return g_strdup_printf ("type='signal',sender='%s',path='%s',interface='%s'", - proxy->name, proxy->path, proxy->interface); + proxy->service, proxy->path, proxy->interface); else return g_strdup_printf ("type='signal',path='%s',interface='%s'", proxy->path, proxy->interface); @@ -413,7 +397,7 @@ g_proxy_get_match_rule (DBusGProxy *proxy) static void dbus_g_proxy_manager_register (DBusGProxyManager *manager, - DBusGProxy *proxy) + DBusGProxy *proxy) { DBusGProxyList *list; @@ -568,8 +552,8 @@ dbus_g_proxy_manager_list_all (DBusGProxyManager *manager) static DBusHandlerResult dbus_g_proxy_manager_filter (DBusConnection *connection, - DBusMessage *message, - void *user_data) + DBusMessage *message, + void *user_data) { DBusGProxyManager *manager; @@ -583,7 +567,7 @@ dbus_g_proxy_manager_filter (DBusConnection *connection, LOCK_MANAGER (manager); if (dbus_message_is_signal (message, - DBUS_INTERFACE_LOCAL, + DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) { /* Destroy all the proxies, quite possibly resulting in unreferencing @@ -620,11 +604,6 @@ dbus_g_proxy_manager_filter (DBusConnection *connection, { char *tri; DBusGProxyList *list; - - /* dbus spec requires these, libdbus validates */ - g_assert (dbus_message_get_path (message) != NULL); - g_assert (dbus_message_get_interface (message) != NULL); - g_assert (dbus_message_get_member (message) != NULL); tri = tristring_from_message (message); @@ -661,7 +640,7 @@ dbus_g_proxy_manager_filter (DBusConnection *connection, proxy = DBUS_G_PROXY (tmp->data); UNLOCK_MANAGER (manager); - dbus_g_proxy_emit_remote_signal (proxy, message); + dbus_g_proxy_emit_received (proxy, message); g_object_unref (G_OBJECT (proxy)); LOCK_MANAGER (manager); @@ -685,15 +664,7 @@ dbus_g_proxy_manager_filter (DBusConnection *connection, /* ---------- DBusGProxy -------------- */ -#define DBUS_G_PROXY_DESTROYED(proxy) (DBUS_G_PROXY (proxy)->manager == NULL) -static void -marshal_dbus_message_to_g_marshaller (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); enum { @@ -708,7 +679,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; static void dbus_g_proxy_init (DBusGProxy *proxy) { - g_datalist_init (&proxy->signal_signatures); + /* Nothing */ } static void @@ -729,17 +700,19 @@ dbus_g_proxy_class_init (DBusGProxyClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - + signals[RECEIVED] = g_signal_new ("received", G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, - NULL, NULL, - marshal_dbus_message_to_g_marshaller, - G_TYPE_NONE, 2, DBUS_TYPE_MESSAGE, G_TYPE_STRING); + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + DBUS_TYPE_MESSAGE); } + static void dbus_g_proxy_dispose (GObject *object) { @@ -747,15 +720,6 @@ dbus_g_proxy_dispose (GObject *object) proxy = DBUS_G_PROXY (object); - if (proxy->manager) - { - dbus_g_proxy_manager_unregister (proxy->manager, proxy); - dbus_g_proxy_manager_unref (proxy->manager); - proxy->manager = NULL; - } - - g_datalist_clear (&proxy->signal_signatures); - g_signal_emit (object, signals[DESTROY], 0); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -765,12 +729,16 @@ static void dbus_g_proxy_finalize (GObject *object) { DBusGProxy *proxy; - + proxy = DBUS_G_PROXY (object); - g_return_if_fail (DBUS_G_PROXY_DESTROYED (proxy)); + if (proxy->manager) + { + dbus_g_proxy_manager_unregister (proxy->manager, proxy); + dbus_g_proxy_manager_unref (proxy->manager); + } - g_free (proxy->name); + g_free (proxy->service); g_free (proxy->path); g_free (proxy->interface); @@ -786,169 +754,29 @@ dbus_g_proxy_destroy (DBusGProxy *proxy) g_object_run_dispose (G_OBJECT (proxy)); } -/* this is to avoid people using g_signal_connect() directly, - * to avoid confusion with local signal names, and because - * of the horribly broken current setup (signals are added - * globally to all proxies) - */ static char* -create_signal_name (const char *interface, - const char *signal) +create_signal_detail (const char *interface, + const char *signal) { GString *str; - char *p; str = g_string_new (interface); - g_string_append (str, "-"); - + g_string_append (str, "."); + g_string_append (str, signal); - /* GLib will silently barf on '.' in signal names */ - p = str->str; - while (*p) - { - if (*p == '.') - *p = '-'; - ++p; - } - return g_string_free (str, FALSE); } -static GSignalCMarshaller -lookup_g_marshaller (DBusGProxy *proxy, - const char *signature) -{ - /* The "proxy" arg would eventually be used if you could provide - * a marshaller when adding a signal to the proxy - */ - -#define MATCH1(sig, t0) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == '\0') -#define MATCH2(sig, t0, t1) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == (DBUS_TYPE_##t1) && (sig)[2] == '\0') -#define MATCH3(sig, t0, t1, t2) ((sig)[0] == (DBUS_TYPE_##t0) && (sig)[1] == (DBUS_TYPE_##t1) && (sig)[2] == (DBUS_TYPE_##t2) && (sig)[3] == '\0') - - switch (*signature) - { - case '\0': - return g_cclosure_marshal_VOID__VOID; - - case DBUS_TYPE_BOOLEAN: - if (MATCH1 (signature, BOOLEAN)) - return g_cclosure_marshal_VOID__BOOLEAN; - break; - - case DBUS_TYPE_BYTE: - if (MATCH1 (signature, BYTE)) - return g_cclosure_marshal_VOID__UCHAR; - break; - - case DBUS_TYPE_INT16: - if (MATCH1 (signature, INT16)) - return g_cclosure_marshal_VOID__INT; - break; - - case DBUS_TYPE_UINT16: - if (MATCH1 (signature, UINT16)) - return g_cclosure_marshal_VOID__UINT; - break; - - case DBUS_TYPE_INT32: - if (MATCH1 (signature, INT32)) - return g_cclosure_marshal_VOID__INT; - break; - - case DBUS_TYPE_UINT32: - if (MATCH1 (signature, UINT32)) - return g_cclosure_marshal_VOID__UINT; - break; - - case DBUS_TYPE_DOUBLE: - if (MATCH1 (signature, DOUBLE)) - return g_cclosure_marshal_VOID__DOUBLE; - break; - - case DBUS_TYPE_OBJECT_PATH: - if (MATCH1 (signature, OBJECT_PATH)) - return g_cclosure_marshal_VOID__STRING; - break; - - case DBUS_TYPE_SIGNATURE: - if (MATCH1 (signature, SIGNATURE)) - return g_cclosure_marshal_VOID__STRING; - break; - - case DBUS_TYPE_STRING: - if (MATCH1 (signature, STRING)) - return g_cclosure_marshal_VOID__STRING; - /* This is for NameOwnerChanged */ - else if (MATCH3 (signature, STRING, STRING, STRING)) - return _dbus_g_marshal_NONE__STRING_STRING_STRING; - break; - } - - return NULL; -} - -static void -marshal_dbus_message_to_g_marshaller (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - /* Incoming here we have three params, the instance (Proxy), the - * DBusMessage, the signature. We want to convert that to an - * expanded GValue array, then call an appropriate normal GLib - * marshaller. - */ -#define MAX_SIGNATURE_ARGS 20 - GValueArray *value_array; - GValue value = {0, }; - GSignalCMarshaller c_marshaller; - DBusGProxy *proxy; - DBusMessage *message; - const char *signature; - - g_assert (n_param_values == 3); - - proxy = g_value_get_object (¶m_values[0]); - message = g_value_get_boxed (¶m_values[1]); - signature = g_value_get_string (¶m_values[2]); - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (message != NULL); - g_return_if_fail (signature != NULL); - - c_marshaller = lookup_g_marshaller (proxy, signature); - - g_return_if_fail (c_marshaller != NULL); - - value_array = _dbus_glib_marshal_dbus_message_to_gvalue_array (message); - - g_return_if_fail (value_array != NULL); - - g_value_init (&value, G_TYPE_FROM_INSTANCE (proxy)); - g_value_set_instance (&value, proxy); - g_value_array_prepend (value_array, &value); - - (* c_marshaller) (closure, return_value, value_array->n_values, - value_array->values, invocation_hint, marshal_data); - - g_value_array_free (value_array); -} - static void -dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, - DBusMessage *message) +dbus_g_proxy_emit_received (DBusGProxy *proxy, + DBusMessage *message) { const char *interface; const char *signal; - char *name; + char *detail; GQuark q; - - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); interface = dbus_message_get_interface (message); signal = dbus_message_get_member (message); @@ -956,47 +784,21 @@ dbus_g_proxy_emit_remote_signal (DBusGProxy *proxy, g_assert (interface != NULL); g_assert (signal != NULL); - name = create_signal_name (interface, signal); + detail = create_signal_detail (interface, signal); /* If the quark isn't preexisting, there's no way there * are any handlers connected. We don't want to create * extra quarks for every possible signal. */ - q = g_quark_try_string (name); + q = g_quark_try_string (detail); if (q != 0) - { - const char *signature; + g_signal_emit (G_OBJECT (proxy), + signals[RECEIVED], + q, + message); - signature = g_datalist_id_get_data (&proxy->signal_signatures, q); - if (signature == NULL) - { -#if 0 - /* this should not trigger a warning, as you shouldn't have to - * add signals you don't care about - */ - g_warning ("Signal '%s' has not been added to this proxy object\n", - name); -#endif - } - else if (!dbus_message_has_signature (message, signature)) - { - g_warning ("Signature '%s' expected for signal '%s', actual signature '%s'\n", - signature, - name, - dbus_message_get_signature (message)); - } - else - { - g_signal_emit (proxy, - signals[RECEIVED], - q, - message, - signature); - } - } - - g_free (name); + g_free (detail); } /** @} End of DBusGLibInternals */ @@ -1040,9 +842,9 @@ dbus_g_proxy_get_type (void) static DBusGProxy* dbus_g_proxy_new (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name) + const char *service_name, + const char *path_name, + const char *interface_name) { DBusGProxy *proxy; @@ -1056,7 +858,7 @@ dbus_g_proxy_new (DBusGConnection *connection, proxy->manager = dbus_g_proxy_manager_get (DBUS_CONNECTION_FROM_G_CONNECTION (connection)); - proxy->name = g_strdup (name); + proxy->service = g_strdup (service_name); proxy->path = g_strdup (path_name); proxy->interface = g_strdup (interface_name); @@ -1066,105 +868,101 @@ dbus_g_proxy_new (DBusGConnection *connection, } /** - * Creates a new proxy for a remote interface exported by a connection - * on a message bus. Method calls and signal connections over this - * proxy will go to the name owner; the name's owner is expected to - * support the given interface name. THE NAME OWNER MAY CHANGE OVER - * TIME, for example between two different method calls, unless the - * name is a unique name. If you need a fixed owner, you need to - * request the current owner and bind a proxy to its unique name - * rather than to the generic name; see - * dbus_g_proxy_new_for_name_owner(). + * Creates a new proxy for a remote interface exported by a service on + * a message bus. Method calls and signal connections over this proxy + * will go to the service owner; the service owner is expected to + * support the given interface name. THE SERVICE OWNER MAY CHANGE OVER + * TIME, for example between two different method calls. If you need a + * fixed owner, you need to request the current owner and bind a proxy + * to that rather than to the generic service name; see + * dbus_g_proxy_new_for_service_owner(). * - * A name-associated proxy only makes sense with a message bus, not - * for app-to-app direct dbus connections. + * A service-associated proxy only makes sense with a message bus, + * not for app-to-app direct dbus connections. * - * This proxy will only emit the "destroy" signal if the - * #DBusConnection is disconnected, the proxy has no remaining - * references, or the name is a unique name and its owner - * disappears. If a well-known name changes owner, the proxy will - * still be alive. + * This proxy will only emit the "destroy" signal if the #DBusConnection + * is disconnected or the proxy is has no remaining references. * * @param connection the connection to the remote bus - * @param name any name on the message bus - * @param path_name name of the object instance to call methods on + * @param service_name name of the service on the message bus + * @param path_name name of the object inside the service to call methods on * @param interface_name name of the interface to call methods on * @returns new proxy object */ DBusGProxy* -dbus_g_proxy_new_for_name (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name) +dbus_g_proxy_new_for_service (DBusGConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name) { DBusGProxy *proxy; g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (service_name != NULL, NULL); g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); - proxy = dbus_g_proxy_new (connection, name, + proxy = dbus_g_proxy_new (connection, service_name, path_name, interface_name); return proxy; } /** - * Similar to dbus_g_proxy_new_for_name(), but makes a round-trip - * request to the message bus to get the current name owner, then - * binds the proxy to the unique name of the current owner, rather - * than to the well-known name. As a result, the name owner will - * not change over time, and the proxy will emit the "destroy" signal - * when the owner disappears from the message bus. + * Similar to dbus_g_proxy_new_for_service(), but makes a round-trip + * request to the message bus to get the current service owner, then + * binds the proxy specifically to the current owner. As a result, the + * service owner will not change over time, and the proxy will emit + * the "destroy" signal when the owner disappears from the message + * bus. * - * An example of the difference between dbus_g_proxy_new_for_name() - * and dbus_g_proxy_new_for_name_owner(): if you provide the well-known name - * "org.freedesktop.Database" dbus_g_proxy_new_for_name() remains bound - * to that name as it changes owner. dbus_g_proxy_new_for_name_owner() - * will fail if the name has no owner. If the name has an owner, - * dbus_g_proxy_new_for_name_owner() will bind to the unique name - * of that owner rather than the generic name. + * An example of the difference between dbus_g_proxy_new_for_service() + * and dbus_g_proxy_new_for_service_owner(): if you pass the service name + * "org.freedesktop.Database" dbus_g_proxy_new_for_service() remains bound + * to that name as it changes owner. dbus_g_proxy_new_for_service_owner() + * will fail if the service has no owner. If the service has an owner, + * dbus_g_proxy_new_for_service_owner() will bind to the unique name + * of that owner rather than the generic service name. * * @param connection the connection to the remote bus - * @param name any name on the message bus + * @param service_name name of the service on the message bus * @param path_name name of the object inside the service to call methods on * @param interface_name name of the interface to call methods on * @param error return location for an error * @returns new proxy object, or #NULL on error */ DBusGProxy* -dbus_g_proxy_new_for_name_owner (DBusGConnection *connection, - const char *name, - const char *path_name, - const char *interface_name, - GError **error) +dbus_g_proxy_new_for_service_owner (DBusGConnection *connection, + const char *service_name, + const char *path_name, + const char *interface_name, + GError **error) { DBusGProxy *proxy; DBusMessage *request, *reply; DBusError derror; - const char *unique_name; - + char *base_service_name; + g_return_val_if_fail (connection != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (service_name != NULL, NULL); g_return_val_if_fail (path_name != NULL, NULL); g_return_val_if_fail (interface_name != NULL, NULL); dbus_error_init (&derror); proxy = NULL; - unique_name = NULL; + base_service_name = NULL; reply = NULL; - request = dbus_message_new_method_call (DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetNameOwner"); + request = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS, + DBUS_PATH_ORG_FREEDESKTOP_DBUS, + DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, + "GetServiceOwner"); if (request == NULL) g_error ("Out of memory"); if (! dbus_message_append_args (request, - DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, service_name, DBUS_TYPE_INVALID)) g_error ("Out of memory"); @@ -1179,13 +977,13 @@ dbus_g_proxy_new_for_name_owner (DBusGConnection *connection, goto error; if (! dbus_message_get_args (reply, &derror, - DBUS_TYPE_STRING, &unique_name, + DBUS_TYPE_STRING, &base_service_name, DBUS_TYPE_INVALID)) goto error; - proxy = dbus_g_proxy_new (connection, unique_name, - path_name, interface_name); + proxy = dbus_g_proxy_new (connection, base_service_name, + path_name, interface_name); goto out; @@ -1199,6 +997,7 @@ dbus_g_proxy_new_for_name_owner (DBusGConnection *connection, dbus_message_unref (request); if (reply) dbus_message_unref (reply); + dbus_free (base_service_name); return proxy; } @@ -1219,8 +1018,8 @@ dbus_g_proxy_new_for_name_owner (DBusGConnection *connection, */ DBusGProxy* dbus_g_proxy_new_for_peer (DBusGConnection *connection, - const char *path_name, - const char *interface_name) + const char *path_name, + const char *interface_name) { DBusGProxy *proxy; @@ -1229,32 +1028,12 @@ dbus_g_proxy_new_for_peer (DBusGConnection *connection, g_return_val_if_fail (interface_name != NULL, NULL); proxy = dbus_g_proxy_new (connection, NULL, - path_name, interface_name); + path_name, interface_name); return proxy; } /** - * Gets the bus name a proxy is bound to (may be #NULL in some cases). - * If you created the proxy with dbus_g_proxy_new_for_name(), then - * the name you passed to that will be returned. - * If you created it with dbus_g_proxy_new_for_name_owner(), then the - * unique connection name will be returned. If you created it - * with dbus_g_proxy_new_for_peer() then #NULL will be returned. - * - * @param proxy the proxy - * @returns the bus name the proxy sends messages to - */ -const char* -dbus_g_proxy_get_bus_name (DBusGProxy *proxy) -{ - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), NULL); - - return proxy->name; -} - -/** * Invokes a method on a remote interface. This function does not * block; instead it returns an opaque #DBusPendingCall object that * tracks the pending call. The method call will not be sent over the @@ -1284,9 +1063,8 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy, va_list args; g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), NULL); - message = dbus_message_new_method_call (proxy->name, + message = dbus_message_new_method_call (proxy->service, proxy->path, proxy->interface, method); @@ -1321,43 +1099,39 @@ dbus_g_proxy_begin_call (DBusGProxy *proxy, * Collects the results of a method call. The method call was normally * initiated with dbus_g_proxy_end_call(). This function will block if * the results haven't yet been received; use - * dbus_g_pending_call_set_notify() to be notified asynchronously that a - * pending call has been completed. If it's completed, it will not block. + * dbus_pending_call_set_notify() to be notified asynchronously that a + * pending call has been completed. Use + * dbus_pending_call_get_completed() to check whether a call has been + * completed. If it's completed, it will not block. * * If the call results in an error, the error is set as normal for * GError and the function returns #FALSE. * * Otherwise, the "out" parameters and return value of the * method are stored in the provided varargs list. - * The list should be terminated with #DBUS_TYPE_INVALID. + * The list should be terminated with DBUS_TYPE_INVALID. * * This function doesn't affect the reference count of the - * #DBusGPendingCall, the caller of dbus_g_proxy_begin_call() still owns + * #DBusPendingCall, the caller of dbus_g_proxy_begin_call() still owns * a reference. * - * @todo this should be changed to make a g_malloc() copy of the - * data returned probably; right now the data vanishes - * when you free the PendingCall which is sort of strange. - * * @param proxy a proxy for a remote interface * @param pending the pending call from dbus_g_proxy_begin_call() * @param error return location for an error * @param first_arg_type type of first "out" argument - * @returns #FALSE if an error is set - */ + * @returns #FALSE if an error is set */ gboolean dbus_g_proxy_end_call (DBusGProxy *proxy, - DBusGPendingCall *pending, - GError **error, - int first_arg_type, - ...) + DBusGPendingCall *pending, + GError **error, + int first_arg_type, + ...) { DBusMessage *message; va_list args; DBusError derror; g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); g_return_val_if_fail (pending != NULL, FALSE); dbus_pending_call_block (DBUS_PENDING_CALL_FROM_G_PENDING_CALL (pending)); @@ -1393,215 +1167,12 @@ dbus_g_proxy_end_call (DBusGProxy *proxy, error: dbus_message_unref (message); - dbus_set_g_error (error, &derror); dbus_error_free (&derror); return FALSE; } /** - * Function for invoking a method and receiving reply values. - * Normally this is not used directly - calls to it are generated - * from client-side wrappers (see dbus-binding-tool). - * - * This function takes two type signatures, one for method arguments, - * and one for return values. The remaining arguments after the - * error parameter should be values of the input arguments, - * followed by pointer values to storage for return values. - * - * @param proxy a proxy for a remote interface - * @param method method to invoke - * @param insig signature of input values - * @param outsig signature of output values - * @param error return location for an error - * @returns #FALSE if an error is set, TRUE otherwise - */ -gboolean -dbus_g_proxy_invoke (DBusGProxy *proxy, - const char *method, - const char *insig, - const char *outsig, - GError **error, - ...) -{ - DBusPendingCall *pending; - DBusMessage *message; - DBusMessage *reply; - va_list args; - va_list args_unwind; - int n_retvals_processed; - DBusMessageIter msgiter; - DBusSignatureIter sigiter; - int expected_type; - gboolean ret; - DBusError derror; - - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), FALSE); - g_return_val_if_fail (!DBUS_G_PROXY_DESTROYED (proxy), FALSE); - - va_start (args, error); - /* Keep around a copy of output arguments so we - * can free on error. */ - G_VA_COPY (args_unwind, args); - - ret = FALSE; - pending = NULL; - reply = NULL; - n_retvals_processed = 0; - message = dbus_message_new_method_call (proxy->name, - proxy->path, - proxy->interface, - method); - if (message == NULL) - goto oom; - - dbus_signature_iter_init (&sigiter, insig); - dbus_message_iter_init_append (message, &msgiter); - while ((expected_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID) - { - GValue gvalue = {0, }; - char *collect_err; - - if (!dbus_gvalue_init (expected_type, &gvalue)) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Unsupported type '%c'"), expected_type); - goto out; - } - - G_VALUE_COLLECT (&gvalue, args, G_VALUE_NOCOPY_CONTENTS, &collect_err); - - if (collect_err) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - collect_err); - goto out; - } - - /* Anything we can init must be marshallable */ - if (!dbus_gvalue_marshal (&msgiter, &gvalue)) - g_assert_not_reached (); - g_value_unset (&gvalue); - - dbus_signature_iter_next (&sigiter); - } - - if (!dbus_connection_send_with_reply (proxy->manager->connection, - message, - &pending, - -1)) - goto oom; - - dbus_pending_call_block (pending); - reply = dbus_pending_call_steal_reply (pending); - - g_assert (reply != NULL); - - dbus_error_init (&derror); - - switch (dbus_message_get_type (reply)) - { - case DBUS_MESSAGE_TYPE_METHOD_RETURN: - - dbus_signature_iter_init (&sigiter, outsig); - dbus_message_iter_init (reply, &msgiter); - while ((expected_type = dbus_signature_iter_get_current_type (&sigiter)) != DBUS_TYPE_INVALID) - { - int arg_type; - gpointer *value_ret; - GValue gvalue = { 0, }; - - value_ret = va_arg (args, gpointer *); - - arg_type = dbus_message_iter_get_arg_type (&msgiter); - if (expected_type != arg_type) - { - if (arg_type == DBUS_TYPE_INVALID) - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too few arguments in reply")); - else - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Reply argument was \"%c\", expected \"%c\""), - arg_type, expected_type); - goto out; - } - - if (!dbus_gvalue_demarshal (&msgiter, &gvalue)) - { - g_set_error (error, - DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Couldn't convert argument type \"%c\""), expected_type); - goto out; - } - /* Anything that can be demarshaled must be storable */ - if (!dbus_gvalue_store (&gvalue, value_ret)) - g_assert_not_reached (); - g_value_unset (&gvalue); - - n_retvals_processed++; - dbus_signature_iter_next (&sigiter); - dbus_message_iter_next (&msgiter); - } - if (dbus_message_iter_get_arg_type (&msgiter) != DBUS_TYPE_INVALID) - { - g_set_error (error, DBUS_GERROR, - DBUS_GERROR_INVALID_ARGS, - _("Too many arguments")); - goto out; - } - break; - case DBUS_MESSAGE_TYPE_ERROR: - dbus_set_error_from_message (&derror, reply); - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - goto out; - break; - default: - dbus_set_error (&derror, DBUS_ERROR_FAILED, - "Reply was neither a method return nor an exception"); - dbus_set_g_error (error, &derror); - dbus_error_free (&derror); - goto out; - break; - } - - ret = TRUE; - out: - va_end (args); - - if (ret == FALSE) - { - int i; - for (i = 0; i < n_retvals_processed; i++) - { - gpointer retval; - - retval = va_arg (args_unwind, gpointer); - - g_free (retval); - } - } - va_end (args_unwind); - - if (pending) - dbus_pending_call_unref (pending); - if (message) - dbus_message_unref (message); - if (reply) - dbus_message_unref (reply); - return ret; - oom: - g_error ("Out of memory"); - ret = FALSE; - goto out; -} - -/** * Sends a method call message as with dbus_g_proxy_begin_call(), but * does not ask for a reply or allow you to receive one. * @@ -1622,9 +1193,8 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy, va_list args; g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - message = dbus_message_new_method_call (proxy->name, + message = dbus_message_new_method_call (proxy->service, proxy->path, proxy->interface, method); @@ -1657,7 +1227,7 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy, * dbus_connection_flush(). * * The message is modified to be addressed to the target interface. - * That is, a destination name field or whatever is needed will be + * That is, a destination service field or whatever is needed will be * added to the message. The basic point of this function is to add * the necessary header fields, otherwise it's equivalent to * dbus_connection_send(). @@ -1670,15 +1240,14 @@ dbus_g_proxy_call_no_reply (DBusGProxy *proxy, * @param client_serial return location for message's serial, or #NULL */ void dbus_g_proxy_send (DBusGProxy *proxy, - DBusMessage *message, - dbus_uint32_t *client_serial) + DBusMessage *message, + dbus_uint32_t *client_serial) { g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - if (proxy->name) + if (proxy->service) { - if (!dbus_message_set_destination (message, proxy->name)) + if (!dbus_message_set_destination (message, proxy->service)) g_error ("Out of memory"); } if (proxy->path) @@ -1697,49 +1266,14 @@ dbus_g_proxy_send (DBusGProxy *proxy, } /** - * Specifies the signature of a signal, such that it's possible to - * connect to the signal on this proxy. - * - * @param proxy the proxy for a remote interface - * @param signal_name the name of the signal - * @param signature D-BUS signature of the signal - */ -void -dbus_g_proxy_add_signal (DBusGProxy *proxy, - const char *signal_name, - const char *signature) -{ - GQuark q; - char *name; - - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); - g_return_if_fail (signal_name != NULL); - g_return_if_fail (signature != NULL); -#ifndef G_DISABLE_CHECKS - if (lookup_g_marshaller (proxy, signature) == NULL) - g_warning ("No marshaller for signature '%s', we need to add API for providing your own", - signature); -#endif - - name = create_signal_name (proxy->interface, signal_name); - - q = g_quark_from_string (name); - - g_return_if_fail (g_datalist_id_get_data (&proxy->signal_signatures, q) == NULL); - - g_datalist_id_set_data_full (&proxy->signal_signatures, - q, g_strdup (signature), - g_free); - - g_free (name); -} - -/** * Connect a signal handler to a proxy for a remote interface. When * the remote interface emits the specified signal, the proxy will * emit a corresponding GLib signal. * + * @todo Right now there's no way to specify the signature to use + * for invoking the GCallback. Need to either rely on introspection, + * or require signature here. + * * @param proxy a proxy for a remote interface * @param signal_name the DBus signal name to listen for * @param handler the handler to connect @@ -1748,41 +1282,27 @@ dbus_g_proxy_add_signal (DBusGProxy *proxy, */ void dbus_g_proxy_connect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback handler, - void *data, - GClosureNotify free_data_func) + const char *signal_name, + GCallback handler, + void *data, + GClosureNotify free_data_func) { - char *name; GClosure *closure; - GQuark q; + char *detail; g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); g_return_if_fail (signal_name != NULL); g_return_if_fail (handler != NULL); - name = create_signal_name (proxy->interface, signal_name); - - q = g_quark_try_string (name); - -#ifndef G_DISABLE_CHECKS - if (q == 0 || g_datalist_id_get_data (&proxy->signal_signatures, q) == NULL) - { - g_warning ("Must add the signal '%s' with dbus_g_proxy_add_signal() prior to connecting to it\n", name); - g_free (name); - return; - } -#endif + detail = create_signal_detail (proxy->interface, signal_name); closure = g_cclosure_new (G_CALLBACK (handler), data, free_data_func); - g_signal_connect_closure_by_id (G_OBJECT (proxy), signals[RECEIVED], - q, + g_quark_from_string (detail), closure, FALSE); - - g_free (name); + + g_free (detail); } /** @@ -1796,40 +1316,38 @@ dbus_g_proxy_connect_signal (DBusGProxy *proxy, */ void dbus_g_proxy_disconnect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback handler, - void *data) + const char *signal_name, + GCallback handler, + void *data) { - char *name; + char *detail; GQuark q; g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (!DBUS_G_PROXY_DESTROYED (proxy)); g_return_if_fail (signal_name != NULL); g_return_if_fail (handler != NULL); - name = create_signal_name (proxy->interface, signal_name); + detail = create_signal_detail (proxy->interface, signal_name); + q = g_quark_try_string (detail); + g_free (detail); - q = g_quark_try_string (name); - - if (q != 0) - { - g_signal_handlers_disconnect_matched (G_OBJECT (proxy), - G_SIGNAL_MATCH_DETAIL | - G_SIGNAL_MATCH_FUNC | - G_SIGNAL_MATCH_DATA, - signals[RECEIVED], - q, - NULL, - G_CALLBACK (handler), data); - } - else +#ifndef G_DISABLE_CHECKS + if (q == 0) { - g_warning ("Attempt to disconnect from signal '%s' which is not registered\n", - name); + g_warning ("%s: No signal handlers for %s found on this DBusGProxy", + G_GNUC_FUNCTION, signal_name); + return; } +#endif - g_free (name); + g_signal_handlers_disconnect_matched (G_OBJECT (proxy), + G_SIGNAL_MATCH_DETAIL | + G_SIGNAL_MATCH_FUNC | + G_SIGNAL_MATCH_DATA, + signals[RECEIVED], + q, + NULL, + G_CALLBACK (handler), data); } /** @} End of DBusGLib public */ diff --git a/mono/Arguments.cs b/mono/Arguments.cs index 61ae443f..f8e3ccea 100644 --- a/mono/Arguments.cs +++ b/mono/Arguments.cs @@ -191,12 +191,6 @@ namespace DBus return (char) dbusType.InvokeMember("Code", BindingFlags.Static | BindingFlags.GetField, null, null, null); } - // Get the type code for a given D-BUS type as a string - public static string GetCodeAsString (Type dbusType) - { - return GetCode (dbusType).ToString (); - } - // Get a complete method signature public override string ToString() { @@ -215,7 +209,7 @@ namespace DBus key += code; } while (dbus_message_iter_next(iter)); } - + Marshal.FreeCoTaskMem(iter); return key; @@ -231,7 +225,7 @@ namespace DBus // Begin appending public void InitAppending() { - dbus_message_iter_init_append(message.RawMessage, appenderIter); + dbus_message_append_iter_init(message.RawMessage, appenderIter); } // Get the enumerator @@ -291,7 +285,7 @@ namespace DBus } [DllImport("dbus-1")] - private extern static void dbus_message_iter_init_append(IntPtr rawMessage, IntPtr iter); + private extern static void dbus_message_append_iter_init(IntPtr rawMessage, IntPtr iter); [DllImport("dbus-1")] private extern static bool dbus_message_iter_has_next(IntPtr iter); diff --git a/mono/Connection.cs b/mono/Connection.cs index af0764db..50b2dd99 100644 --- a/mono/Connection.cs +++ b/mono/Connection.cs @@ -161,23 +161,22 @@ namespace DBus { if (!dbus_connection_register_object_path (RawConnection, path, ref vtable, IntPtr.Zero)) throw new OutOfMemoryException (); - + this.object_paths[path] = vtable; } - + internal void UnregisterObjectPath (string path) { dbus_connection_unregister_object_path (RawConnection, path); - + this.object_paths.Remove (path); } - - public string UniqueName + public string BaseService { get { - return Marshal.PtrToStringAnsi (dbus_bus_get_unique_name (RawConnection)); + return Marshal.PtrToStringAnsi (dbus_bus_get_base_service (RawConnection)); } } @@ -317,7 +316,7 @@ namespace DBus private extern static void dbus_connection_disconnect (IntPtr ptr); [DllImport ("dbus-1")] - private extern static IntPtr dbus_bus_get_unique_name (IntPtr ptr); + private extern static IntPtr dbus_bus_get_base_service (IntPtr ptr); [DllImport("dbus-1")] private extern static bool dbus_connection_add_filter(IntPtr rawConnection, diff --git a/mono/DBusType/ObjectPath.cs b/mono/DBusType/ObjectPath.cs index 4f064d59..38952f4e 100644 --- a/mono/DBusType/ObjectPath.cs +++ b/mono/DBusType/ObjectPath.cs @@ -28,11 +28,10 @@ namespace DBus.DBusType public ObjectPath(IntPtr iter, Service service) { - IntPtr raw; + IntPtr raw_str = dbus_message_iter_get_object_path (iter); + this.path = Marshal.PtrToStringAnsi (raw_str); + dbus_free (raw_str); - dbus_message_iter_get_basic (iter, out raw); - - this.path = Marshal.PtrToStringAnsi (raw); this.service = service; } @@ -50,10 +49,10 @@ namespace DBus.DBusType public void Append(IntPtr iter) { - IntPtr marshalVal = Marshal.StringToHGlobalAnsi (Path); + IntPtr raw_str = Marshal.StringToHGlobalAnsi (Path); - bool success = dbus_message_iter_append_basic (iter, (int) Code, ref marshalVal); - Marshal.FreeHGlobal (marshalVal); + bool success = dbus_message_iter_append_object_path (iter, raw_str); + Marshal.FreeHGlobal (raw_str); if (!success) throw new ApplicationException("Failed to append OBJECT_PATH argument:" + val); @@ -99,9 +98,12 @@ namespace DBus.DBusType } [DllImport("dbus-1")] - private extern static void dbus_message_iter_get_basic (IntPtr iter, out IntPtr path); + private extern static IntPtr dbus_message_iter_get_object_path(IntPtr iter); [DllImport("dbus-1")] - private extern static bool dbus_message_iter_append_basic (IntPtr iter, int type, ref IntPtr path); + private extern static bool dbus_message_iter_append_object_path(IntPtr iter, IntPtr path); + + [DllImport("dbus-1")] + private extern static void dbus_free (IntPtr raw); } } diff --git a/mono/DBusType/String.cs b/mono/DBusType/String.cs index 3b619cfb..9d7502fa 100644 --- a/mono/DBusType/String.cs +++ b/mono/DBusType/String.cs @@ -25,19 +25,17 @@ namespace DBus.DBusType public String(IntPtr iter, Service service) { - IntPtr raw; - - dbus_message_iter_get_basic (iter, out raw); - - this.val = Marshal.PtrToStringAnsi (raw); + IntPtr raw_str = dbus_message_iter_get_string (iter); + this.val = Marshal.PtrToStringAnsi (raw_str); + dbus_free (raw_str); } public void Append(IntPtr iter) { - IntPtr marshalVal = Marshal.StringToHGlobalAnsi (val); + IntPtr raw_str = Marshal.StringToHGlobalAnsi (val); - bool success = dbus_message_iter_append_basic (iter, (int) Code, ref marshalVal); - Marshal.FreeHGlobal (marshalVal); + bool success = dbus_message_iter_append_string (iter, raw_str); + Marshal.FreeHGlobal (raw_str); if (!success) throw new ApplicationException("Failed to append STRING argument:" + val); @@ -87,9 +85,12 @@ namespace DBus.DBusType } [DllImport("dbus-1")] - private extern static void dbus_message_iter_get_basic (IntPtr iter, out IntPtr value); + private extern static IntPtr dbus_message_iter_get_string(IntPtr iter); [DllImport("dbus-1")] - private extern static bool dbus_message_iter_append_basic (IntPtr iter, int type, ref IntPtr value); + private extern static bool dbus_message_iter_append_string(IntPtr iter, IntPtr value); + + [DllImport("dbus-1")] + private extern static void dbus_free (IntPtr raw); } } diff --git a/mono/Service.cs b/mono/Service.cs index 40703a53..fc423b0f 100644 --- a/mono/Service.cs +++ b/mono/Service.cs @@ -20,9 +20,6 @@ namespace DBus private static AssemblyBuilder proxyAssembly; private ModuleBuilder module = null; - // Add a match for signals. FIXME: Can we filter the service? - private const string MatchRule = "type='signal'"; - internal Service(string name, Connection connection) { this.name = name; @@ -38,7 +35,7 @@ namespace DBus // This isn't used for now uint flags = 0; - if (dbus_bus_request_name (connection.RawConnection, name, flags, ref error) == -1) { + if (dbus_bus_acquire_service(connection.RawConnection, name, flags, ref error) == -1) { throw new DBusException(error); } @@ -47,12 +44,12 @@ namespace DBus this.local = true; } - public static bool HasOwner(Connection connection, string name) + public static bool Exists(Connection connection, string name) { Error error = new Error(); error.Init(); - if (dbus_bus_name_has_owner(connection.RawConnection, + if (dbus_bus_service_exists(connection.RawConnection, name, ref error)) { return true; @@ -66,10 +63,10 @@ namespace DBus public static Service Get(Connection connection, string name) { - if (HasOwner(connection, name)) { + if (Exists(connection, name)) { return new Service(name, connection); } else { - throw new ApplicationException("Name '" + name + "' does not exist."); + throw new ApplicationException("Service '" + name + "' does not exist."); } } @@ -178,14 +175,15 @@ namespace DBus } [DllImport("dbus-1")] - private extern static int dbus_bus_request_name(IntPtr rawConnection, - string serviceName, - uint flags, ref Error error); + private extern static int dbus_bus_acquire_service(IntPtr rawConnection, + string serviceName, + uint flags, ref Error error); [DllImport("dbus-1")] - private extern static bool dbus_bus_name_has_owner(IntPtr rawConnection, + private extern static bool dbus_bus_service_exists(IntPtr rawConnection, string serviceName, ref Error error); + } } diff --git a/python/dbus_bindings.pyx.in b/python/dbus_bindings.pyx.in index 6681c458..797b0e51 100644 --- a/python/dbus_bindings.pyx.in +++ b/python/dbus_bindings.pyx.in @@ -5,8 +5,6 @@ # where python conditionals have a ( ) around them, thus violating # PEP-8 were written by the lame wannabe python programmer seth -#FIXME: find memory leaks that I am sure exist - #include "dbus_h_wrapper.h" cdef extern from "stdlib.h": @@ -78,9 +76,6 @@ class ByteArray(str): def __init__(self, value): str.__init__(value) -class Signature(str): - def __init__(self, value): - str.__init__(value) #forward delcerations cdef class Connection @@ -158,8 +153,8 @@ cdef class Connection: cdef DBusConnection *_get_conn(self): return self.conn - def get_unique_name(self): - return bus_get_unique_name(self) + def get_base_service(self): + return bus_get_base_service(self) def setup_with_g_main(self): dbus_connection_setup_with_g_main(self.conn, NULL) @@ -431,17 +426,13 @@ cdef class Watch: cdef class MessageIter: cdef DBusMessageIter *iter cdef DBusMessageIter real_iter - cdef dbus_uint32_t level - def __init__(self, level=0): + def __init__(self): self.iter = &self.real_iter - self.level = level - if(self.level > 32): - raise TypeError, 'Type recurion is too deep' - + cdef __cinit__(self, DBusMessageIter *iter): self.real_iter = iter[0] - + cdef DBusMessageIter *_get_iter(self): return self.iter @@ -451,18 +442,15 @@ cdef class MessageIter: def next(self): return dbus_message_iter_next(self.iter) - def get(self, arg_type=None): - if(arg_type == None): - arg_type = self.get_arg_type() + def get(self): + arg_type = self.get_arg_type() if arg_type == TYPE_INVALID: raise TypeError, 'Invalid arg type in MessageIter' + elif arg_type == TYPE_NIL: + retval = None elif arg_type == TYPE_STRING: retval = self.get_string() - elif arg_type == TYPE_INT16: - retval = self.get_int16() - elif arg_type == TYPE_UINT16: - retval = self.get_uint16() elif arg_type == TYPE_INT32: retval = self.get_int32() elif arg_type == TYPE_UINT32: @@ -477,227 +465,186 @@ cdef class MessageIter: retval = self.get_byte() elif arg_type == TYPE_BOOLEAN: retval = self.get_boolean() - elif arg_type == TYPE_SIGNATURE: - retval = self.get_signature() elif arg_type == TYPE_ARRAY: - array_type = self.get_element_type() - if array_type == TYPE_DICT_ENTRY: - retval = self.get_dict() + array_type = self.get_array_type() + + if array_type == TYPE_STRING: + retval = self.get_string_array() + elif array_type == TYPE_OBJECT_PATH: + retval = self.get_object_path_array() + elif array_type == TYPE_BYTE: + retval = self.get_byte_array() + elif array_type == TYPE_INT32: + retval = self.get_int32_array() + elif array_type == TYPE_UINT32: + retval = self.get_uint32_array() + elif array_type == TYPE_INT64: + retval = self.get_int64_array() + elif array_type == TYPE_UINT64: + retval = self.get_uint64_array() + elif array_type == TYPE_DOUBLE: + retval = self.get_double_array() else: - retval = self.get_array(array_type) + raise TypeError, "Unknown array type %d in MessageIter" % (array_type) + elif arg_type == TYPE_DICT: + retval = self.get_dict() elif arg_type == TYPE_OBJECT_PATH: retval = self.get_object_path() - elif arg_type == TYPE_STRUCT: - retval = self.get_struct() - elif arg_type == TYPE_VARIANT: - retval = self.get_variant() - elif arg_type == TYPE_DICT_ENTRY: - raise TypeError, 'Dictionary Entries can only appear as part of an array container' else: raise TypeError, 'Unknown arg type %d in MessageIter' % (arg_type) return retval - def get_arg_type(self): - return dbus_message_iter_get_arg_type(self.iter) + def get_dict(self): + cdef DBusMessageIter c_dict_iter + cdef MessageIter dict_iter + + dbus_message_iter_init_dict_iterator(self.iter, &c_dict_iter) - def get_element_type(self): - return dbus_message_iter_get_element_type(self.iter) + dict_iter = MessageIter() + dict_iter.__cinit__(&c_dict_iter) - def get_byte(self): - cdef char c_val - dbus_message_iter_get_basic(self.iter, <char *>&c_val) - return c_val - - def get_boolean(self): - cdef dbus_bool_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_bool_t *>&c_val) - return c_val + dict = {} + + end_of_dict = False + + while True: + key = dict_iter.get_dict_key() + value = dict_iter.get() + dict[key] = value + if not dict_iter.has_next(): + break + dict_iter.next() + + return dict - def get_signature(self): - signature_string = self.get_string() - return Signature(signature_string) + def get_arg_type(self): + return dbus_message_iter_get_arg_type(self.iter) - def get_int16(self): - cdef dbus_int16_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_int16_t *>&c_val) - return c_val + def get_array_type(self): + return dbus_message_iter_get_array_type(self.iter) - def get_uint16(self): - cdef dbus_uint16_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_uint16_t *>&c_val) - return c_val + # FIXME: implement get_byte + #def get_byte(self): + # return dbus_message_iter_get_byte(self.iter) + def get_boolean(self): + return dbus_message_iter_get_boolean(self.iter) + def get_int32(self): - cdef dbus_int32_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_int32_t *>&c_val) - return c_val - + return dbus_message_iter_get_int32(self.iter) + def get_uint32(self): - cdef dbus_uint32_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_uint32_t *>&c_val) - return c_val - + return dbus_message_iter_get_uint32(self.iter) + def get_int64(self): - cdef dbus_int64_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_int64_t *>&c_val) - return c_val + return dbus_message_iter_get_int64(self.iter) def get_uint64(self): - cdef dbus_uint64_t c_val - dbus_message_iter_get_basic(self.iter, <dbus_uint64_t *>&c_val) - return c_val + return dbus_message_iter_get_uint64(self.iter) def get_double(self): - cdef double c_val - dbus_message_iter_get_basic(self.iter, <double *>&c_val) - return c_val + return dbus_message_iter_get_double(self.iter) def get_string(self): - cdef char *c_str - dbus_message_iter_get_basic(self.iter, <char **>&c_str) - return c_str + return dbus_message_iter_get_string(self.iter) def get_object_path(self): - object_path_string = self.get_string() + object_path_string = dbus_message_iter_get_object_path(self.iter) return ObjectPath(object_path_string) + + def get_dict_key(self): + return dbus_message_iter_get_dict_key(self.iter) - def get_dict(self): - cdef DBusMessageIter c_dict_iter - cdef MessageIter dict_iter - level = self.level + 1 - - dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_dict_iter) - dict_iter = MessageIter(level) - dict_iter.__cinit__(&c_dict_iter) - - python_dict = {} - cur_arg_type = dict_iter.get_arg_type() - while cur_arg_type == TYPE_DICT_ENTRY: - if cur_arg_type != TYPE_DICT_ENTRY: - raise TypeError, "Dictionary elements must be of type TYPE_DICT_ENTRY '%s != %s'" % (TYPE_DICT_ENTRY, cur_arg_type) - - dict_entry = dict_iter.get_struct() - if len(dict_entry) != 2: - raise TypeError, "Dictionary entries must be structs of two elements. This entry had %i elements.'" % (len(dict_entry)) - - python_dict[dict_entry[0]] = dict_entry[1] - - dict_iter.next() - cur_arg_type = dict_iter.get_arg_type() - - return python_dict - - def get_array(self, type): - cdef DBusMessageIter c_array_iter - cdef MessageIter array_iter - level = self.level + 1 - - dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter) - array_iter = MessageIter(level) - array_iter.__cinit__(&c_array_iter) - + # FIXME: implement dbus_message_iter_init_array_iterator + + def get_byte_array(self): + cdef int len + cdef unsigned char *bytearray + cdef int i + dbus_message_iter_get_byte_array(self.iter, &bytearray, <int*>&len) + python_string = PyString_FromStringAndSize(<char *>bytearray, len) + return python_string + + # FIXME: implement dbus_message_iter_get_boolean_array + + def get_int32_array(self): + cdef int len + cdef dbus_int32_t *retval + cdef int i + dbus_message_iter_get_int32_array(self.iter, &retval, <int*>&len) python_list = [] - cur_arg_type = array_iter.get_arg_type() - while cur_arg_type != TYPE_INVALID: - if cur_arg_type != type: - raise TypeError, "Array elements must be of the same type '%s != %s'" % (type, cur_arg_type) - - value = array_iter.get(type) - python_list.append(value) - - array_iter.next() - cur_arg_type = array_iter.get_arg_type() - + for i from 0 <= i < len: + python_list.append(retval[i]) return python_list - def get_variant(self): - cdef DBusMessageIter c_var_iter - cdef MessageIter var_iter - level = self.level + 1 - - dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_var_iter) - var_iter = MessageIter(level) - var_iter.__cinit__(&c_var_iter) - - return var_iter.get() + def get_uint32_array(self): + cdef int len + cdef dbus_uint32_t *retval + cdef int i + dbus_message_iter_get_uint32_array(self.iter, &retval, <int*>&len) + python_list = [] + for i from 0 <= i < len: + python_list.append(retval[i]) + return python_list - def get_struct(self): - cdef DBusMessageIter c_struct_iter - cdef MessageIter struct_iter - level = self.level + 1 + def get_int64_array(self): + cdef int len + cdef dbus_int64_t *retval + cdef int i + dbus_message_iter_get_int64_array(self.iter, &retval, <int*>&len) + python_list = [] + for i from 0 <= i < len: + python_list.append(retval[i]) + return python_list - dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_struct_iter) - struct_iter = MessageIter(level) - struct_iter.__cinit__(&c_struct_iter) + def get_uint64_array(self): + cdef int len + cdef dbus_uint64_t *retval + cdef int i + dbus_message_iter_get_uint64_array(self.iter, &retval, <int*>&len) + python_list = [] + for i from 0 <= i < len: + python_list.append(retval[i]) + return python_list + def get_double_array(self): + cdef int len + cdef double *retval + cdef int i + dbus_message_iter_get_double_array(self.iter, &retval, <int*>&len) python_list = [] - while struct_iter.get_arg_type() != TYPE_INVALID: - value = struct_iter.get() - python_list.append(value) - - struct_iter.next() - - return tuple(python_list) - - def python_value_to_dbus_sig(self, value, level = 0): - - if(level > 32): - raise TypeError, 'Type recurion is too deep' - - level = level + 1 - - ptype = type(value) - ret = "" - if ptype == bool: - ret = TYPE_BOOL - ret = str(chr(ret)) - elif ptype == int: - ret = TYPE_INT32 - ret = str(chr(ret)) - elif ptype == long: - ret = TYPE_INT64 - ret = str(chr(ret)) - elif ptype == str: - ret = TYPE_STRING - ret = str(chr(ret)) - elif ptype == float: - ret = TYPE_FLOAT - ret = str(chr(ret)) - elif ptype == dict: - dict_list = value.items() - key, value = dict_list[0] - - ret = str(chr(TYPE_ARRAY)) + str(chr(DICT_ENTRY_BEGIN)) - ret = ret + self.python_value_to_dbus_sig(key, level) - ret = ret + self.python_value_to_dbus_sig(value, level) - ret = ret + str(chr(DICT_ENTRY_END)) - - elif ptype == tuple: - ret = str(chr(STRUCT_BEGIN)) - for item in value: - ret = ret + self.python_value_to_dbus_sig(item, level) - ret = ret + str(chr(STRUCT_END)) - elif ptype == list: - ret = str(chr(TYPE_ARRAY)) - ret = ret + self.python_value_to_dbus_sig(value[0], level) - elif isinstance(value, ObjectPath): - ret = TYPE_PATH - ret = str(chr(ret)) - elif isinstance(ByteArray): - ret = str(chr(TYPE_ARRAY)) + str(chr(TYPE_BYTE)) - elif isinstance(Signature): - ret = TYPE_SIGNATURE - ret = str(chr(ret)) - else: - raise TypeError, "Argument of unknown type '%s'" % (ptype) + for i from 0 <= i < len: + python_list.append(retval[i]) + return python_list - return ret - + def get_string_array(self): + cdef int len + cdef char **retval + cdef int i + dbus_message_iter_get_string_array(self.iter, &retval, <int*>&len) + list = [] + for i from 0 <= i < len: + list.append(retval[i]) + return list + + def get_object_path_array(self): + cdef int len + cdef char **retval + cdef int i + dbus_message_iter_get_object_path_array(self.iter, &retval, <int*>&len) + list = [] + for i from 0 <= i < len: + list.append(ObjectPath(retval[i])) + return list + + # dbus_message_append_iter_init included in class Message + #FIXME: handle all the different types? def append(self, value): value_type = type(value) + if value_type == bool: retval = self.append_boolean(value) elif value_type == int: @@ -710,204 +657,170 @@ cdef class MessageIter: retval = self.append_double(value) elif value_type == dict: retval = self.append_dict(value) - elif value_type == tuple: - retval = self.append_struct(value) elif value_type == list: - retval = self.append_array(value) - #elif value_type == None.__class__: - # retval = self.append_nil() + if len(value) == 0: + # Empty lists are currently not supported, returning None instead + retval = self.append(None) + else: + list_type = type(value[0]) + if list_type == str: + self.append_string_array(value) + elif list_type == int: + self.append_int32_array(value) + elif list_type == long: + self.append_int64_array(value) + elif list_type == float: + self.append_double_array(value) + elif isinstance(value[0], ObjectPath): + self.append_object_path_array(value) + else: + raise TypeError, "List of unknown type '%s'" % (list_type) + elif value_type == None.__class__: + retval = self.append_nil() elif isinstance(value, ObjectPath): retval = self.append_object_path(value) elif isinstance(value, ByteArray): - retval = self.append_array(value) - elif isinstance(value, Signature): - retval = self.append_signature(value) + retval = self.append_byte_array(value) else: raise TypeError, "Argument of unknown type '%s'" % (value_type) return retval + def append_nil(self): + return dbus_message_iter_append_nil(self.iter) + def append_boolean(self, value): - cdef dbus_bool_t c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_BOOLEAN, <dbus_bool_t *>&c_value) + return dbus_message_iter_append_boolean(self.iter, value) def append_byte(self, value): - cdef char b if type(value) != str or len(value) != 1: raise TypeError - - b = ord(value) - return dbus_message_iter_append_basic(self.iter, TYPE_BYTE, <char *>&b) + return dbus_message_iter_append_byte(self.iter, ord(value)) def append_int32(self, value): - cdef dbus_int32_t c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_INT32, <dbus_int32_t *>&c_value) + return dbus_message_iter_append_int32(self.iter, value) def append_uint32(self, value): - cdef dbus_uint32_t c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_UINT32, <dbus_uint32_t *>&c_value) + return dbus_message_iter_append_uint32(self.iter, value) def append_int64(self, value): - cdef dbus_int64_t c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_INT64, <dbus_int64_t *>&c_value) + return dbus_message_iter_append_int64(self.iter, value) def append_uint64(self, value): - cdef dbus_uint64_t c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_UINT64, <dbus_uint64_t *>&c_value) + return dbus_message_iter_append_uint64(self.iter, value) def append_double(self, value): - cdef double c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_DOUBLE, <double *>&c_value) + return dbus_message_iter_append_double(self.iter, value) def append_string(self, value): - cdef char *c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_STRING, <char **>&c_value) + return dbus_message_iter_append_string(self.iter, value) - def append_object_path(self, value): - cdef char *c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_PATH, <char **>&c_value) + def append_dict_key(self, value): + return dbus_message_iter_append_dict_key(self.iter, value) - def append_signature(self, value): - cdef char *c_value - c_value = value - return dbus_message_iter_append_basic(self.iter, TYPE_SIGNATURE, <char **>&c_value) + def append_object_path(self, value): + return dbus_message_iter_append_object_path(self.iter, value) + # FIXME: append_array, append_boolean_array, append_uint32_array, + # append_uint64_array def append_dict(self, python_dict): - cdef DBusMessageIter c_dict_iter, c_dict_entry_iter - cdef MessageIter dict_iter, dict_entry_iter + cdef DBusMessageIter c_dict_iter + cdef MessageIter dict_iter - level = self.level + 1 - - dict_list = python_dict.items() - key, value = dict_list[0] - - sig = str(chr(DICT_ENTRY_BEGIN)) - sig = sig + self.python_value_to_dbus_sig(key) - sig = sig + self.python_value_to_dbus_sig(value) - sig = sig + str(chr(DICT_ENTRY_END)) - - dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_dict_iter) - dict_iter = MessageIter(level) - dict_iter.__cinit__(&c_dict_iter) - - for key, value in dict_list: - dbus_message_iter_open_container(dict_iter.iter, TYPE_DICT_ENTRY, sig, <DBusMessageIter *>&c_dict_entry_iter) - dict_entry_iter = MessageIter(level) - dict_entry_iter.__cinit__(&c_dict_entry_iter) - - dict_entry_iter.append(key) - dict_entry_iter.append(value) - - dbus_message_iter_close_container(dict_iter.iter, dict_entry_iter.iter) - - dbus_message_iter_close_container(self.iter, dict_iter.iter) - - def append_struct(self, python_struct): - cdef DBusMessageIter c_struct_iter - cdef MessageIter struct_iter - - level = self.level + 1 - dbus_message_iter_open_container(self.iter, TYPE_STRUCT, NULL, <DBusMessageIter *>&c_struct_iter) - struct_iter = MessageIter(level) - struct_iter.__cinit__(&c_struct_iter) + dbus_message_iter_append_dict(self.iter, &c_dict_iter) - for item in python_struct: - if not struct_iter.append(item): - dbus_message_iter_close_container(self.iter, struct_iter.iter) - return False - - dbus_message_iter_close_container(self.iter, struct_iter.iter) - - def append_array(self, python_list): - cdef DBusMessageIter c_array_iter - cdef MessageIter array_iter - - level = self.level + 1 - sig = self.python_value_to_dbus_sig(python_list[0]) + dict_iter = MessageIter() + dict_iter.__cinit__(&c_dict_iter) - dbus_message_iter_open_container(self.iter, TYPE_ARRAY, sig, <DBusMessageIter *>&c_array_iter) - array_iter = MessageIter(level) - array_iter.__cinit__(&c_array_iter) + for key, value in python_dict.iteritems(): + if type(key) != str: + raise TypeError, "DBus dict keys must be strings" + dict_iter.append_dict_key(key) + dict_iter.append(value) + def append_byte_array(self, python_list): + cdef unsigned char * value + cdef int length + cdef int i length = len(python_list) - for item in python_list: - if not array_iter.append(item): - dbus_message_iter_close_container(self.iter, array_iter.iter) - return False - - dbus_message_iter_close_container(self.iter, array_iter.iter) - - return True - - def __str__(self): - cdef DBusMessageIter c_array_iter - cdef MessageIter array_iter - - value_at_iter = True - retval = "" - while (value_at_iter): - type = self.get_arg_type() - if type == TYPE_INVALID: - break - elif type == TYPE_STRING: - str = iter.get_string() - arg = 'string:%s\n' % (str) - elif type == TYPE_OBJECT_PATH: - path = iter.get_object_path() - arg = 'object_path:%s\n' % (path) - elif type == TYPE_INT32: - num = iter.get_int32() - arg = 'int32:%d\n' % (num) - elif type == TYPE_UINT32: - num = iter.get_uint32() - arg = 'uint32:%u\n' % (num) - elif type == TYPE_INT64: - num = iter.get_int64() - arg = 'int64:%d\n' % (num) - elif type == TYPE_UINT64: - num = iter.get_uint64() - arg = 'uint64:%u\n' % (num) - elif type == TYPE_DOUBLE: - num = iter.get_double() - arg = 'double:%f\n' % (num) - elif type == TYPE_BYTE: - num = iter.get_byte() - arg = 'byte:%x(%s)\n' % (num, str(chr(num))) - elif type == TYPE_BOOLEAN: - bool = iter.get_boolean() - if (bool): - str = "true" - else: - str = "false" - arg = 'boolean:%s\n' % (str) - elif type == TYPE_ARRAY: - dbus_message_iter_recurse(self.iter, <DBusMessageIter *>&c_array_iter) - array_iter = MessageIter(self.level + 1) - array_iter.__cinit__(&c_array_iter) - if array_iter.has_next(): - arg = 'array [' + str(array_iter) + ']' - else: - arg = 'array []' - else: - arg = '(unknown arg type %d)\n' % type - - retval = retval + arg - value_at_iter = self.next() - - return retval - + value = <unsigned char*>malloc(length * sizeof(unsigned char)) + for i from 0 <= i < length: + item = python_list[i] + if type(item) != str or len(item) != 1: + raise TypeError + value[i] = ord(item) + return dbus_message_iter_append_byte_array(self.iter, value, length) + + def append_int32_array(self, python_list): + cdef dbus_int32_t *value + cdef int length + cdef int i + length = len(python_list) + value = <dbus_int32_t*>malloc(length * sizeof(dbus_int32_t)) + for i from 0 <= i < length: + item = python_list[i] + if type(item) != int: + raise TypeError + value[i] = item + return dbus_message_iter_append_int32_array(self.iter, value, length) + + def append_int64_array(self, python_list): + cdef dbus_int64_t *value + cdef int length + cdef int i + length = len(python_list) + value = <dbus_int64_t*>malloc(length * sizeof(dbus_int64_t)) + for i from 0 <= i < length: + item = python_list[i] + if type(item) != int: + raise TypeError + value[i] = item + return dbus_message_iter_append_int64_array(self.iter, value, length) + + def append_double_array(self, python_list): + cdef double *value + cdef int length + cdef int i + length = len(python_list) + value = <double*>malloc(length * sizeof(double)) + for i from 0 <= i < length: + item = python_list[i] + if type(item) != float: + raise TypeError + value[i] = item + return dbus_message_iter_append_double_array(self.iter, value, length) + + def append_object_path_array(self, list): + cdef char **value + cdef int length + cdef int i + length = len(list) + value = <char**>malloc(length * sizeof(char *)) + for i from 0 <= i < length: + item = list[i] + if not isinstance(item, ObjectPath): + raise TypeError + value[i] = item + + return dbus_message_iter_append_object_path_array(self.iter, value, length) + + def append_string_array(self, python_list): + cdef char **value + cdef int length + cdef dbus_bool_t return_code + cdef int i + length = len(python_list) + value = <char**>malloc(length * sizeof(char *)) + for i from 0 <= i < length: + item = python_list[i] + if type(item) != str: + raise TypeError + value[i] = item + return dbus_message_iter_append_string_array(self.iter, value, length) (MESSAGE_TYPE_INVALID, MESSAGE_TYPE_METHOD_CALL, MESSAGE_TYPE_METHOD_RETURN, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_SIGNAL) = range(5) -(TYPE_INVALID, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT16, TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_OBJECT_PATH, TYPE_SIGNATURE, TYPE_ARRAY, TYPE_STRUCT, STRUCT_BEGIN, STRUCT_END, TYPE_VARIANT, TYPE_DICT_ENTRY, DICT_ENTRY_BEGIN, DICT_ENTRY_END) = (0, ord('y'), ord('b'), ord('n'), ord('i'), ord('u'), ord('q'), ord('x'), ord('t'), ord('d'), ord('s'), ord('o'), ord('g'), ord('a'), ord('r'), ord('('), ord(')'), ord('v'), ord('e'), ord('{'), ord('}')) +(TYPE_INVALID, TYPE_NIL, TYPE_BYTE, TYPE_BOOLEAN, TYPE_INT32, TYPE_UINT32, TYPE_INT64, TYPE_UINT64, TYPE_DOUBLE, TYPE_STRING, TYPE_CUSTOM, TYPE_ARRAY, TYPE_DICT, TYPE_OBJECT_PATH) = (0, ord('v'), ord('y'), ord('b'), ord('i'), ord('u'), ord('x'), ord('t'), ord('d'), ord('s'), ord('c'), ord('a'), ord('m'), ord('o')) (HANDLER_RESULT_HANDLED, HANDLER_RESULT_NOT_YET_HANDLED, HANDLER_RESULT_NEED_MEMORY) = range(3) cdef class Message: @@ -952,7 +865,7 @@ cdef class Message: return "error" else: return "(unknown message type)" - + def __str__(self): message_type = self.get_type() sender = self.get_sender() @@ -979,8 +892,51 @@ cdef class Message: # FIXME: should really use self.convert_to_tuple() here iter = self.get_iter() + value_at_iter = True + + while (value_at_iter): + type = iter.get_arg_type() + + if type == TYPE_INVALID: + break + elif type == TYPE_NIL: + arg = 'nil:None\n' + elif type == TYPE_STRING: + str = iter.get_string() + arg = 'string:%s\n' % (str) + elif type == TYPE_OBJECT_PATH: + path = iter.get_object_path() + arg = 'object_path:%s\n' % (path) + elif type == TYPE_INT32: + num = iter.get_int32() + arg = 'int32:%d\n' % (num) + elif type == TYPE_UINT32: + num = iter.get_uint32() + arg = 'uint32:%u\n' % (num) + elif type == TYPE_INT64: + num = iter.get_int64() + arg = 'int64:%d\n' % (num) + elif type == TYPE_UINT64: + num = iter.get_uint64() + arg = 'uint64:%u\n' % (num) + elif type == TYPE_DOUBLE: + num = iter.get_double() + arg = 'double:%f\n' % (num) + elif type == TYPE_BYTE: + num = iter.get_byte() + arg = 'byte:%d\n' % (num) + elif type == TYPE_BOOLEAN: + bool = iter.get_boolean() + if (bool): + str = "true" + else: + str = "false" + arg = 'boolean:%s\n' % (str) + else: + arg = '(unknown arg type %d)\n' % type - retval = retval + "\n" + str(iter) + retval = retval + arg + value_at_iter = iter.next() return retval @@ -990,19 +946,15 @@ cdef class Message: cdef DBusMessage *_get_msg(self): return self.msg - def get_iter(self, append=False): + def get_iter(self): cdef DBusMessageIter iter cdef MessageIter message_iter cdef DBusMessage *msg msg = self._get_msg() + dbus_message_iter_init(msg, &iter) - if append: - dbus_message_iter_init_append(msg, &iter) - else: - dbus_message_iter_init(msg, &iter) - - message_iter = MessageIter(0) + message_iter = MessageIter() message_iter.__cinit__(&iter) return message_iter @@ -1157,7 +1109,7 @@ cdef class Server: BUS_SESSION = DBUS_BUS_SESSION BUS_SYSTEM = DBUS_BUS_SYSTEM -BUS_STARTER = DBUS_BUS_STARTER +BUS_ACTIVATION = DBUS_BUS_ACTIVATION def bus_get (bus_type): cdef DBusError error @@ -1175,10 +1127,10 @@ def bus_get (bus_type): conn.__cinit__(None, connection) return conn -def bus_get_unique_name(Connection connection): +def bus_get_base_service(Connection connection): cdef DBusConnection *conn conn = connection._get_conn() - return dbus_bus_get_unique_name(conn) + return dbus_bus_get_base_service(conn) def bus_get_unix_user(Connection connection, service_name): cdef DBusError error @@ -1194,10 +1146,10 @@ def bus_get_unix_user(Connection connection, service_name): return retval #These are defines, not enums so they aren't auto generated -DBUS_START_REPLY_SUCCESS = 0 -DBUS_START_REPLY_ALREADY_RUNNING = 1 +ACTIVATION_REPLY_ACTIVATED = 0 +ACTIVATION_REPLY_ALREADY_ACTIVE = 1 -def bus_start_service_by_name(Connection connection, service_name, flags=0): +def bus_activate_service(Connection connection, service_name, flags=0): cdef DBusError error dbus_error_init(&error) cdef dbus_bool_t retval @@ -1206,7 +1158,7 @@ def bus_start_service_by_name(Connection connection, service_name, flags=0): conn = connection._get_conn() - retval = dbus_bus_start_service_by_name(conn, service_name, flags, &results, &error) + retval = dbus_bus_activate_service(conn, service_name, flags, &results, &error) return (retval, results) @@ -1227,29 +1179,29 @@ def bus_register(Connection connection): SERVICE_FLAG_PROHIBIT_REPLACEMENT = 0x1 SERVICE_FLAG_REPLACE_EXISTING = 0x2 -def bus_request_name(Connection connection, service_name, flags=0): +def bus_acquire_service(Connection connection, service_name, flags=0): cdef DBusError error dbus_error_init(&error) cdef int retval cdef DBusConnection *conn conn = connection._get_conn() - retval = dbus_bus_request_name(conn, - service_name, - flags, - &error) + retval = dbus_bus_acquire_service(conn, + service_name, + flags, + &error) if dbus_error_is_set(&error): raise DBusException, error.message return retval -def bus_name_has_owner(Connection connection, service_name): +def bus_service_exists(Connection connection, service_name): cdef DBusError error dbus_error_init(&error) cdef dbus_bool_t retval cdef DBusConnection *conn conn = connection._get_conn() - retval = dbus_bus_name_has_owner(conn, + retval = dbus_bus_service_exists(conn, service_name, &error) if dbus_error_is_set(&error): |