diff options
| -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): | 
