dbus/dbus dbus-object-tree.c,1.1,1.2 dbus-object-tree.h,1.1,1.2 dbus-pending-call.c,1.1,1.2 dbus-pending-call.h,1.1,1.2 Makefile.am,1.56,1.57 dbus-address.c,1.10,1.11 dbus-auth.c,1.28,1.29 dbus-bus.c,1.24,1.25 dbus-bus.h,1.7,1.8 dbus-connection-internal.h,1.12,1.13 dbus-connection.c,1.69,1.70 dbus-connection.h,1.24,1.25 dbus-dataslot.h,1.3,1.4 dbus-errors.c,1.21,1.22 dbus-errors.h,1.19,1.20 dbus-hash.c,1.14,1.15 dbus-hash.h,1.9,1.10 dbus-internals.c,1.30,1.31 dbus-internals.h,1.36,1.37 dbus-keyring.c,1.18,1.19 dbus-mainloop.c,1.12,1.13 dbus-mainloop.h,1.3,1.4 dbus-marshal.c,1.41,1.42 dbus-marshal.h,1.17,1.18 dbus-md5.h,1.1,1.2 dbus-message-builder.c,1.18,1.19 dbus-message.c,1.103,1.104 dbus-message.h,1.42,1.43 dbus-protocol.h,1.20,1.21 dbus-server-debug-pipe.c,1.12,1.13 dbus-server-protected.h,1.10,1.11 dbus-server-unix.c,1.18,1.19 dbus-server.c,1.29,1.30 dbus-sha.h,1.1,1.2 dbus-spawn.c,1.12,1.13 dbus-string.c,1.41,1.42 dbus-string.h,1.20,1.21 dbus-sysdeps.c,1.64,1.65 dbus-sysdeps.h,1.35,1.36 dbus-test.c,1.30,1.31 dbus-test.h,1.22,1.23 dbus-threads.c,1.17,1.18 dbus-threads.h,1.3,1.4 dbus-timeout.c,1.10,1.11 dbus-transport-protected.h,1.9,1.10 dbus-transport.c,1.33,1.34 dbus-types.h,1.7,1.8 dbus-userdb.c,1.4,1.5 dbus-watch.c,1.13,1.14 dbus.h,1.15,1.16
Havoc Pennington
hp@pdx.freedesktop.org
Mon, 29 Sep 2003 19:33:26 -0700
- Previous message: dbus/bus signals.c,1.1,1.2 signals.h,1.1,1.2 Makefile.am,1.27,1.28 activation.c,1.27,1.28 bus.c,1.38,1.39 bus.h,1.18,1.19 config-parser.c,1.21,1.22 connection.c,1.43,1.44 connection.h,1.15,1.16 dbus-daemon-1.1.in,1.3,1.4 desktop-file.c,1.7,1.8 dispatch.c,1.50,1.51 dispatch.h,1.3,1.4 driver.c,1.41,1.42 policy.c,1.13,1.14 policy.h,1.9,1.10 services.c,1.15,1.16 session.conf.in,1.5,1.6 system.conf.in,1.10,1.11 test-main.c,1.12,1.13 test.c,1.21,1.22 test.h,1.10,1.11
- Next message: dbus/doc TODO,1.23,1.24 dbus-specification.sgml,1.40,1.41
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/dbus/dbus/dbus
In directory pdx:/tmp/cvs-serv18265/dbus
Modified Files:
Makefile.am dbus-address.c dbus-auth.c dbus-bus.c dbus-bus.h
dbus-connection-internal.h dbus-connection.c dbus-connection.h
dbus-dataslot.h dbus-errors.c dbus-errors.h dbus-hash.c
dbus-hash.h dbus-internals.c dbus-internals.h dbus-keyring.c
dbus-mainloop.c dbus-mainloop.h dbus-marshal.c dbus-marshal.h
dbus-md5.h dbus-message-builder.c dbus-message.c
dbus-message.h dbus-protocol.h dbus-server-debug-pipe.c
dbus-server-protected.h dbus-server-unix.c dbus-server.c
dbus-sha.h dbus-spawn.c dbus-string.c dbus-string.h
dbus-sysdeps.c dbus-sysdeps.h dbus-test.c dbus-test.h
dbus-threads.c dbus-threads.h dbus-timeout.c
dbus-transport-protected.h dbus-transport.c dbus-types.h
dbus-userdb.c dbus-watch.c dbus.h
Added Files:
dbus-object-tree.c dbus-object-tree.h dbus-pending-call.c
dbus-pending-call.h
Log Message:
2003-09-29 Havoc Pennington <hp@pobox.com>
* Merge dbus-object-names branch. To see the entire patch
do cvs diff -r DBUS_OBJECT_NAMES_BRANCHPOINT -r dbus-object-names,
it's huuuuge though.
To revert, I tagged DBUS_BEFORE_OBJECT_NAMES_MERGE.
2003-09-28 Havoc Pennington <hp@pobox.com>
* HACKING: update to reflect new server
2003-09-26 Seth Nickell <seth@gnome.org>
* python/dbus.py:
* python/examples/example-signals.py:
Start implementing some notions of signals. The API
is really terrible, but they sort of work (with the
exception of being able to filter by service, and to
transmit signals *as* a particular service). Need to
figure out how to make messages come from the service
we registered :-(
* python/dbus_bindings.pyx.in:
Removed duplicate message_handler callbacks.
2003-09-25 Havoc Pennington <hp@redhat.com>
* bus/session.conf.in: fix my mess
2003-09-25 Havoc Pennington <hp@pobox.com>
* bus/session.conf.in: fix security policy, reported by Seth Nickell
2003-09-25 Seth Nickell <seth@gnome.org>
* python/examples/example-service.py:
Johan notices complete wrong code in example-service, but
completely wrong in a way that works exactly the same (!).
Johan is confused, how could this possibly work? Example
code fails to serve purpose of making things clear.
Seth fixes.
2003-09-25 Mark McLoughlin <mark@skynet.ie>
* doc/dbus-specification.sgml: don't require header fields
to be 4-byte aligned and specify that fields should be
distinguished from padding by the fact that zero is not
a valid field name.
* doc/TODO: remove re-alignment item and add item to doc
the OBJECT_PATH type.
* dbus/dbus-message.c:
(HeaderField): rename the original member to value_offset
and introduce a name_offset member to keep track of where
the field actually begins.
(adjust_field_offsets): remove.
(append_int_field), (append_uint_field),
(append_string_field): don't align the start of the header
field to a 4-byte boundary.
(get_next_field): impl finding the next marhsalled field
after a given field.
(re_align_field_recurse): impl re-aligning a number of
already marshalled fields.
(delete_field): impl deleting a field of any type and
re-aligning any following fields.
(delete_int_or_uint_field), (delete_string_field): remove.
(set_int_field), (set_uint_field): no need to re-check
that we have the correct type for the field.
(set_string_field): ditto and impl re-aligning any
following fields.
(decode_header_data): update to take into account that
the fields aren't 4-byte aligned any more and the new
way to distinguish padding from header fields. Also,
don't exit when there is too much header padding.
(process_test_subdir): print the directory.
(_dbus_message_test): add test to make sure a following
field is re-aligned correctly after field deletion.
* dbus/dbus-string.[ch]:
(_dbus_string_insert_bytes): rename from insert_byte and
allow the insert of multiple bytes.
(_dbus_string_test): test inserting multiple bytes.
* dbus/dbus-marshal.c: (_dbus_marshal_set_string): add
warning note to docs about having to re-align any
marshalled values following the string.
* dbus/dbus-message-builder.c:
(append_string_field), (_dbus_message_data_load):
don't align the header field.
* dbus/dbus-auth.c: (process_test_subdir): print the
directory.
* test/break-loader.c: (randomly_add_one_byte): upd. for
insert_byte change.
* test/data/invalid-messages/bad-header-field-alignment.message:
new test case.
* test/data/valid-messages/unknown-header-field.message: shove
a dict in the unknown field.
2003-09-25 Seth Nickell <seth@gnome.org>
* python/dbus.py:
* python/dbus_bindings.pyx.in:
Handle return values.
* python/examples/example-client.py:
* python/examples/example-service.py:
Pass back return values from the service to the client.
2003-09-24 Seth Nickell <seth@gnome.org>
* python/dbus.py:
Connect Object methods (when you are sharing an object) up... pass
in a list of methods to be shared. Sharing all the methods just
worked out too weird. You can now create nice Services over the
DBus in Python. :-)
* python/dbus_bindings.pyx.in:
Keep references to user_data tuples passed into C functions so
Python doesn't garbage collect on us.
Implement MethodReturn and Error subclasses of Message for creating
DBusMessage's of those types.
* python/examples/example-client.py:
* python/examples/example-service.py:
Simple example code showing both how create DBus services and objects,
and how to use them.
2003-09-23 Havoc Pennington <hp@pobox.com>
* glib/dbus-gproxy.c (dbus_gproxy_manager_filter): implement
2003-09-23 Havoc Pennington <hp@redhat.com>
* glib/dbus-gproxy.c (dbus_gproxy_connect_signal): implement
(dbus_gproxy_disconnect_signal): implement
(dbus_gproxy_manager_remove_signal_match): implement
(dbus_gproxy_manager_add_signal_match): implement
(dbus_gproxy_oneway_call): implement
2003-09-23 Havoc Pennington <hp@pobox.com>
* glib/dbus-gproxy.c (struct DBusGProxy): convert to a GObject
subclass. This means dropping the transparent thread safety of the
proxy; you now need a separate proxy per-thread, or your own
locking on the proxy. Probably right anyway.
(dbus_gproxy_ref, dbus_gproxy_unref): nuke, just use g_object_ref
2003-09-22 Havoc Pennington <hp@redhat.com>
* glib/dbus-gproxy.c (dbus_gproxy_manager_get): implement
2003-09-21 Seth Nickell <seth@gnome.org>
First checkin of the Python bindings.
* python/.cvsignore:
* python/Makefile.am:
* python/dbus_bindings.pyx.in:
* python/dbus_h_wrapper.h:
Pieces for Pyrex to operate on, building a dbus_bindings.so
python module for low-level access to the DBus APIs.
* python/dbus.py:
High-level Python module for accessing DBus objects.
* configure.in:
* Makefile.am:
Build stuff for the python bindings.
* acinclude.m4:
Extra macro needed for finding the Python C header files.
2003-09-21 Havoc Pennington <hp@pobox.com>
* glib/dbus-gproxy.c (dbus_gproxy_manager_new): start
implementing the proxy manager, didn't get very far.
* dbus/dbus-bus.c (dbus_bus_add_match): new
(dbus_bus_remove_match): new
* glib/dbus-gproxy.c (dbus_gproxy_new_for_service): add a
path_name argument; adjust the other not-yet-implemented
gproxy constructors to be what I think they should be.
2003-09-21 Havoc Pennington <hp@pobox.com>
* dbus/dbus-bus.c (dbus_bus_get): set exit_on_disconnect to TRUE
by default for message bus connections.
* dbus/dbus-connection.c (dbus_connection_dispatch): exit if
exit_on_disconnect flag is set and we process the disconnected
signal.
(dbus_connection_set_exit_on_disconnect): new function
2003-09-21 Havoc Pennington <hp@pobox.com>
Get matching rules mostly working in the bus; only actually
parsing the rule text remains. However, the client side of
"signal connections" hasn't been started, this patch is only the
bus side.
* dbus/dispatch.c: fix for the matching rules changes
* bus/driver.c (bus_driver_handle_remove_match)
(bus_driver_handle_add_match): send an ack reply from these
method calls
* glib/dbus-gproxy.c (dbus_gproxy_begin_call): fix order of
arguments, reported by Seth Nickell
* bus/config-parser.c (append_rule_from_element): support
eavesdrop=true|false attribute on policies so match rules
can be prevented from snooping on the system bus.
* bus/dbus-daemon-1.1.in: consistently use terminology "sender"
and "destination" in attribute names; fix some docs bugs;
add eavesdrop=true|false attribute
* bus/driver.c (bus_driver_handle_add_match)
(bus_driver_handle_remove_match): handle AddMatch, RemoveMatch
messages
* dbus/dbus-protocol.h (DBUS_SERVICE_ORG_FREEDESKTOP_BROADCAST): get
rid of broadcast service concept, signals are just always broadcast
* bus/signals.c, bus/dispatch.c, bus/connection.c, bus/bus.c:
mostly implement matching rules stuff (currently only exposed as signal
connections)
2003-09-21 Mark McLoughlin <mark@skynet.ie>
* doc/dbus-specification.sgml: Change the header field name
to be an enum and update the rest of the spec to reference
the fields using the conventinal name.
* dbus/dbus-protocol.h: update to reflect the spec.
* doc/TODO: add item to remove the 4 byte alignment requirement.
* dbus/dbus-message.c: Remove the code to generalise the
header/body length and serial number header fields as named
header fields so we can reference field names using the
protocol values.
(append_int_field), (append_uint_field), (append_string_field):
Append the field name as a byte rather than four chars.
(delete_int_or_uint_field), (delete_string_field): reflect the
fact that the field name and typecode now occupy 4 bytes instead
of 8.
(decode_string_field), (decode_header_data): update to reflect
protocol changes and move the field specific encoding from
decode_string_field() back into decode_header_data().
* dbus/dbus-internals.[ch]: (_dbus_header_field_to_string):
Add utility to aid debugging.
* dbus/dbus-message-builder.c:
(append_string_field), (_dbus_message_data_load): Update to
reflect protocol changes; Change the FIELD_NAME directive
to HEADER_FIELD and allow it to take the field's conventional
name rather than the actual value.
* test/data/*/*.message: Update to use HEADER_FIELD instead
of FIELD_NAME; Always align the header on an 8 byte boundary
*before* updating the header length.
2003-09-15 Havoc Pennington <hp@pobox.com>
* dbus/dbus-pending-call.c: add the get/set object data
boilerplate as for DBusConnection, etc. Use generic object data
for the notify callback.
* glib/dbus-gparser.c (parse_node): parse child nodes
* tools/dbus-viewer.c: more hacking on the dbus-viewer
* glib/dbus-gutils.c (_dbus_gutils_split_path): add a file to
contain functions shared between the convenience lib and the
installed lib
* glib/Makefile.am (libdbus_glib_1_la_LDFLAGS): add
-export-symbols-regex to the GLib library
* dbus/dbus-object-tree.c (_dbus_object_tree_dispatch_and_unlock):
fix the locking in here, and add a default handler for
Introspect() that just returns sub-nodes.
2003-09-14 Havoc Pennington <hp@pobox.com>
* glib/dbus-gthread.c (dbus_g_thread_init): rename to make g_foo
rather than gfoo consistent
* glib/dbus-gproxy.h: delete for now, move contents to
dbus-glib.h, because the include files don't work right since we
aren't in the dbus/ subdir.
* glib/dbus-gproxy.c (dbus_gproxy_send): finish implementing
(dbus_gproxy_end_call): finish
(dbus_gproxy_begin_call): finish
* glib/dbus-gmain.c (dbus_set_g_error): new
* glib/dbus-gobject.c (handle_introspect): include information
about child nodes in the introspection
* dbus/dbus-connection.c (dbus_connection_list_registered): new
function to help in implementation of introspection
* dbus/dbus-object-tree.c
(_dbus_object_tree_list_registered_and_unlock): new function
2003-09-12 Havoc Pennington <hp@pobox.com>
* glib/dbus-gidl.h: add common base class for all the foo_info
types
* tools/dbus-viewer.c: add GTK-based introspection UI thingy
similar to kdcop
* test/Makefile.am: try test srcdir -ef . in addition to test
srcdir = ., one of them should work (yeah lame)
* glib/Makefile.am: build the "idl" parser stuff as a convenience
library
* glib/dbus-gparser.h: make description_load routines return
NodeInfo* not Parser*
* Makefile.am (SUBDIRS): build test dir after all library dirs
* configure.in: add GTK+ detection
2003-09-07 Havoc Pennington <hp@pobox.com>
* Make Doxygen contented.
2003-09-07 Havoc Pennington <hp@pobox.com>
* doc/dbus-specification.sgml: more updates
2003-09-06 Havoc Pennington <hp@pobox.com>
* doc/dbus-specification.sgml: partial updates
* bus/dbus-daemon-1.1.in: fix the config file docs for the
zillionth time; hopefully I edited the right file this time.
* bus/config-parser.c (append_rule_from_element): support
send_type, send_path, receive_type, receive_path
* bus/policy.c: add message type and path to the list of things
that can be "firewalled"
2003-09-06 Havoc Pennington <hp@pobox.com>
* dbus/dbus-connection.c (dbus_connection_register_fallback): add this
(dbus_connection_register_object_path): make this not handle
messages to paths below the given path
2003-09-03 Havoc Pennington <hp@pobox.com>
* test/glib/Makefile.am: add this with random glib-linked test
programs
* glib/Makefile.am: remove the random test programs from here,
leave only the unit tests
* glib/dbus-gobject.c (_dbus_gobject_test): add test for
uscore/javacaps conversion, and fix
(get_object_property, set_object_property): change to .NET
convention for mapping props to methods, set_FooBar/get_FooBar,
since one language has such a convention we may as well copy it.
Plus real methods in either getFooBar or get_foo_bar style won't
collide with this convention.
2003-09-01 Havoc Pennington <hp@pobox.com>
* glib/dbus-gparser.c: implement
* glib/dbus-gobject.c: start implementing skeletons support
* configure.in: when disabling checks/assert, also define
G_DISABLE_ASSERT and G_DISABLE_CHECKS
2003-09-01 Havoc Pennington <hp@pobox.com>
* glib/Makefile.am: rearrange a bunch of files and get "make
check" framework set up
2003-08-31 Havoc Pennington <hp@pobox.com>
* fix build with --disable-tests
2003-08-30 Havoc Pennington <hp@pobox.com>
* dbus/dbus-connection.c: purge DBusMessageHandler
* dbus/dbus-message-handler.c: remove DBusMessageHandler, just
use callbacks everywhere
2003-08-30 Havoc Pennington <hp@pobox.com>
* test/data/valid-config-files/system.d/test.conf: change to
root for the user so warnings don't get printed
* dbus/dbus-message.c: add dbus_message_get_path,
dbus_message_set_path
* dbus/dbus-object-tree.c (do_test_dispatch): add test of
dispatching to a path
* dbus/dbus-string.c (_dbus_string_validate_path): add
* dbus/dbus-marshal.c (_dbus_demarshal_object_path): implement
(_dbus_marshal_object_path): implement
* dbus/dbus-protocol.h (DBUS_HEADER_FIELD_PATH): new header field
to contain the path to the target object
(DBUS_HEADER_FIELD_SENDER_SERVICE): rename
DBUS_HEADER_FIELD_SENDER to explicitly say it's the sender service
2003-08-30 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-tree.c: write tests and fix the discovered bugs
2003-08-29 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-tree.c: modify to allow overlapping paths to be
registered
(struct DBusObjectSubtree): shrink this
a lot, since we may have a lot of them
(_dbus_object_tree_free_all_unlocked): implement
(_dbus_object_tree_dispatch_and_unlock): implement
2003-08-29 Havoc Pennington <hp@pobox.com>
* dbus/dbus-internals.h: fix _DBUS_N_GLOBAL_LOCKS
2003-08-28 Havoc Pennington <hp@pobox.com>
purge DBusObjectID
* dbus/dbus-connection.c: port to no ObjectID, create a
DBusObjectTree, rename ObjectTree to ObjectPath in public API
* dbus/dbus-connection.h (struct DBusObjectTreeVTable): delete
everything except UnregisterFunction and MessageFunction
* dbus/dbus-marshal.c: port away from DBusObjectID,
add DBUS_TYPE_OBJECT_PATH
* dbus/dbus-object-registry.[hc], dbus/dbus-object.[hc],
dbus/dbus-objectid.[hc]: remove these, we are moving to
path-based object IDs
2003-08-25 Havoc Pennington <hp@pobox.com>
Just noticed that dbus_message_test is hosed, I wonder when I
broke that. I thought make check was passing earlier...
* dbus/dbus-object-tree.c: add new "object tree" to match DCOP
container tree, will replace most of dbus-object-registry
* dbus/dbus-string.c (_dbus_string_append_printf_valist): fix C99
screwup
2003-08-19 Havoc Pennington <hp@pobox.com>
* dbus/dbus-message.c (decode_string_field): support FIELD_SENDER
(dbus_message_is_error): fix this function
* bus/dbus-daemon-1.1: clarify logic on when <deny>/<allow> rules
match
* bus/policy.c (bus_client_policy_check_can_receive): fix code to
reflect clarified man page
(bus_client_policy_check_can_send): ditto
* bus/session.conf.in: fixup
* bus/system.conf.in: fixup
2003-08-18 Havoc Pennington <hp@redhat.com>
* dbus/dbus-hash.c (_dbus_hash_table_insert_two_strings): fix
* dbus/dbus-message.c (_dbus_message_loader_queue_messages): fix
dumb bug created earlier (wrong order of args to
decode_header_data())
* tools/dbus-send.c: port
* tools/dbus-print-message.c (print_message): port
* test/data/*messages: port all messages over
* dbus/dbus-message-builder.c: support including
message type
* bus/driver.c: port over
* bus/dispatch.c: port over to new stuff
* dbus/dbus-connection.c (_dbus_connection_new_for_transport):
rename disconnect signal to "Disconnected"
2003-08-17 Havoc Pennington <hp@pobox.com>
This doesn't compile yet, but syncing up so I can hack on it from
work. What are branches for if not broken code? ;-)
* dbus/dbus-protocol.h: remove DBUS_HEADER_FIELD_NAME, add
DBUS_HEADER_FIELD_INTERFACE, DBUS_HEADER_FIELD_MEMBER,
DBUS_HEADER_FIELD_ERROR_NAME
* dbus/dbus-hash.c: Introduce DBUS_HASH_TWO_STRINGS as hack to use
for the interface+member pairs
(string_hash): change to use g_str_hash algorithm
(find_direct_function, find_string_function): refactor these to
share most code.
* dbus/dbus-message.c: port all of this over to support
interface/member fields instead of name field
* dbus/dbus-object-registry.c: port over
* dbus/dbus-string.c (_dbus_string_validate_interface): rename
from _dbus_string_validate_name
* bus/dbus-daemon-1.1: change file format for the
<deny>/<allow> stuff to match new message naming scheme
* bus/policy.c: port over
* bus/config-parser.c: parse new format
2003-08-16 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-registry.c (add_and_remove_objects): remove
broken assertion
* glib/dbus-gproxy.c: some hacking
2003-08-15 Havoc Pennington <hp@redhat.com>
* dbus/dbus-pending-call.c (dbus_pending_call_block): implement
* dbus/dbus-connection.c
(dbus_connection_send_with_reply_and_block): factor out internals;
change to convert any error replies to DBusError instead of
returning them as a message
2003-08-15 Havoc Pennington <hp@pobox.com>
* dbus/dbus-connection.c,
dbus/dbus-pending-call.c: Finish the pending call stuff
2003-08-14 Havoc Pennington <hp@redhat.com>
* dbus/dbus-pending-call.c: start on new object that will replace
DBusMessageHandler and ReplyHandlerData for tracking outstanding
replies
* dbus/dbus-gproxy.c: start on proxy object used to communicate
with remote interfaces
* dbus/dbus-gidl.c: do the boring boilerplate in here
2003-08-12 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch): make this return proper
DBusHandlerResult to avoid DBUS_ERROR_UNKNOWN_METHOD
* dbus/dbus-errors.c (dbus_set_error): use
_dbus_string_append_printf_valist
* dbus/dbus-string.c (_dbus_string_append_printf_valist)
(_dbus_string_append_printf): new
* dbus/dbus-errors.h (DBUS_ERROR_UNKNOWN_MESSAGE): change to
UNKNOWN_METHOD
* dbus/dbus-connection.c (dbus_connection_dispatch): handle
DBUS_HANDLER_RESULT_NEED_MEMORY; send default error reply if a
message is unhandled.
2003-08-11 Havoc Pennington <hp@pobox.com>
* bus/test.c (client_disconnect_handler): change to return
HANDLED (would have been REMOVE_MESSAGE)
* dbus/dbus-object.h (enum DBusHandlerResult): rename to
HANDLED/NOT_YET_HANDLED instead of
REMOVE_MESSAGE/ALLOW_MORE_HANDLERS to make it clearer how it
should be used.
2003-08-10 Havoc Pennington <hp@pobox.com>
* tools/dbus-send.c (main): add --type argument, for now
supporting only method_call and signal types.
* tools/dbus-print-message.c: print message type
* dbus/dbus-connection.c (_dbus_connection_new_for_transport):
init connection->objects
* doc/dbus-specification.sgml: fix sgml
* bus/*.c: port over to object-instance API changes
* test/test-service.c: ditto
* dbus/dbus-message.c (dbus_message_create_header): allow #NULL
name, we will have to fix up the rest of the code to also handle
this
(dbus_message_new): generic message-creation call
(set_string_field): allow appending name field
2003-08-06 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-registry.c: implement signal connection
and dispatch
* dbus/dbus-connection.c (_dbus_connection_unref_unlocked): new
* dbus/dbus-internals.c (_dbus_memdup): new function
2003-08-02 Havoc Pennington <hp@pobox.com>
* dbus/dbus-message.c (dbus_message_get_no_reply)
(dbus_message_set_no_reply): add these and remove
set_is_error/get_is_error
* dbus/dbus-protocol.h, doc/dbus-specification.sgml:
remove the ERROR flag, since there's now an ERROR type
2003-08-01 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-registry.c (_dbus_object_registry_handle_and_unlock):
implement
* dbus/dbus-message.c (dbus_message_get_type): new function
* doc/dbus-specification.sgml: add "type" byte to messages
2003-08-01 Havoc Pennington <hp@pobox.com>
* dbus/dbus-protocol.h (DBUS_MESSAGE_TYPE_*): introduce
a message type enum to distinguish kinds of message
(DBUS_HEADER_FLAG_NO_REPLY_EXPECTED): flag for a message
that need not be replied to
2003-08-01 Havoc Pennington <hp@pobox.com>
* dbus/dbus-marshal.c: adapt to DBusObjectID changes
(unpack_8_octets): fix no-64-bit-int bug
* dbus/dbus-object-registry.c (validate_id): validate the
connection ID bits, not just the instance ID.
* dbus/dbus-connection.c (_dbus_connection_init_id): initialize
the connection-global 33 bits of the object ID
* dbus/dbus-object-registry.c (info_from_entry): fill in
object ID in the new way
* dbus/dbus-objectid.h: rather than high/low bits, specifically
define server/client/instance bits.
2003-07-30 Havoc Pennington <hp@pobox.com>
* dbus/dbus-connection.c (dbus_connection_register_object): fix
build
2003-07-13 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object.h (struct DBusObjectVTable): add padding
fields to DBusObjectVTable and DBusObjectInfo
2003-07-12 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object-registry.c: implement unit test,
fix bugs discovered in process
* dbus/dbus-connection.c: remove handler_table and
register_handler(), add DBusObjectRegistry usage
* dbus/dbus-objectid.c (dbus_object_id_is_null)
(dbus_object_id_set_null): new functions
2003-07-08 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object.c: implement some of this
* dbus/dbus-object-registry.c
(_dbus_object_registry_add_and_unlock): fill in the object_id out
param
(_dbus_object_registry_new): handle OOM
2003-07-08 Havoc Pennington <hp@pobox.com>
* dbus/dbus-object.h: sketch out an API for registering objects
with a connection, that allows us to use as little as 24 bytes
per object and lets application code represent an object in
any conceivable way.
* dbus/dbus-object-registry.c: implement the hard bits of the
DBusConnection aspect of object API. Not yet wired up.
2003-07-06 Havoc Pennington <hp@pobox.com>
* dbus/dbus-marshal.c (_dbus_marshal_set_object_id): new function
(_dbus_marshal_object_id): new
(_dbus_demarshal_object_id): new
(_dbus_marshal_get_arg_end_pos): support object ID type, and
consolidate identical switch cases. Don't conditionalize handling
of DBUS_TYPE_UINT64, need to handle the type always.
(_dbus_marshal_validate_arg): consolidate identical cases, and
handle DBUS_TYPE_OBJECT_ID
* dbus/dbus-objectid.c: new file with DBusObjectID data type.
* dbus/dbus-protocol.h: add DBUS_TYPE_OBJECT_ID
2003-09-28 Havoc Pennington <hp@pobox.com>
* real 0.13 release
2003-09-28 Havoc Pennington <hp@pobox.com>
* doc/Makefile.am (dbus-specification.html): testing a funky hack
to work with Debian db2html
2003-09-28 Havoc Pennington <hp@pobox.com>
* configure.in: 0.13
* doc/Makefile.am (dbus-test-plan.html): accept nonexistence of
stylesheet-images for benefit of Debian
Change back to using filesystem-linked sockets for the system
bus, so only root can create the default system bus address.
* bus/system.conf.in: change to use
DBUS_SYSTEM_BUS_DEFAULT_ADDRESS
* dbus/Makefile.am (INCLUDES): remove DBUS_SYSTEM_BUS_PATH define
from here.
* configure.in: define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS
here, and AC_DEFINE DBUS_SYSTEM_PATH
2003-08-09 Anders Carlsson <andersca@codefactory.se>
* doc/TODO:
* doc/busconfig.dtd:
Add busconfig DTD.
2003-08-09 Anders Carlsson <andersca@codefactory.se>
* doc/dbus-specification.sgml:
Add activation reply values.
2003-08-05 Havoc Pennington <hp@redhat.com>
* configure.in: 0.12
2003-08-05 Anders Carlsson <andersca@codefactory.se>
* glib/dbus-gmain.c: (watch_fd_new), (watch_fd_ref),
(watch_fd_unref), (dbus_gsource_check), (dbus_gsource_dispatch),
(add_watch), (remove_watch), (create_source):
Refcount fds, fixes some reentrancy issues.
2003-07-30 Havoc Pennington <hp@redhat.com>
* dbus/dbus-bus.c (init_connections_unlocked): fix default system
bus address to be abstract if we have abstract sockets
* NEWS: update
2003-07-28 Havoc Pennington <hp@redhat.com>
* bus/messagebus.in: fix to avoid processname/servicename
confusion, from Michael Kearey
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=100965
2003-07-23 Havoc Pennington <hp@pobox.com>
* dbus/dbus-message.c (dbus_message_iter_get_named):
fix from Andy Hanton to remove broken "+1"
2003-07-16 Havoc Pennington <hp@pobox.com>
* tools/dbus-launch.c (babysit): close stdout/stderr in the
babysitter process, as suggested by Thomas Leonard, so
an "eval `dbus-launch --exit-with-session`" will actually
return
2003-07-16 Havoc Pennington <hp@pobox.com>
* configure.in: print out EXPANDED_* variables in the summary at
the end; clean up the code that computes EXPANDED_ variables and
get the ones using exec_prefix right. Should make things work
when you build without --prefix
Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/dbus/Makefile.am,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- Makefile.am 29 Sep 2003 01:43:52 -0000 1.56
+++ Makefile.am 30 Sep 2003 02:32:52 -0000 1.57
@@ -15,7 +15,7 @@
dbus-macros.h \
dbus-memory.h \
dbus-message.h \
- dbus-message-handler.h \
+ dbus-pending-call.h \
dbus-protocol.h \
dbus-server.h \
dbus-threads.h \
@@ -39,8 +39,10 @@
dbus-keyring.c \
dbus-keyring.h \
dbus-message.c \
- dbus-message-handler.c \
dbus-message-internal.h \
+ dbus-object-tree.c \
+ dbus-object-tree.h \
+ dbus-pending-call.c \
dbus-resources.c \
dbus-resources.h \
dbus-server.c \
Index: dbus-address.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-address.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dbus-address.c 3 May 2003 23:20:34 -0000 1.10
+++ dbus-address.c 30 Sep 2003 02:32:52 -0000 1.11
@@ -25,22 +25,29 @@
#include "dbus-address.h"
#include "dbus-internals.h"
#include "dbus-list.h"
+#include "dbus-string.h"
/**
- * @defgroup DBusAddress Address parsing
- * @ingroup DBus
- * @brief Parsing addresses of D-BUS servers.
+ * @defgroup DBusAddressInternals Address parsing
+ * @ingroup DBusInternals
+ * @brief Implementation of parsing addresses of D-BUS servers.
*
* @{
*/
+
+/**
+ * Internals of DBusAddressEntry
+ */
struct DBusAddressEntry
{
- DBusString method;
+ DBusString method; /**< The address type (unix, tcp, etc.) */
- DBusList *keys;
- DBusList *values;
+ DBusList *keys; /**< List of keys */
+ DBusList *values; /**< List of values */
};
+/** @} */ /* End of internals */
+
static void
dbus_address_entry_free (DBusAddressEntry *entry)
{
@@ -71,6 +78,13 @@
dbus_free (entry);
}
+/**
+ * @defgroup DBusAddress Address parsing
+ * @ingroup DBus
+ * @brief Parsing addresses of D-BUS servers.
+ *
+ * @{
+ */
/**
* Frees a #NULL-terminated array of address entries.
@@ -371,7 +385,7 @@
}
-/** @} */
+/** @} */ /* End of public API */
#ifdef DBUS_BUILD_TESTS
#include "dbus-test.h"
Index: dbus-auth.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- dbus-auth.c 11 May 2003 07:59:08 -0000 1.28
+++ dbus-auth.c 30 Sep 2003 02:32:52 -0000 1.29
@@ -28,8 +28,6 @@
#include "dbus-sha.h"
#include "dbus-userdb.h"
-/* See doc/dbus-sasl-profile.txt */
-
/**
* @defgroup DBusAuth Authentication
* @ingroup DBusInternals
@@ -75,10 +73,13 @@
const DBusString *command,
const DBusString *args);
+/**
+ * Handler for a given auth protocol command
+ */
typedef struct
{
- const char *command;
- DBusProcessAuthCommandFunction func;
+ const char *command; /**< Name of the command */
+ DBusProcessAuthCommandFunction func; /**< Function to handle the command */
} DBusAuthCommandHandler;
/**
@@ -113,18 +114,21 @@
*/
typedef void (* DBusAuthShutdownFunction) (DBusAuth *auth);
+/**
+ * Virtual table representing a particular auth mechanism.
+ */
typedef struct
{
- const char *mechanism;
- DBusAuthDataFunction server_data_func;
- DBusAuthEncodeFunction server_encode_func;
- DBusAuthDecodeFunction server_decode_func;
- DBusAuthShutdownFunction server_shutdown_func;
- DBusInitialResponseFunction client_initial_response_func;
- DBusAuthDataFunction client_data_func;
- DBusAuthEncodeFunction client_encode_func;
- DBusAuthDecodeFunction client_decode_func;
- DBusAuthShutdownFunction client_shutdown_func;
+ const char *mechanism; /**< Name of the mechanism */
+ DBusAuthDataFunction server_data_func; /**< Function on server side for DATA */
+ DBusAuthEncodeFunction server_encode_func; /**< Function on server side to encode */
+ DBusAuthDecodeFunction server_decode_func; /**< Function on server side to decode */
+ DBusAuthShutdownFunction server_shutdown_func; /**< Function on server side to shut down */
+ DBusInitialResponseFunction client_initial_response_func; /**< Function on client side to handle initial response */
+ DBusAuthDataFunction client_data_func; /**< Function on client side for DATA */
+ DBusAuthEncodeFunction client_encode_func; /**< Function on client side for encode */
+ DBusAuthDecodeFunction client_decode_func; /**< Function on client side for decode */
+ DBusAuthShutdownFunction client_shutdown_func; /**< Function on client side for shutdown */
} DBusAuthMechanismHandler;
/**
@@ -174,17 +178,23 @@
unsigned int buffer_outstanding : 1; /**< Buffer is "checked out" for reading data into */
};
+/**
+ * "Subclass" of DBusAuth for client side
+ */
typedef struct
{
- DBusAuth base;
+ DBusAuth base; /**< Parent class */
DBusList *mechs_to_try; /**< Mechanisms we got from the server that we're going to try using */
} DBusAuthClient;
+/**
+ * "Subclass" of DBusAuth for server side.
+ */
typedef struct
{
- DBusAuth base;
+ DBusAuth base; /**< Parent class */
int failures; /**< Number of times client has been rejected */
int max_failures; /**< Number of times we reject before disconnect */
@@ -2370,7 +2380,7 @@
goto failed;
}
- printf ("Testing:\n");
+ printf ("Testing %s:\n", subdir);
next:
while (_dbus_directory_get_next_file (dir, &filename, &error))
Index: dbus-bus.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- dbus-bus.c 29 Sep 2003 01:43:52 -0000 1.24
+++ dbus-bus.c 30 Sep 2003 02:32:52 -0000 1.25
@@ -25,6 +25,7 @@
#include "dbus-bus.h"
#include "dbus-protocol.h"
#include "dbus-internals.h"
+#include "dbus-message.h"
#include <string.h>
/**
@@ -52,6 +53,10 @@
* Block of message-bus-related data we attach to each
* #DBusConnection used with these convenience functions.
*
+ *
+ * @todo get rid of most of these; they should be done
+ * with DBusGProxy and the Qt equivalent, i.e. the same
+ * way any other interface would be used.
*/
typedef struct
{
@@ -338,6 +343,12 @@
_DBUS_UNLOCK (bus);
return NULL;
}
+
+ /* By default we're bound to the lifecycle of
+ * the message bus.
+ */
+ dbus_connection_set_exit_on_disconnect (connection,
+ TRUE);
if (!dbus_bus_register (connection, error))
{
@@ -403,9 +414,10 @@
return TRUE;
}
- message = dbus_message_new (DBUS_MESSAGE_HELLO,
- DBUS_SERVICE_DBUS);
-
+ message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "Hello");
if (!message)
{
@@ -521,9 +533,10 @@
_dbus_return_val_if_fail (service_name != NULL, 0);
_dbus_return_val_if_error_is_set (error, 0);
- message = dbus_message_new (DBUS_MESSAGE_ACQUIRE_SERVICE,
- DBUS_SERVICE_DBUS);
-
+ message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "AcquireService");
if (message == NULL)
{
@@ -595,8 +608,10 @@
_dbus_return_val_if_fail (service_name != NULL, FALSE);
_dbus_return_val_if_error_is_set (error, FALSE);
- message = dbus_message_new (DBUS_MESSAGE_SERVICE_EXISTS,
- DBUS_SERVICE_DBUS);
+ message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "ServiceExists");
if (message == NULL)
{
_DBUS_SET_OOM (error);
@@ -657,8 +672,10 @@
DBusMessage *msg;
DBusMessage *reply;
- msg = dbus_message_new (DBUS_MESSAGE_ACTIVATE_SERVICE,
- DBUS_SERVICE_DBUS);
+ msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "ActivateService");
if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, service_name,
DBUS_TYPE_UINT32, flags, DBUS_TYPE_INVALID))
@@ -669,7 +686,7 @@
}
reply = dbus_connection_send_with_reply_and_block (connection, msg,
- -1, error);
+ -1, error);
dbus_message_unref (msg);
if (reply == NULL)
@@ -698,5 +715,125 @@
return TRUE;
}
+static void
+send_no_return_values (DBusConnection *connection,
+ DBusMessage *msg,
+ DBusError *error)
+{
+ if (error)
+ {
+ /* Block to check success codepath */
+ DBusMessage *reply;
+
+ reply = dbus_connection_send_with_reply_and_block (connection, msg,
+ -1, error);
+
+ if (reply == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return;
+ }
+
+ if (dbus_set_error_from_message (error, reply))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ dbus_message_unref (reply);
+ return;
+ }
+
+ dbus_message_unref (reply);
+ }
+ else
+ {
+ /* Silently-fail nonblocking codepath */
+ if (!dbus_connection_send (connection, msg, NULL))
+ return;
+ }
+}
+
+/**
+ * Adds a match rule to match messages going through the message bus.
+ * The "rule" argument is the string form of a match rule.
+ *
+ * If you pass #NULL for the error, this function will not
+ * block; the match thus won't be added until you flush the
+ * connection, and if there's an error adding the match
+ * (only possible error is lack of resources in the bus),
+ * you won't find out about it.
+ *
+ * If you pass non-#NULL for the error this function will
+ * block until it gets a reply.
+ *
+ * Normal API conventions would have the function return
+ * a boolean value indicating whether the error was set,
+ * but that would require blocking always to determine
+ * the return value.
+ *
+ * @param connection connection to the message bus
+ * @param rule textual form of match rule
+ * @param error location to store any errors
+ */
+void
+dbus_bus_add_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error)
+{
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "AddMatch");
+
+ if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (msg);
+ _DBUS_SET_OOM (error);
+ return;
+ }
+
+ send_no_return_values (connection, msg, error);
+
+ dbus_message_unref (msg);
+}
+
+/**
+ * Removes a previously-added match rule "by value" (the most
+ * recently-added identical rule gets removed). The "rule" argument
+ * is the string form of a match rule.
+ *
+ * If you pass #NULL for the error, this function will not
+ * block; otherwise it will. See detailed explanation in
+ * docs for dbus_bus_add_match().
+ *
+ * @param connection connection to the message bus
+ * @param rule textual form of match rule
+ * @param error location to store any errors
+ */
+void
+dbus_bus_remove_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error)
+{
+ DBusMessage *msg;
+
+ msg = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "RemoveMatch");
+
+ if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, rule,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (msg);
+ _DBUS_SET_OOM (error);
+ return;
+ }
+
+ send_no_return_values (connection, msg, error);
+
+ dbus_message_unref (msg);
+}
/** @} */
Index: dbus-bus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-bus.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- dbus-bus.h 14 May 2003 02:40:41 -0000 1.7
+++ dbus-bus.h 30 Sep 2003 02:32:52 -0000 1.8
@@ -59,6 +59,13 @@
dbus_uint32_t *reply,
DBusError *error);
+void dbus_bus_add_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+void dbus_bus_remove_match (DBusConnection *connection,
+ const char *rule,
+ DBusError *error);
+
DBUS_END_DECLS;
#endif /* DBUS_BUS_H */
Index: dbus-connection-internal.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection-internal.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-connection-internal.h 18 Apr 2003 04:18:57 -0000 1.12
+++ dbus-connection-internal.h 30 Sep 2003 02:32:52 -0000 1.13
@@ -29,6 +29,8 @@
#include <dbus/dbus-transport.h>
#include <dbus/dbus-resources.h>
#include <dbus/dbus-list.h>
+#include <dbus/dbus-timeout.h>
+#include <dbus/dbus-dataslot.h>
DBUS_BEGIN_DECLS;
@@ -39,9 +41,13 @@
DBUS_ITERATION_BLOCK = 1 << 2 /**< Block if nothing to do. */
} DBusIterationFlags;
+/** default timeout value when waiting for a message reply */
+#define _DBUS_DEFAULT_TIMEOUT_VALUE (15 * 1000)
+
void _dbus_connection_lock (DBusConnection *connection);
void _dbus_connection_unlock (DBusConnection *connection);
void _dbus_connection_ref_unlocked (DBusConnection *connection);
+void _dbus_connection_unref_unlocked (DBusConnection *connection);
dbus_bool_t _dbus_connection_queue_received_message (DBusConnection *connection,
DBusMessage *message);
void _dbus_connection_queue_received_message_link (DBusConnection *connection,
@@ -72,16 +78,52 @@
unsigned int flags,
int timeout_milliseconds);
void _dbus_connection_notify_disconnected (DBusConnection *connection);
-void _dbus_connection_handler_destroyed_locked (DBusConnection *connection,
- DBusMessageHandler *handler);
-dbus_bool_t _dbus_message_handler_add_connection (DBusMessageHandler *handler,
- DBusConnection *connection);
-void _dbus_message_handler_remove_connection (DBusMessageHandler *handler,
- DBusConnection *connection);
-DBusHandlerResult _dbus_message_handler_handle_message (DBusMessageHandler *handler,
- DBusConnection *connection,
+
+DBusPendingCall* _dbus_pending_call_new (DBusConnection *connection,
+ int timeout_milliseconds,
+ DBusTimeoutHandler timeout_handler);
+void _dbus_pending_call_notify (DBusPendingCall *pending);
+void _dbus_connection_remove_pending_call (DBusConnection *connection,
+ DBusPendingCall *pending);
+DBusMessage* _dbus_connection_block_for_reply (DBusConnection *connection,
+ dbus_uint32_t client_serial,
+ int timeout_milliseconds);
+void _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
DBusMessage *message);
+
+/**
+ * @addtogroup DBusPendingCallInternals DBusPendingCall implementation details
+ * @{
+ */
+/**
+ * @brief Internals of DBusPendingCall
+ *
+ * Object representing a reply message that we're waiting for.
+ */
+struct DBusPendingCall
+{
+ DBusAtomic refcount; /**< reference count */
+
+ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+
+ DBusPendingCallNotifyFunction function; /**< Notifier when reply arrives. */
+
+ DBusConnection *connection; /**< Connections we're associated with */
+ DBusMessage *reply; /**< Reply (after we've received it) */
+ DBusTimeout *timeout; /**< Timeout */
+
+ DBusList *timeout_link; /**< Preallocated timeout response */
+
+ dbus_uint32_t reply_serial; /**< Expected serial of reply */
+
+ unsigned int completed : 1; /**< TRUE if completed */
+ unsigned int timeout_added : 1; /**< Have added the timeout */
+};
+
+/** @} End of DBusPendingCallInternals */
+
+
DBUS_END_DECLS;
#endif /* DBUS_CONNECTION_INTERNAL_H */
Index: dbus-connection.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -d -r1.69 -r1.70
--- dbus-connection.c 22 Jun 2003 19:39:47 -0000 1.69
+++ dbus-connection.c 30 Sep 2003 02:32:52 -0000 1.70
@@ -31,10 +31,12 @@
#include "dbus-list.h"
#include "dbus-hash.h"
#include "dbus-message-internal.h"
-#include "dbus-message-handler.h"
#include "dbus-threads.h"
#include "dbus-protocol.h"
#include "dbus-dataslot.h"
+#include "dbus-string.h"
+#include "dbus-pending-call.h"
+#include "dbus-object-tree.h"
#if 0
#define CONNECTION_LOCK(connection) do { \
@@ -77,7 +79,7 @@
* you to set a function to be used to monitor the dispatch status.
*
* If you're using GLib or Qt add-on libraries for D-BUS, there are
- * special convenience functions in those libraries that hide
+ * special convenience APIs in those libraries that hide
* all the details of dispatch and watch/timeout monitoring.
* For example, dbus_connection_setup_with_g_main().
*
@@ -122,8 +124,32 @@
* @{
*/
-/** default timeout value when waiting for a message reply */
-#define DEFAULT_TIMEOUT_VALUE (15 * 1000)
+/**
+ * Internal struct representing a message filter function
+ */
+typedef struct DBusMessageFilter DBusMessageFilter;
+
+/**
+ * Internal struct representing a message filter function
+ */
+struct DBusMessageFilter
+{
+ DBusAtomic refcount; /**< Reference count */
+ DBusHandleMessageFunction function; /**< Function to call to filter */
+ void *user_data; /**< User data for the function */
+ DBusFreeFunction free_user_data_function; /**< Function to free the user data */
+};
+
+
+/**
+ * Internals of DBusPreallocatedSend
+ */
+struct DBusPreallocatedSend
+{
+ DBusConnection *connection; /**< Connection we'd send the message to */
+ DBusList *queue_link; /**< Preallocated link in the queue */
+ DBusList *counter_link; /**< Preallocated link in the resource counter */
+};
static dbus_bool_t _dbus_modify_sigpipe = TRUE;
@@ -157,12 +183,11 @@
DBusWatchList *watches; /**< Stores active watches. */
DBusTimeoutList *timeouts; /**< Stores active timeouts. */
- DBusHashTable *handler_table; /**< Table of registered DBusMessageHandler */
DBusList *filter_list; /**< List of filters. */
DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
- DBusHashTable *pending_replies; /**< Hash of message serials and their message handlers. */
+ DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */
dbus_uint32_t client_serial; /**< Client serial. Increments each time a message is sent */
DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */
@@ -180,30 +205,38 @@
DBusList *link_cache; /**< A cache of linked list links to prevent contention
* for the global linked list mempool lock
*/
-};
-
-typedef struct
-{
- DBusConnection *connection;
- DBusMessageHandler *handler;
- DBusTimeout *timeout;
- int serial;
-
- DBusList *timeout_link; /* Preallocated timeout response */
-
- dbus_bool_t timeout_added;
- dbus_bool_t connection_added;
-} ReplyHandlerData;
+ DBusObjectTree *objects; /**< Object path handlers registered with this connection */
-static void reply_handler_data_free (ReplyHandlerData *data);
+ unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
+};
static void _dbus_connection_remove_timeout_locked (DBusConnection *connection,
DBusTimeout *timeout);
static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
DBusDispatchStatus new_status);
+static void _dbus_connection_last_unref (DBusConnection *connection);
+static void
+_dbus_message_filter_ref (DBusMessageFilter *filter)
+{
+ _dbus_assert (filter->refcount.value > 0);
+ _dbus_atomic_inc (&filter->refcount);
+}
+static void
+_dbus_message_filter_unref (DBusMessageFilter *filter)
+{
+ _dbus_assert (filter->refcount.value > 0);
+
+ if (_dbus_atomic_dec (&filter->refcount) == 1)
+ {
+ if (filter->free_user_data_function)
+ (* filter->free_user_data_function) (filter->user_data);
+
+ dbus_free (filter);
+ }
+}
/**
* Acquires the connection lock.
@@ -281,7 +314,7 @@
_dbus_connection_queue_received_message_link (DBusConnection *connection,
DBusList *link)
{
- ReplyHandlerData *reply_handler_data;
+ DBusPendingCall *pending;
dbus_int32_t reply_serial;
DBusMessage *message;
@@ -295,14 +328,15 @@
reply_serial = dbus_message_get_reply_serial (message);
if (reply_serial != -1)
{
- reply_handler_data = _dbus_hash_table_lookup_int (connection->pending_replies,
- reply_serial);
- if (reply_handler_data != NULL)
+ pending = _dbus_hash_table_lookup_int (connection->pending_replies,
+ reply_serial);
+ if (pending != NULL)
{
- if (reply_handler_data->timeout_added)
+ if (pending->timeout_added)
_dbus_connection_remove_timeout_locked (connection,
- reply_handler_data->timeout);
- reply_handler_data->timeout_added = FALSE;
+ pending->timeout);
+
+ pending->timeout_added = FALSE;
}
}
@@ -310,9 +344,11 @@
_dbus_connection_wakeup_mainloop (connection);
- _dbus_assert (dbus_message_get_name (message) != NULL);
_dbus_verbose ("Message %p (%s) added to incoming queue %p, %d incoming\n",
- message, dbus_message_get_name (message),
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection,
connection->n_incoming);
}
@@ -395,7 +431,10 @@
connection->n_outgoing -= 1;
_dbus_verbose ("Message %p (%s) removed from outgoing queue %p, %d left to send\n",
- message, dbus_message_get_name (message),
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection, connection->n_outgoing);
/* Save this link in the link cache also */
@@ -553,6 +592,118 @@
}
}
+static dbus_bool_t
+_dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
+ DBusPendingCall *pending)
+{
+ _dbus_assert (pending->reply_serial != 0);
+
+ if (!_dbus_connection_add_timeout (connection, pending->timeout))
+ return FALSE;
+
+ if (!_dbus_hash_table_insert_int (connection->pending_replies,
+ pending->reply_serial,
+ pending))
+ {
+ _dbus_connection_remove_timeout (connection, pending->timeout);
+ return FALSE;
+ }
+
+ pending->timeout_added = TRUE;
+ pending->connection = connection;
+
+ dbus_pending_call_ref (pending);
+
+ return TRUE;
+}
+
+static void
+free_pending_call_on_hash_removal (void *data)
+{
+ DBusPendingCall *pending;
+
+ if (data == NULL)
+ return;
+
+ pending = data;
+
+ if (pending->connection)
+ {
+ if (pending->timeout_added)
+ {
+ _dbus_connection_remove_timeout (pending->connection,
+ pending->timeout);
+ pending->timeout_added = FALSE;
+ }
+
+ pending->connection = NULL;
+
+ dbus_pending_call_unref (pending);
+ }
+}
+
+static void
+_dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
+ DBusPendingCall *pending)
+{
+ /* The idea here is to avoid finalizing the pending call
+ * with the lock held, since there's a destroy notifier
+ * in pending call that goes out to application code.
+ */
+ dbus_pending_call_ref (pending);
+ _dbus_hash_table_remove_int (connection->pending_replies,
+ pending->reply_serial);
+ CONNECTION_UNLOCK (connection);
+ dbus_pending_call_unref (pending);
+}
+
+/**
+ * Removes a pending call from the connection, such that
+ * the pending reply will be ignored. May drop the last
+ * reference to the pending call.
+ *
+ * @param connection the connection
+ * @param pending the pending call
+ */
+void
+_dbus_connection_remove_pending_call (DBusConnection *connection,
+ DBusPendingCall *pending)
+{
+ CONNECTION_LOCK (connection);
+ _dbus_connection_detach_pending_call_and_unlock (connection, pending);
+}
+
+/**
+ * Completes a pending call with the given message,
+ * or if the message is #NULL, by timing out the pending call.
+ *
+ * @param pending the pending call
+ * @param message the message to complete the call with, or #NULL
+ * to time out the call
+ */
+void
+_dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
+ DBusMessage *message)
+{
+ if (message == NULL)
+ {
+ message = pending->timeout_link->data;
+ _dbus_list_clear (&pending->timeout_link);
+ }
+
+ _dbus_verbose (" handing message %p to pending call\n", message);
+
+ _dbus_assert (pending->reply == NULL);
+ pending->reply = message;
+ dbus_message_ref (pending->reply);
+
+ dbus_pending_call_ref (pending); /* in case there's no app with a ref held */
+ _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending);
+
+ /* Must be called unlocked since it invokes app callback */
+ _dbus_pending_call_notify (pending);
+ dbus_pending_call_unref (pending);
+}
/**
* Acquire the transporter I/O path. This must be done before
@@ -664,7 +815,7 @@
DBusConnection *connection;
DBusWatchList *watch_list;
DBusTimeoutList *timeout_list;
- DBusHashTable *handler_table, *pending_replies;
+ DBusHashTable *pending_replies;
DBusMutex *mutex;
DBusCondVar *message_returned_cond;
DBusCondVar *dispatch_cond;
@@ -672,10 +823,10 @@
DBusList *disconnect_link;
DBusMessage *disconnect_message;
DBusCounter *outgoing_counter;
+ DBusObjectTree *objects;
watch_list = NULL;
connection = NULL;
- handler_table = NULL;
pending_replies = NULL;
timeout_list = NULL;
mutex = NULL;
@@ -685,6 +836,7 @@
disconnect_link = NULL;
disconnect_message = NULL;
outgoing_counter = NULL;
+ objects = NULL;
watch_list = _dbus_watch_list_new ();
if (watch_list == NULL)
@@ -692,17 +844,12 @@
timeout_list = _dbus_timeout_list_new ();
if (timeout_list == NULL)
- goto error;
-
- handler_table =
- _dbus_hash_table_new (DBUS_HASH_STRING,
- dbus_free, NULL);
- if (handler_table == NULL)
- goto error;
+ goto error;
pending_replies =
_dbus_hash_table_new (DBUS_HASH_INT,
- NULL, (DBusFreeFunction)reply_handler_data_free);
+ NULL,
+ (DBusFreeFunction)free_pending_call_on_hash_removal);
if (pending_replies == NULL)
goto error;
@@ -726,7 +873,10 @@
if (io_path_cond == NULL)
goto error;
- disconnect_message = dbus_message_new (DBUS_MESSAGE_LOCAL_DISCONNECT, NULL);
+ disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
+ "Disconnected");
+
if (disconnect_message == NULL)
goto error;
@@ -737,6 +887,10 @@
outgoing_counter = _dbus_counter_new ();
if (outgoing_counter == NULL)
goto error;
+
+ objects = _dbus_object_tree_new (connection);
+ if (objects == NULL)
+ goto error;
if (_dbus_modify_sigpipe)
_dbus_disable_sigpipe ();
@@ -749,11 +903,12 @@
connection->transport = transport;
connection->watches = watch_list;
connection->timeouts = timeout_list;
- connection->handler_table = handler_table;
connection->pending_replies = pending_replies;
connection->outgoing_counter = outgoing_counter;
connection->filter_list = NULL;
connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
+ connection->objects = objects;
+ connection->exit_on_disconnect = FALSE;
_dbus_data_slot_list_init (&connection->slot_list);
@@ -790,9 +945,6 @@
if (connection != NULL)
dbus_free (connection);
- if (handler_table)
- _dbus_hash_table_unref (handler_table);
-
if (pending_replies)
_dbus_hash_table_unref (pending_replies);
@@ -804,6 +956,9 @@
if (outgoing_counter)
_dbus_counter_unref (outgoing_counter);
+
+ if (objects)
+ _dbus_object_tree_unref (objects);
return NULL;
}
@@ -825,6 +980,39 @@
#endif
}
+/**
+ * Decrements the reference count of a DBusConnection.
+ * Requires that the caller already holds the connection lock.
+ *
+ * @param connection the connection.
+ */
+void
+_dbus_connection_unref_unlocked (DBusConnection *connection)
+{
+ dbus_bool_t last_unref;
+
+ _dbus_return_if_fail (connection != NULL);
+
+ /* The connection lock is better than the global
+ * lock in the atomic increment fallback
+ */
+
+#ifdef DBUS_HAVE_ATOMIC_INT
+ last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
+#else
+ _dbus_assert (connection->refcount.value > 0);
+
+ connection->refcount.value -= 1;
+ last_unref = (connection->refcount.value == 0);
+#if 0
+ printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
+#endif
+#endif
+
+ if (last_unref)
+ _dbus_connection_last_unref (connection);
+}
+
static dbus_uint32_t
_dbus_connection_get_next_client_serial (DBusConnection *connection)
{
@@ -839,50 +1027,6 @@
}
/**
- * Used to notify a connection when a DBusMessageHandler is
- * destroyed, so the connection can drop any reference
- * to the handler. This is a private function, but still
- * takes the connection lock. Don't call it with the lock held.
- *
- * @todo needs to check in pending_replies too.
- *
- * @param connection the connection
- * @param handler the handler
- */
-void
-_dbus_connection_handler_destroyed_locked (DBusConnection *connection,
- DBusMessageHandler *handler)
-{
- DBusHashIter iter;
- DBusList *link;
-
- CONNECTION_LOCK (connection);
-
- _dbus_hash_iter_init (connection->handler_table, &iter);
- while (_dbus_hash_iter_next (&iter))
- {
- DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
-
- if (h == handler)
- _dbus_hash_iter_remove_entry (&iter);
- }
-
- link = _dbus_list_get_first_link (&connection->filter_list);
- while (link != NULL)
- {
- DBusMessageHandler *h = link->data;
- DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
-
- if (h == handler)
- _dbus_list_remove_link (&connection->filter_list,
- link);
-
- link = next;
- }
- CONNECTION_UNLOCK (connection);
-}
-
-/**
* A callback for use with dbus_watch_new() to create a DBusWatch.
*
* @todo This is basically a hack - we could delete _dbus_transport_handle_watch()
@@ -1019,7 +1163,6 @@
static void
_dbus_connection_last_unref (DBusConnection *connection)
{
- DBusHashIter iter;
DBusList *link;
_dbus_verbose ("Finalizing connection %p\n", connection);
@@ -1032,6 +1175,8 @@
_dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
/* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
+ _dbus_object_tree_free_all_unlocked (connection->objects);
+
dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
@@ -1043,29 +1188,24 @@
connection->timeouts = NULL;
_dbus_data_slot_list_free (&connection->slot_list);
- /* ---- Done with stuff that invokes application callbacks */
-
- _dbus_hash_iter_init (connection->handler_table, &iter);
- while (_dbus_hash_iter_next (&iter))
- {
- DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
-
- _dbus_message_handler_remove_connection (h, connection);
- }
link = _dbus_list_get_first_link (&connection->filter_list);
while (link != NULL)
{
- DBusMessageHandler *h = link->data;
+ DBusMessageFilter *filter = link->data;
DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
-
- _dbus_message_handler_remove_connection (h, connection);
+
+ filter->function = NULL;
+ _dbus_message_filter_unref (filter); /* calls app callback */
+ link->data = NULL;
link = next;
}
+ _dbus_list_clear (&connection->filter_list);
+
+ /* ---- Done with stuff that invokes application callbacks */
- _dbus_hash_table_unref (connection->handler_table);
- connection->handler_table = NULL;
+ _dbus_object_tree_unref (connection->objects);
_dbus_hash_table_unref (connection->pending_replies);
connection->pending_replies = NULL;
@@ -1219,12 +1359,29 @@
return res;
}
-struct DBusPreallocatedSend
+/**
+ * Set whether _exit() should be called when the connection receives a
+ * disconnect signal. The call to _exit() comes after any handlers for
+ * the disconnect signal run; handlers can cancel the exit by calling
+ * this function.
+ *
+ * By default, exit_on_disconnect is #FALSE; but for message bus
+ * connections returned from dbus_bus_get() it will be toggled on
+ * by default.
+ *
+ * @param connection the connection
+ * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal
+ */
+void
+dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
+ dbus_bool_t exit_on_disconnect)
{
- DBusConnection *connection;
- DBusList *queue_link;
- DBusList *counter_link;
-};
+ _dbus_return_if_fail (connection != NULL);
+
+ CONNECTION_LOCK (connection);
+ connection->exit_on_disconnect = exit_on_disconnect != FALSE;
+ CONNECTION_UNLOCK (connection);
+}
static DBusPreallocatedSend*
_dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
@@ -1350,7 +1507,9 @@
_dbus_verbose ("Message %p (%s) added to outgoing queue %p, %d pending to send\n",
message,
- dbus_message_get_name (message),
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
connection,
connection->n_outgoing);
@@ -1398,7 +1557,12 @@
_dbus_return_if_fail (preallocated != NULL);
_dbus_return_if_fail (message != NULL);
_dbus_return_if_fail (preallocated->connection == connection);
- _dbus_return_if_fail (dbus_message_get_name (message) != NULL);
+ _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
+ (dbus_message_get_interface (message) != NULL &&
+ dbus_message_get_member (message) != NULL));
+ _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
+ (dbus_message_get_interface (message) != NULL &&
+ dbus_message_get_member (message) != NULL));
CONNECTION_LOCK (connection);
_dbus_connection_send_preallocated_unlocked (connection,
@@ -1407,6 +1571,28 @@
CONNECTION_UNLOCK (connection);
}
+static dbus_bool_t
+_dbus_connection_send_unlocked (DBusConnection *connection,
+ DBusMessage *message,
+ dbus_uint32_t *client_serial)
+{
+ DBusPreallocatedSend *preallocated;
+
+ _dbus_assert (connection != NULL);
+ _dbus_assert (message != NULL);
+
+ preallocated = _dbus_connection_preallocate_send_unlocked (connection);
+ if (preallocated == NULL)
+ return FALSE;
+
+
+ _dbus_connection_send_preallocated_unlocked (connection,
+ preallocated,
+ message,
+ client_serial);
+ return TRUE;
+}
+
/**
* Adds a message to the outgoing message queue. Does not block to
* write the message to the network; that happens asynchronously. To
@@ -1430,50 +1616,41 @@
DBusMessage *message,
dbus_uint32_t *client_serial)
{
- DBusPreallocatedSend *preallocated;
-
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (message != NULL, FALSE);
CONNECTION_LOCK (connection);
-
- preallocated = _dbus_connection_preallocate_send_unlocked (connection);
- if (preallocated == NULL)
+
+ if (!_dbus_connection_send_unlocked (connection, message, client_serial))
{
CONNECTION_UNLOCK (connection);
return FALSE;
}
- else
- {
- _dbus_connection_send_preallocated_unlocked (connection,
- preallocated,
- message,
- client_serial);
- CONNECTION_UNLOCK (connection);
- return TRUE;
- }
+
+ CONNECTION_UNLOCK (connection);
+ return TRUE;
}
static dbus_bool_t
reply_handler_timeout (void *data)
{
DBusConnection *connection;
- ReplyHandlerData *reply_handler_data = data;
DBusDispatchStatus status;
+ DBusPendingCall *pending = data;
- connection = reply_handler_data->connection;
+ connection = pending->connection;
CONNECTION_LOCK (connection);
- if (reply_handler_data->timeout_link)
+ if (pending->timeout_link)
{
_dbus_connection_queue_synthesized_message_link (connection,
- reply_handler_data->timeout_link);
- reply_handler_data->timeout_link = NULL;
+ pending->timeout_link);
+ pending->timeout_link = NULL;
}
_dbus_connection_remove_timeout (connection,
- reply_handler_data->timeout);
- reply_handler_data->timeout_added = FALSE;
+ pending->timeout);
+ pending->timeout_added = FALSE;
status = _dbus_connection_get_dispatch_status_unlocked (connection);
@@ -1483,52 +1660,29 @@
return TRUE;
}
-static void
-reply_handler_data_free (ReplyHandlerData *data)
-{
- if (!data)
- return;
-
- if (data->timeout_added)
- _dbus_connection_remove_timeout_locked (data->connection,
- data->timeout);
-
- if (data->connection_added)
- _dbus_message_handler_remove_connection (data->handler,
- data->connection);
-
- if (data->timeout_link)
- {
- dbus_message_unref ((DBusMessage *)data->timeout_link->data);
- _dbus_list_free_link (data->timeout_link);
- }
-
- dbus_message_handler_unref (data->handler);
-
- dbus_free (data);
-}
-
/**
* Queues a message to send, as with dbus_connection_send_message(),
- * but also sets up a DBusMessageHandler to receive a reply to the
+ * but also returns a #DBusPendingCall used to receive a reply to the
* message. If no reply is received in the given timeout_milliseconds,
- * expires the pending reply and sends the DBusMessageHandler a
- * synthetic error reply (generated in-process, not by the remote
- * application) indicating that a timeout occurred.
+ * this function expires the pending reply and generates a synthetic
+ * error reply (generated in-process, not by the remote application)
+ * indicating that a timeout occurred.
*
- * Reply handlers see their replies after message filters see them,
- * but before message handlers added with
- * dbus_connection_register_handler() see them, regardless of the
- * reply message's name. Reply handlers are only handed a single
- * message as a reply, after one reply has been seen the handler is
- * removed. If a filter filters out the reply before the handler sees
- * it, the reply is immediately timed out and a timeout error reply is
+ * A #DBusPendingCall will see a reply message after any filters, but
+ * before any object instances or other handlers. A #DBusPendingCall
+ * will always see exactly one reply message, unless it's cancelled
+ * with dbus_pending_call_cancel().
+ *
+ * If a filter filters out the reply before the handler sees it, the
+ * reply is immediately timed out and a timeout error reply is
* generated. If a filter removes the timeout error reply then the
- * reply handler will never be called. Filters should not do this.
+ * #DBusPendingCall will get confused. Filtering the timeout error
+ * is thus considered a bug and will print a warning.
*
- * If #NULL is passed for the reply_handler, the timeout reply will
- * still be generated and placed into the message queue, but no
- * specific message handler will receive the reply.
+ * If #NULL is passed for the pending_return, the #DBusPendingCall
+ * will still be generated internally, and used to track
+ * the message reply timeout. This means a timeout error will
+ * occur if no reply arrives, unlike with dbus_connection_send().
*
* If -1 is passed for the timeout, a sane default timeout is used. -1
* is typically the best value for the timeout for this reason, unless
@@ -1538,7 +1692,7 @@
*
* @param connection the connection
* @param message the message to send
- * @param reply_handler message handler expecting the reply, or #NULL
+ * @param pending_return return location for a #DBusPendingCall object, or #NULL
* @param timeout_milliseconds timeout in milliseconds or -1 for default
* @returns #TRUE if the message is successfully queued, #FALSE if no memory.
*
@@ -1546,63 +1700,30 @@
dbus_bool_t
dbus_connection_send_with_reply (DBusConnection *connection,
DBusMessage *message,
- DBusMessageHandler *reply_handler,
+ DBusPendingCall **pending_return,
int timeout_milliseconds)
{
- DBusTimeout *timeout;
- ReplyHandlerData *data;
+ DBusPendingCall *pending;
DBusMessage *reply;
DBusList *reply_link;
dbus_int32_t serial = -1;
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (reply_handler != NULL, FALSE);
_dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
-
- if (timeout_milliseconds == -1)
- timeout_milliseconds = DEFAULT_TIMEOUT_VALUE;
-
- data = dbus_new0 (ReplyHandlerData, 1);
- if (!data)
- return FALSE;
+ if (pending_return)
+ *pending_return = NULL;
- timeout = _dbus_timeout_new (timeout_milliseconds, reply_handler_timeout,
- data, NULL);
+ pending = _dbus_pending_call_new (connection,
+ timeout_milliseconds,
+ reply_handler_timeout);
- if (!timeout)
- {
- reply_handler_data_free (data);
- return FALSE;
- }
+ if (pending == NULL)
+ return FALSE;
CONNECTION_LOCK (connection);
- /* Add timeout */
- if (!_dbus_connection_add_timeout (connection, timeout))
- {
- reply_handler_data_free (data);
- _dbus_timeout_unref (timeout);
- CONNECTION_UNLOCK (connection);
- return FALSE;
- }
-
- /* The connection now owns the reference to the timeout. */
- _dbus_timeout_unref (timeout);
-
- data->timeout_added = TRUE;
- data->timeout = timeout;
- data->connection = connection;
-
- if (!_dbus_message_handler_add_connection (reply_handler, connection))
- {
- CONNECTION_UNLOCK (connection);
- reply_handler_data_free (data);
- return FALSE;
- }
- data->connection_added = TRUE;
-
/* Assign a serial to the message */
if (dbus_message_get_serial (message) == 0)
{
@@ -1610,17 +1731,14 @@
_dbus_message_set_serial (message, serial);
}
- data->handler = reply_handler;
- data->serial = serial;
-
- dbus_message_handler_ref (reply_handler);
+ pending->reply_serial = serial;
- reply = dbus_message_new_error_reply (message, DBUS_ERROR_NO_REPLY,
- "No reply within specified time");
+ reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
+ "No reply within specified time");
if (!reply)
{
CONNECTION_UNLOCK (connection);
- reply_handler_data_free (data);
+ dbus_pending_call_unref (pending);
return FALSE;
}
@@ -1629,33 +1747,42 @@
{
CONNECTION_UNLOCK (connection);
dbus_message_unref (reply);
- reply_handler_data_free (data);
+ dbus_pending_call_unref (pending);
return FALSE;
}
- data->timeout_link = reply_link;
-
- /* Insert the serial in the pending replies hash. */
- if (!_dbus_hash_table_insert_int (connection->pending_replies, serial, data))
+ pending->timeout_link = reply_link;
+
+ /* Insert the serial in the pending replies hash;
+ * hash takes a refcount on DBusPendingCall.
+ * Also, add the timeout.
+ */
+ if (!_dbus_connection_attach_pending_call_unlocked (connection,
+ pending))
{
CONNECTION_UNLOCK (connection);
- reply_handler_data_free (data);
+ dbus_pending_call_unref (pending);
return FALSE;
}
-
- CONNECTION_UNLOCK (connection);
- if (!dbus_connection_send (connection, message, NULL))
+ if (!_dbus_connection_send_unlocked (connection, message, NULL))
{
- /* This will free the handler data too */
- _dbus_hash_table_remove_int (connection->pending_replies, serial);
+ _dbus_connection_detach_pending_call_and_unlock (connection,
+ pending);
return FALSE;
}
+ if (pending_return)
+ {
+ dbus_pending_call_ref (pending);
+ *pending_return = pending;
+ }
+
+ CONNECTION_UNLOCK (connection);
+
return TRUE;
}
-
static DBusMessage*
check_for_reply_unlocked (DBusConnection *connection,
dbus_uint32_t client_serial)
@@ -1682,45 +1809,34 @@
}
/**
- * Sends a message and blocks a certain time period while waiting for a reply.
- * This function does not dispatch any message handlers until the main loop
- * has been reached. This function is used to do non-reentrant "method calls."
- * If a reply is received, it is returned, and removed from the incoming
- * message queue. If it is not received, #NULL is returned and the
- * error is set to #DBUS_ERROR_NO_REPLY. If something else goes
- * wrong, result is set to whatever is appropriate, such as
- * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED.
+ * Blocks a certain time period while waiting for a reply.
+ * If no reply arrives, returns #NULL.
*
* @todo could use performance improvements (it keeps scanning
* the whole message queue for example) and has thread issues,
* see comments in source
*
* @param connection the connection
- * @param message the message to send
+ * @param client_serial the reply serial to wait for
* @param timeout_milliseconds timeout in milliseconds or -1 for default
- * @param error return location for error message
- * @returns the message that is the reply or #NULL with an error code if the
- * function fails.
+ * @returns the message that is the reply or #NULL if no reply
*/
-DBusMessage *
-dbus_connection_send_with_reply_and_block (DBusConnection *connection,
- DBusMessage *message,
- int timeout_milliseconds,
- DBusError *error)
+DBusMessage*
+_dbus_connection_block_for_reply (DBusConnection *connection,
+ dbus_uint32_t client_serial,
+ int timeout_milliseconds)
{
- dbus_uint32_t client_serial;
long start_tv_sec, start_tv_usec;
long end_tv_sec, end_tv_usec;
long tv_sec, tv_usec;
DBusDispatchStatus status;
_dbus_return_val_if_fail (connection != NULL, NULL);
- _dbus_return_val_if_fail (message != NULL, NULL);
- _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
- _dbus_return_val_if_error_is_set (error, NULL);
+ _dbus_return_val_if_fail (client_serial != 0, NULL);
+ _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
if (timeout_milliseconds == -1)
- timeout_milliseconds = DEFAULT_TIMEOUT_VALUE;
+ timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
/* it would probably seem logical to pass in _DBUS_INT_MAX
* for infinite timeout, but then math below would get
@@ -1729,14 +1845,6 @@
if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
- if (!dbus_connection_send (connection, message, &client_serial))
- {
- _DBUS_SET_OOM (error);
- return NULL;
- }
-
- message = NULL;
-
/* Flush message queue */
dbus_connection_flush (connection);
@@ -1778,8 +1886,7 @@
{
status = _dbus_connection_get_dispatch_status_unlocked (connection);
- _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply %s\n",
- dbus_message_get_name (reply));
+ _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
/* Unlocks, and calls out to user code */
_dbus_connection_update_dispatch_status_and_unlock (connection, status);
@@ -1831,11 +1938,6 @@
_dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
(tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
-
- if (dbus_connection_get_is_connected (connection))
- dbus_set_error (error, DBUS_ERROR_NO_REPLY, "Message did not receive a reply");
- else
- dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Disconnected prior to receiving a reply");
/* unlocks and calls out to user code */
_dbus_connection_update_dispatch_status_and_unlock (connection, status);
@@ -1844,6 +1946,70 @@
}
/**
+ * Sends a message and blocks a certain time period while waiting for
+ * a reply. This function does not reenter the main loop,
+ * i.e. messages other than the reply are queued up but not
+ * processed. This function is used to do non-reentrant "method
+ * calls."
+ *
+ * If a normal reply is received, it is returned, and removed from the
+ * incoming message queue. If it is not received, #NULL is returned
+ * and the error is set to #DBUS_ERROR_NO_REPLY. If an error reply is
+ * received, it is converted to a #DBusError and returned as an error,
+ * then the reply message is deleted. If something else goes wrong,
+ * result is set to whatever is appropriate, such as
+ * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED.
+ *
+ * @param connection the connection
+ * @param message the message to send
+ * @param timeout_milliseconds timeout in milliseconds or -1 for default
+ * @param error return location for error message
+ * @returns the message that is the reply or #NULL with an error code if the
+ * function fails.
+ */
+DBusMessage *
+dbus_connection_send_with_reply_and_block (DBusConnection *connection,
+ DBusMessage *message,
+ int timeout_milliseconds,
+ DBusError *error)
+{
+ dbus_uint32_t client_serial;
+ DBusMessage *reply;
+
+ _dbus_return_val_if_fail (connection != NULL, NULL);
+ _dbus_return_val_if_fail (message != NULL, NULL);
+ _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
+ _dbus_return_val_if_error_is_set (error, NULL);
+
+ if (!dbus_connection_send (connection, message, &client_serial))
+ {
+ _DBUS_SET_OOM (error);
+ return NULL;
+ }
+
+ reply = _dbus_connection_block_for_reply (connection,
+ client_serial,
+ timeout_milliseconds);
+
+ if (reply == NULL)
+ {
+ if (dbus_connection_get_is_connected (connection))
+ dbus_set_error (error, DBUS_ERROR_NO_REPLY, "Message did not receive a reply");
+ else
+ dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Disconnected prior to receiving a reply");
+
+ return NULL;
+ }
+ else if (dbus_set_error_from_message (error, reply))
+ {
+ dbus_message_unref (reply);
+ return NULL;
+ }
+ else
+ return reply;
+}
+
+/**
* Blocks until the outgoing message queue is empty.
*
* @param connection the connection.
@@ -1908,6 +2074,8 @@
DBusDispatchStatus status;
_dbus_return_val_if_fail (connection != NULL, NULL);
+ /* can't borrow during dispatch */
+ _dbus_return_val_if_fail (!connection->dispatch_acquired, NULL);
/* this is called for the side effect that it queues
* up any messages from the transport
@@ -1943,6 +2111,8 @@
{
_dbus_return_if_fail (connection != NULL);
_dbus_return_if_fail (message != NULL);
+ /* can't borrow during dispatch */
+ _dbus_return_if_fail (!connection->dispatch_acquired);
CONNECTION_LOCK (connection);
@@ -1971,6 +2141,8 @@
_dbus_return_if_fail (connection != NULL);
_dbus_return_if_fail (message != NULL);
+ /* can't borrow during dispatch */
+ _dbus_return_if_fail (!connection->dispatch_acquired);
CONNECTION_LOCK (connection);
@@ -2007,7 +2179,10 @@
connection->n_incoming -= 1;
_dbus_verbose ("Message %p (%s) removed from incoming queue %p, %d incoming\n",
- link->data, dbus_message_get_name (link->data),
+ link->data,
+ dbus_message_get_interface (link->data) ?
+ dbus_message_get_interface (link->data) :
+ "no interface",
connection, connection->n_incoming);
return link;
@@ -2040,6 +2215,25 @@
return NULL;
}
+static void
+_dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
+ DBusList *message_link)
+{
+ _dbus_assert (message_link != NULL);
+ /* You can't borrow a message while a link is outstanding */
+ _dbus_assert (connection->message_borrowed == NULL);
+
+ _dbus_list_prepend_link (&connection->incoming_messages,
+ message_link);
+ connection->n_incoming += 1;
+
+ _dbus_verbose ("Message %p (%s) put back into queue %p, %d incoming\n",
+ message_link->data,
+ dbus_message_get_interface (message_link->data) ?
+ dbus_message_get_interface (message_link->data) :
+ "no interface",
+ connection, connection->n_incoming);
+}
/**
* Returns the first-received message from the incoming message queue,
@@ -2215,18 +2409,22 @@
* does not necessarily dispatch a message, as the data may
* be part of authentication or the like.
*
+ * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY
+ *
+ * @todo right now a message filter gets run on replies to a pending
+ * call in here, but not in the case where we block without
+ * entering the main loop.
+ *
* @param connection the connection
* @returns dispatch status
*/
DBusDispatchStatus
dbus_connection_dispatch (DBusConnection *connection)
{
- DBusMessageHandler *handler;
DBusMessage *message;
DBusList *link, *filter_list_copy, *message_link;
DBusHandlerResult result;
- ReplyHandlerData *reply_handler_data;
- const char *name;
+ DBusPendingCall *pending;
dbus_int32_t reply_serial;
DBusDispatchStatus status;
@@ -2272,11 +2470,11 @@
message = message_link->data;
- result = DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+ result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
reply_serial = dbus_message_get_reply_serial (message);
- reply_handler_data = _dbus_hash_table_lookup_int (connection->pending_replies,
- reply_serial);
+ pending = _dbus_hash_table_lookup_int (connection->pending_replies,
+ reply_serial);
if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
{
@@ -2294,7 +2492,7 @@
}
_dbus_list_foreach (&filter_list_copy,
- (DBusForeachFunction)dbus_message_handler_ref,
+ (DBusForeachFunction)_dbus_message_filter_ref,
NULL);
/* We're still protected from dispatch() reentrancy here
@@ -2305,92 +2503,164 @@
link = _dbus_list_get_first_link (&filter_list_copy);
while (link != NULL)
{
- DBusMessageHandler *handler = link->data;
+ DBusMessageFilter *filter = link->data;
DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
_dbus_verbose (" running filter on message %p\n", message);
- result = _dbus_message_handler_handle_message (handler, connection,
- message);
+ result = (* filter->function) (connection, message, filter->user_data);
- if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
+ if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
break;
link = next;
}
_dbus_list_foreach (&filter_list_copy,
- (DBusForeachFunction)dbus_message_handler_unref,
+ (DBusForeachFunction)_dbus_message_filter_unref,
NULL);
_dbus_list_clear (&filter_list_copy);
CONNECTION_LOCK (connection);
+ if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
+ goto out;
+
/* Did a reply we were waiting on get filtered? */
- if (reply_handler_data && result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
+ if (pending && result == DBUS_HANDLER_RESULT_HANDLED)
{
/* Queue the timeout immediately! */
- if (reply_handler_data->timeout_link)
+ if (pending->timeout_link)
{
_dbus_connection_queue_synthesized_message_link (connection,
- reply_handler_data->timeout_link);
- reply_handler_data->timeout_link = NULL;
+ pending->timeout_link);
+ pending->timeout_link = NULL;
}
else
{
/* We already queued the timeout? Then it was filtered! */
- _dbus_warn ("The timeout error with reply serial %d was filtered, so the reply handler will never be called.\n", reply_serial);
+ _dbus_warn ("The timeout error with reply serial %d was filtered, so the DBusPendingCall will never stop pending.\n", reply_serial);
}
}
- if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
+ if (result == DBUS_HANDLER_RESULT_HANDLED)
goto out;
-
- if (reply_handler_data)
+
+ if (pending)
{
- CONNECTION_UNLOCK (connection);
+ _dbus_pending_call_complete_and_unlock (pending, message);
- _dbus_verbose (" running reply handler on message %p\n", message);
+ pending = NULL;
- result = _dbus_message_handler_handle_message (reply_handler_data->handler,
- connection, message);
- reply_handler_data_free (reply_handler_data);
CONNECTION_LOCK (connection);
goto out;
}
+
+ /* We're still protected from dispatch() reentrancy here
+ * since we acquired the dispatcher
+ */
+ _dbus_verbose (" running object path dispatch on message %p (%s)\n",
+ message,
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface");
- name = dbus_message_get_name (message);
- if (name != NULL)
+ result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
+ message);
+
+ CONNECTION_LOCK (connection);
+
+ if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
+ goto out;
+
+ if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
{
- handler = _dbus_hash_table_lookup_string (connection->handler_table,
- name);
- if (handler != NULL)
+ DBusMessage *reply;
+ DBusString str;
+ DBusPreallocatedSend *preallocated;
+
+ _dbus_verbose (" sending error %s\n",
+ DBUS_ERROR_UNKNOWN_METHOD);
+
+ if (!_dbus_string_init (&str))
{
- /* We're still protected from dispatch() reentrancy here
- * since we acquired the dispatcher
- */
- CONNECTION_UNLOCK (connection);
+ result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto out;
+ }
+
+ if (!_dbus_string_append_printf (&str,
+ "Method \"%s\" on interface \"%s\" doesn't exist\n",
+ dbus_message_get_member (message),
+ dbus_message_get_interface (message)))
+ {
+ _dbus_string_free (&str);
+ result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto out;
+ }
+
+ reply = dbus_message_new_error (message,
+ DBUS_ERROR_UNKNOWN_METHOD,
+ _dbus_string_get_const_data (&str));
+ _dbus_string_free (&str);
- _dbus_verbose (" running app handler on message %p (%s)\n",
- message, dbus_message_get_name (message));
-
- result = _dbus_message_handler_handle_message (handler, connection,
- message);
- CONNECTION_LOCK (connection);
- if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
- goto out;
+ if (reply == NULL)
+ {
+ result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto out;
+ }
+
+ preallocated = _dbus_connection_preallocate_send_unlocked (connection);
+
+ if (preallocated == NULL)
+ {
+ dbus_message_unref (reply);
+ result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ goto out;
}
- }
+ _dbus_connection_send_preallocated_unlocked (connection, preallocated,
+ reply, NULL);
+
+ dbus_message_unref (reply);
+
+ result = DBUS_HANDLER_RESULT_HANDLED;
+ }
+
_dbus_verbose (" done dispatching %p (%s) on connection %p\n", message,
- dbus_message_get_name (message), connection);
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
+ connection);
out:
+ if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
+ {
+ /* Put message back, and we'll start over.
+ * Yes this means handlers must be idempotent if they
+ * don't return HANDLED; c'est la vie.
+ */
+ _dbus_connection_putback_message_link_unlocked (connection,
+ message_link);
+ }
+ else
+ {
+ if (connection->exit_on_disconnect &&
+ dbus_message_is_signal (message,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
+ "Disconnected"))
+ {
+ _dbus_verbose ("Exiting on Disconnected signal\n");
+ CONNECTION_UNLOCK (connection);
+ _dbus_exit (1);
+ _dbus_assert_not_reached ("Call to exit() returned");
+ }
+
+ _dbus_list_free_link (message_link);
+ dbus_message_unref (message); /* don't want the message to count in max message limits
+ * in computing dispatch status below
+ */
+ }
+
_dbus_connection_release_dispatch (connection);
-
- _dbus_list_free_link (message_link);
- dbus_message_unref (message); /* don't want the message to count in max message limits
- * in computing dispatch status
- */
status = _dbus_connection_get_dispatch_status_unlocked (connection);
@@ -2704,226 +2974,248 @@
}
/**
- * Adds a message filter. Filters are handlers that are run on
- * all incoming messages, prior to the normal handlers
- * registered with dbus_connection_register_handler().
- * Filters are run in the order that they were added.
- * The same handler can be added as a filter more than once, in
- * which case it will be run more than once.
- * Filters added during a filter callback won't be run on the
- * message being processed.
+ * Adds a message filter. Filters are handlers that are run on all
+ * incoming messages, prior to the objects registered with
+ * dbus_connection_register_object_path(). Filters are run in the
+ * order that they were added. The same handler can be added as a
+ * filter more than once, in which case it will be run more than once.
+ * Filters added during a filter callback won't be run on the message
+ * being processed.
*
- * The connection does NOT add a reference to the message handler;
- * instead, if the message handler is finalized, the connection simply
- * forgets about it. Thus the caller of this function must keep a
- * reference to the message handler.
+ * @todo we don't run filters on messages while blocking without
+ * entering the main loop, since filters are run as part of
+ * dbus_connection_dispatch().
*
* @param connection the connection
- * @param handler the handler
+ * @param function function to handle messages
+ * @param user_data user data to pass to the function
+ * @param free_data_function function to use for freeing user data
* @returns #TRUE on success, #FALSE if not enough memory.
*/
dbus_bool_t
-dbus_connection_add_filter (DBusConnection *connection,
- DBusMessageHandler *handler)
+dbus_connection_add_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data,
+ DBusFreeFunction free_data_function)
{
+ DBusMessageFilter *filter;
+
_dbus_return_val_if_fail (connection != NULL, FALSE);
- _dbus_return_val_if_fail (handler != NULL, FALSE);
+ _dbus_return_val_if_fail (function != NULL, FALSE);
+ filter = dbus_new0 (DBusMessageFilter, 1);
+ if (filter == NULL)
+ return FALSE;
+
+ filter->refcount.value = 1;
+
CONNECTION_LOCK (connection);
- if (!_dbus_message_handler_add_connection (handler, connection))
- {
- CONNECTION_UNLOCK (connection);
- return FALSE;
- }
if (!_dbus_list_append (&connection->filter_list,
- handler))
+ filter))
{
- _dbus_message_handler_remove_connection (handler, connection);
+ _dbus_message_filter_unref (filter);
CONNECTION_UNLOCK (connection);
return FALSE;
}
+ /* Fill in filter after all memory allocated,
+ * so we don't run the free_user_data_function
+ * if the add_filter() fails
+ */
+
+ filter->function = function;
+ filter->user_data = user_data;
+ filter->free_user_data_function = free_data_function;
+
CONNECTION_UNLOCK (connection);
return TRUE;
}
/**
* Removes a previously-added message filter. It is a programming
- * error to call this function for a handler that has not
- * been added as a filter. If the given handler was added
- * more than once, only one instance of it will be removed
- * (the most recently-added instance).
+ * error to call this function for a handler that has not been added
+ * as a filter. If the given handler was added more than once, only
+ * one instance of it will be removed (the most recently-added
+ * instance).
*
* @param connection the connection
- * @param handler the handler to remove
+ * @param function the handler to remove
+ * @param user_data user data for the handler to remove
*
*/
void
-dbus_connection_remove_filter (DBusConnection *connection,
- DBusMessageHandler *handler)
+dbus_connection_remove_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data)
{
+ DBusList *link;
+ DBusMessageFilter *filter;
+
_dbus_return_if_fail (connection != NULL);
- _dbus_return_if_fail (handler != NULL);
+ _dbus_return_if_fail (function != NULL);
CONNECTION_LOCK (connection);
- if (!_dbus_list_remove_last (&connection->filter_list, handler))
+
+ filter = NULL;
+
+ link = _dbus_list_get_last_link (&connection->filter_list);
+ while (link != NULL)
{
- _dbus_warn ("Tried to remove a DBusConnection filter that had not been added\n");
- CONNECTION_UNLOCK (connection);
- return;
+ filter = link->data;
+
+ if (filter->function == function &&
+ filter->user_data == user_data)
+ {
+ _dbus_list_remove_link (&connection->filter_list, link);
+ filter->function = NULL;
+
+ break;
+ }
+
+ link = _dbus_list_get_prev_link (&connection->filter_list, link);
}
+
+ CONNECTION_UNLOCK (connection);
- _dbus_message_handler_remove_connection (handler, connection);
+#ifndef DBUS_DISABLE_CHECKS
+ if (filter == NULL)
+ {
+ _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
+ function, user_data);
+ return;
+ }
+#endif
+
+ /* Call application code */
+ if (filter->free_user_data_function)
+ (* filter->free_user_data_function) (filter->user_data);
- CONNECTION_UNLOCK (connection);
+ filter->free_user_data_function = NULL;
+ filter->user_data = NULL;
+
+ _dbus_message_filter_unref (filter);
}
/**
- * Registers a handler for a list of message names. A single handler
- * can be registered for any number of message names, but each message
- * name can only have one handler at a time. It's not allowed to call
- * this function with the name of a message that already has a
- * handler. If the function returns #FALSE, the handlers were not
- * registered due to lack of memory.
+ * Registers a handler for a given path in the object hierarchy.
+ * The given vtable handles messages sent to exactly the given path.
*
- * The connection does NOT add a reference to the message handler;
- * instead, if the message handler is finalized, the connection simply
- * forgets about it. Thus the caller of this function must keep a
- * reference to the message handler.
*
- * @todo the messages_to_handle arg may be more convenient if it's a
- * single string instead of an array. Though right now MessageHandler
- * is sort of designed to say be associated with an entire object with
- * multiple methods, that's why for example the connection only
- * weakrefs it. So maybe the "manual" API should be different.
- *
* @param connection the connection
- * @param handler the handler
- * @param messages_to_handle the messages to handle
- * @param n_messages the number of message names in messages_to_handle
- * @returns #TRUE on success, #FALSE if no memory or another handler already exists
- *
- **/
+ * @param path #NULL-terminated array of path elements
+ * @param vtable the virtual table
+ * @param user_data data to pass to functions in the vtable
+ * @returns #FALSE if not enough memory
+ */
dbus_bool_t
-dbus_connection_register_handler (DBusConnection *connection,
- DBusMessageHandler *handler,
- const char **messages_to_handle,
- int n_messages)
+dbus_connection_register_object_path (DBusConnection *connection,
+ const char **path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data)
{
- int i;
-
- _dbus_return_val_if_fail (connection != NULL, FALSE);
- _dbus_return_val_if_fail (handler != NULL, FALSE);
- _dbus_return_val_if_fail (n_messages >= 0, FALSE);
- _dbus_return_val_if_fail (n_messages == 0 || messages_to_handle != NULL, FALSE);
+ dbus_bool_t retval;
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+ _dbus_return_val_if_fail (path != NULL, FALSE);
+ _dbus_return_val_if_fail (path[0] != NULL, FALSE);
+ _dbus_return_val_if_fail (vtable != NULL, FALSE);
+
CONNECTION_LOCK (connection);
- i = 0;
- while (i < n_messages)
- {
- DBusHashIter iter;
- char *key;
- key = _dbus_strdup (messages_to_handle[i]);
- if (key == NULL)
- goto failed;
-
- if (!_dbus_hash_iter_lookup (connection->handler_table,
- key, TRUE,
- &iter))
- {
- dbus_free (key);
- goto failed;
- }
+ retval = _dbus_object_tree_register (connection->objects,
+ FALSE,
+ path, vtable,
+ user_data);
- if (_dbus_hash_iter_get_value (&iter) != NULL)
- {
- _dbus_warn ("Bug in application: attempted to register a second handler for %s\n",
- messages_to_handle[i]);
- dbus_free (key); /* won't have replaced the old key with the new one */
- goto failed;
- }
+ CONNECTION_UNLOCK (connection);
- if (!_dbus_message_handler_add_connection (handler, connection))
- {
- _dbus_hash_iter_remove_entry (&iter);
- /* key has freed on nuking the entry */
- goto failed;
- }
-
- _dbus_hash_iter_set_value (&iter, handler);
+ return retval;
+}
- ++i;
- }
-
- CONNECTION_UNLOCK (connection);
- return TRUE;
+/**
+ * Registers a fallback handler for a given subsection of the object
+ * hierarchy. The given vtable handles messages at or below the given
+ * path. You can use this to establish a default message handling
+ * policy for a whole "subdirectory."
+ *
+ * @param connection the connection
+ * @param path #NULL-terminated array of path elements
+ * @param vtable the virtual table
+ * @param user_data data to pass to functions in the vtable
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_connection_register_fallback (DBusConnection *connection,
+ const char **path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data)
+{
+ dbus_bool_t retval;
- failed:
- /* unregister everything registered so far,
- * so we don't fail partially
- */
- dbus_connection_unregister_handler (connection,
- handler,
- messages_to_handle,
- i);
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+ _dbus_return_val_if_fail (path != NULL, FALSE);
+ _dbus_return_val_if_fail (path[0] != NULL, FALSE);
+ _dbus_return_val_if_fail (vtable != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+
+ retval = _dbus_object_tree_register (connection->objects,
+ TRUE,
+ path, vtable,
+ user_data);
CONNECTION_UNLOCK (connection);
- return FALSE;
+
+ return retval;
}
/**
- * Unregisters a handler for a list of message names. The handlers
- * must have been previously registered.
+ * Unregisters the handler registered with exactly the given path.
+ * It's a bug to call this function for a path that isn't registered.
+ * Can unregister both fallback paths and object paths.
*
* @param connection the connection
- * @param handler the handler
- * @param messages_to_handle the messages to handle
- * @param n_messages the number of message names in messages_to_handle
- *
- **/
+ * @param path the #NULL-terminated array of path elements
+ */
void
-dbus_connection_unregister_handler (DBusConnection *connection,
- DBusMessageHandler *handler,
- const char **messages_to_handle,
- int n_messages)
+dbus_connection_unregister_object_path (DBusConnection *connection,
+ const char **path)
{
- int i;
-
_dbus_return_if_fail (connection != NULL);
- _dbus_return_if_fail (handler != NULL);
- _dbus_return_if_fail (n_messages >= 0);
- _dbus_return_if_fail (n_messages == 0 || messages_to_handle != NULL);
-
+ _dbus_return_if_fail (path != NULL);
+ _dbus_return_if_fail (path[0] != NULL);
+
CONNECTION_LOCK (connection);
- i = 0;
- while (i < n_messages)
- {
- DBusHashIter iter;
- if (!_dbus_hash_iter_lookup (connection->handler_table,
- (char*) messages_to_handle[i], FALSE,
- &iter))
- {
- _dbus_warn ("Bug in application: attempted to unregister handler for %s which was not registered\n",
- messages_to_handle[i]);
- }
- else if (_dbus_hash_iter_get_value (&iter) != handler)
- {
- _dbus_warn ("Bug in application: attempted to unregister handler for %s which was registered by a different handler\n",
- messages_to_handle[i]);
- }
- else
- {
- _dbus_hash_iter_remove_entry (&iter);
- _dbus_message_handler_remove_connection (handler, connection);
- }
+ return _dbus_object_tree_unregister_and_unlock (connection->objects,
+ path);
+}
- ++i;
- }
+/**
+ * Lists the registered fallback handlers and object path handlers at
+ * the given parent_path. The returned array should be freed with
+ * dbus_free_string_array().
+ *
+ * @param connection the connection
+ * @param parent_path the path to list the child handlers of
+ * @param child_entries returns #NULL-terminated array of children
+ * @returns #FALSE if no memory to allocate the child entries
+ */
+dbus_bool_t
+dbus_connection_list_registered (DBusConnection *connection,
+ const char **parent_path,
+ char ***child_entries)
+{
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+ _dbus_return_val_if_fail (parent_path != NULL, FALSE);
+ _dbus_return_val_if_fail (child_entries != NULL, FALSE);
- CONNECTION_UNLOCK (connection);
+ CONNECTION_LOCK (connection);
+
+ return _dbus_object_tree_list_registered_and_unlock (connection->objects,
+ parent_path,
+ child_entries);
}
static DBusDataSlotAllocator slot_allocator;
Index: dbus-connection.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- dbus-connection.h 22 Jun 2003 19:39:47 -0000 1.24
+++ dbus-connection.h 30 Sep 2003 02:32:52 -0000 1.25
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-connection.h DBusConnection object
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -28,22 +28,17 @@
#define DBUS_CONNECTION_H
#include <dbus/dbus-errors.h>
-#include <dbus/dbus-message.h>
#include <dbus/dbus-memory.h>
+#include <dbus/dbus-message.h>
DBUS_BEGIN_DECLS;
-typedef struct DBusConnection DBusConnection;
typedef struct DBusWatch DBusWatch;
typedef struct DBusTimeout DBusTimeout;
-typedef struct DBusMessageHandler DBusMessageHandler;
typedef struct DBusPreallocatedSend DBusPreallocatedSend;
-
-typedef enum
-{
- DBUS_HANDLER_RESULT_REMOVE_MESSAGE, /**< Remove this message, no further processing. */
- DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS /**< Run any additional handlers that are interested in this message. */
-} DBusHandlerResult;
+typedef struct DBusPendingCall DBusPendingCall;
+typedef struct DBusConnection DBusConnection;
+typedef struct DBusObjectPathVTable DBusObjectPathVTable;
typedef enum
{
@@ -63,6 +58,13 @@
DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */
} DBusDispatchStatus;
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect */
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect */
+ DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory to return another result */
+} DBusHandlerResult;
+
typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
void *data);
typedef void (* DBusWatchToggledFunction) (DBusWatch *watch,
@@ -83,6 +85,14 @@
unsigned long uid,
void *data);
+typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending,
+ void *user_data);
+
+
+typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
DBusConnection* dbus_connection_open (const char *address,
DBusError *error);
void dbus_connection_ref (DBusConnection *connection);
@@ -90,6 +100,8 @@
void dbus_connection_disconnect (DBusConnection *connection);
dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection);
dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection);
+void dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
+ dbus_bool_t exit_on_disconnect);
void dbus_connection_flush (DBusConnection *connection);
DBusMessage* dbus_connection_borrow_message (DBusConnection *connection);
void dbus_connection_return_message (DBusConnection *connection,
@@ -104,7 +116,7 @@
dbus_uint32_t *client_serial);
dbus_bool_t dbus_connection_send_with_reply (DBusConnection *connection,
DBusMessage *message,
- DBusMessageHandler *reply_handler,
+ DBusPendingCall **pending_return,
int timeout_milliseconds);
DBusMessage * dbus_connection_send_with_reply_and_block (DBusConnection *connection,
DBusMessage *message,
@@ -156,22 +168,18 @@
dbus_bool_t dbus_timeout_handle (DBusTimeout *timeout);
dbus_bool_t dbus_timeout_get_enabled (DBusTimeout *timeout);
-/* Handlers */
-dbus_bool_t dbus_connection_add_filter (DBusConnection *connection,
- DBusMessageHandler *handler);
-void dbus_connection_remove_filter (DBusConnection *connection,
- DBusMessageHandler *handler);
+/* Filters */
-dbus_bool_t dbus_connection_register_handler (DBusConnection *connection,
- DBusMessageHandler *handler,
- const char **messages_to_handle,
- int n_messages);
-void dbus_connection_unregister_handler (DBusConnection *connection,
- DBusMessageHandler *handler,
- const char **messages_to_handle,
- int n_messages);
+dbus_bool_t dbus_connection_add_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data,
+ DBusFreeFunction free_data_function);
+void dbus_connection_remove_filter (DBusConnection *connection,
+ DBusHandleMessageFunction function,
+ void *user_data);
+/* Other */
dbus_bool_t dbus_connection_allocate_data_slot (dbus_int32_t *slot_p);
void dbus_connection_free_data_slot (dbus_int32_t *slot_p);
dbus_bool_t dbus_connection_set_data (DBusConnection *connection,
@@ -200,6 +208,44 @@
dbus_uint32_t *client_serial);
+/* Object tree functionality */
+
+typedef void (* DBusObjectPathUnregisterFunction) (DBusConnection *connection,
+ void *user_data);
+typedef DBusHandlerResult (* DBusObjectPathMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+/**
+ * Virtual table that must be implemented to handle a portion of the
+ * object path hierarchy.
+ */
+struct DBusObjectPathVTable
+{
+ DBusObjectPathUnregisterFunction unregister_function; /**< Function to unregister this handler */
+ DBusObjectPathMessageFunction message_function; /**< Function to handle messages */
+
+ void (* dbus_internal_pad1) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad2) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad3) (void *); /**< Reserved for future expansion */
+ void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */
+};
+
+dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection,
+ const char **path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection,
+ const char **path,
+ const DBusObjectPathVTable *vtable,
+ void *user_data);
+void dbus_connection_unregister_object_path (DBusConnection *connection,
+ const char **path);
+
+dbus_bool_t dbus_connection_list_registered (DBusConnection *connection,
+ const char **parent_path,
+ char ***child_entries);
+
DBUS_END_DECLS;
#endif /* DBUS_CONNECTION_H */
Index: dbus-dataslot.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-dataslot.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- dbus-dataslot.h 22 Jun 2003 19:39:47 -0000 1.3
+++ dbus-dataslot.h 30 Sep 2003 02:32:52 -0000 1.4
@@ -40,12 +40,18 @@
};
typedef struct DBusAllocatedSlot DBusAllocatedSlot;
+
+/** An allocated slot for storing data
+ */
struct DBusAllocatedSlot
{
dbus_int32_t slot_id; /**< ID of this slot */
int refcount; /**< Number of uses of the slot */
};
+/**
+ * An allocator that tracks a set of slot IDs.
+ */
struct DBusDataSlotAllocator
{
DBusAllocatedSlot *allocated_slots; /**< Allocated slots */
@@ -54,6 +60,10 @@
DBusMutex *lock; /**< thread lock */
};
+/**
+ * Data structure that stores the actual user data set at a given
+ * slot.
+ */
struct DBusDataSlotList
{
DBusDataSlot *slots; /**< Data slots */
Index: dbus-errors.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-errors.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- dbus-errors.c 29 Apr 2003 22:57:13 -0000 1.21
+++ dbus-errors.c 30 Sep 2003 02:32:52 -0000 1.22
@@ -23,53 +23,26 @@
*/
#include "dbus-errors.h"
#include "dbus-internals.h"
+#include "dbus-string.h"
#include <stdarg.h>
-#include <stdio.h>
#include <string.h>
/**
- * @defgroup DBusErrors Error reporting
- * @ingroup DBus
- * @brief Error reporting
- *
- * Types and functions related to reporting errors.
- *
- *
- * In essence D-BUS error reporting works as follows:
- *
- * @code
- * DBusError error;
- * dbus_error_init (&error);
- * dbus_some_function (arg1, arg2, &error);
- * if (dbus_error_is_set (&error))
- * {
- * fprintf (stderr, "an error occurred: %s\n", error.message);
- * dbus_error_free (&error);
- * }
- * @endcode
- *
- * There are some rules. An error passed to a D-BUS function must
- * always be unset; you can't pass in an error that's already set. If
- * a function has a return code indicating whether an error occurred,
- * and also a #DBusError parameter, then the error will always be set
- * if and only if the return code indicates an error occurred. i.e.
- * the return code and the error are never going to disagree.
- *
- * An error only needs to be freed if it's been set, not if
- * it's merely been initialized.
- *
- * You can check the specific error that occurred using
- * dbus_error_has_name().
- *
+ * @defgroup DBusErrorInternals Error reporting internals
+ * @ingroup DBusInternals
+ * @brief Error reporting internals
* @{
*/
-
+
+/**
+ * Internals of DBusError
+ */
typedef struct
{
const char *name; /**< error name */
char *message; /**< error message */
- unsigned int const_message : 1; /** Message is not owned by DBusError */
+ unsigned int const_message : 1; /**< Message is not owned by DBusError */
unsigned int dummy2 : 1; /**< placeholder */
unsigned int dummy3 : 1; /**< placeholder */
@@ -127,6 +100,45 @@
return error;
}
+/** @} */ /* End of internals */
+
+/**
+ * @defgroup DBusErrors Error reporting
+ * @ingroup DBus
+ * @brief Error reporting
+ *
+ * Types and functions related to reporting errors.
+ *
+ *
+ * In essence D-BUS error reporting works as follows:
+ *
+ * @code
+ * DBusError error;
+ * dbus_error_init (&error);
+ * dbus_some_function (arg1, arg2, &error);
+ * if (dbus_error_is_set (&error))
+ * {
+ * fprintf (stderr, "an error occurred: %s\n", error.message);
+ * dbus_error_free (&error);
+ * }
+ * @endcode
+ *
+ * There are some rules. An error passed to a D-BUS function must
+ * always be unset; you can't pass in an error that's already set. If
+ * a function has a return code indicating whether an error occurred,
+ * and also a #DBusError parameter, then the error will always be set
+ * if and only if the return code indicates an error occurred. i.e.
+ * the return code and the error are never going to disagree.
+ *
+ * An error only needs to be freed if it's been set, not if
+ * it's merely been initialized.
+ *
+ * You can check the specific error that occurred using
+ * dbus_error_has_name().
+ *
+ * @{
+ */
+
/**
* Initializes a DBusError structure. Does not allocate
* any memory; the error only needs to be freed
@@ -292,9 +304,6 @@
*
* @todo should be called dbus_error_set()
*
- * @todo stdio.h shouldn't be included in this file,
- * should write _dbus_string_append_printf instead
- *
* @param error the error.
* @param name the error name (not copied!!!)
* @param format printf-style format string.
@@ -306,11 +315,9 @@
...)
{
DBusRealError *real;
+ DBusString str;
va_list args;
- int message_length;
- char *message;
- char c;
-
+
if (error == NULL)
return;
@@ -321,31 +328,46 @@
_dbus_assert (error->name == NULL);
_dbus_assert (error->message == NULL);
- if (format == NULL)
- format = message_from_error (name);
-
- va_start (args, format);
- /* Measure the message length */
- message_length = vsnprintf (&c, 1, format, args) + 1;
- va_end (args);
-
- message = dbus_malloc (message_length);
+ if (!_dbus_string_init (&str))
+ goto nomem;
- if (!message)
+ if (format == NULL)
{
- dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, NULL);
- return;
+ if (!_dbus_string_append (&str,
+ message_from_error (name)))
+ {
+ _dbus_string_free (&str);
+ goto nomem;
+ }
+ }
+ else
+ {
+ va_start (args, format);
+ if (!_dbus_string_append_printf_valist (&str, format, args))
+ {
+ _dbus_string_free (&str);
+ goto nomem;
+ }
+ va_end (args);
}
-
- va_start (args, format);
- vsprintf (message, format, args);
- va_end (args);
real = (DBusRealError *)error;
+
+ if (!_dbus_string_steal_data (&str, &real->message))
+ {
+ _dbus_string_free (&str);
+ goto nomem;
+ }
real->name = name;
- real->message = message;
real->const_message = FALSE;
+
+ _dbus_string_free (&str);
+
+ return;
+
+ nomem:
+ dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, NULL);
}
-/** @} */
+/** @} */ /* End public API */
Index: dbus-errors.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-errors.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- dbus-errors.h 5 Apr 2003 19:03:40 -0000 1.19
+++ dbus-errors.h 30 Sep 2003 02:32:52 -0000 1.20
@@ -35,6 +35,9 @@
typedef struct DBusError DBusError;
+/**
+ * Object representing an exception.
+ */
struct DBusError
{
const char *name; /**< error name */
@@ -50,13 +53,8 @@
};
#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed"
-#define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Activate.ServiceNotFound"
-#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed"
-#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
-#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
-#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
-#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
+#define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.ServiceNotFound"
#define DBUS_ERROR_SERVICE_DOES_NOT_EXIST "org.freedesktop.DBus.Error.ServiceDoesNotExist"
#define DBUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply"
#define DBUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError"
@@ -72,8 +70,14 @@
#define DBUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected"
#define DBUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs"
#define DBUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound"
-#define DBUS_ERROR_UNKNOWN_MESSAGE "org.freedesktop.DBus.Error.UnknownMessage"
+#define DBUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod"
#define DBUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut"
+#define DBUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound"
+#define DBUS_ERROR_SPAWN_EXEC_FAILED "org.freedesktop.DBus.Error.Spawn.ExecFailed"
+#define DBUS_ERROR_SPAWN_FORK_FAILED "org.freedesktop.DBus.Error.Spawn.ForkFailed"
+#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
+#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
+#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
void dbus_error_init (DBusError *error);
void dbus_error_free (DBusError *error);
Index: dbus-hash.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-hash.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- dbus-hash.c 5 May 2003 03:13:35 -0000 1.14
+++ dbus-hash.c 30 Sep 2003 02:32:52 -0000 1.15
@@ -221,26 +221,32 @@
int n_entries_on_init; /**< used to detect table resize since initialization */
} DBusRealHashIter;
-static DBusHashEntry* find_direct_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated);
-static DBusHashEntry* find_string_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated);
-static unsigned int string_hash (const char *str);
-static void rebuild_table (DBusHashTable *table);
-static DBusHashEntry* alloc_entry (DBusHashTable *table);
-static void remove_entry (DBusHashTable *table,
- DBusHashEntry **bucket,
- DBusHashEntry *entry);
-static void free_entry (DBusHashTable *table,
- DBusHashEntry *entry);
-static void free_entry_data (DBusHashTable *table,
- DBusHashEntry *entry);
+static DBusHashEntry* find_direct_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static DBusHashEntry* find_string_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static DBusHashEntry* find_two_strings_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated);
+static unsigned int string_hash (const char *str);
+static unsigned int two_strings_hash (const char *str);
+static void rebuild_table (DBusHashTable *table);
+static DBusHashEntry* alloc_entry (DBusHashTable *table);
+static void remove_entry (DBusHashTable *table,
+ DBusHashEntry **bucket,
+ DBusHashEntry *entry);
+static void free_entry (DBusHashTable *table,
+ DBusHashEntry *entry);
+static void free_entry_data (DBusHashTable *table,
+ DBusHashEntry *entry);
/** @} */
@@ -323,6 +329,9 @@
case DBUS_HASH_STRING:
table->find_function = find_string_function;
break;
+ case DBUS_HASH_TWO_STRINGS:
+ table->find_function = find_two_strings_function;
+ break;
default:
_dbus_assert_not_reached ("Unknown hash table type");
break;
@@ -685,6 +694,24 @@
}
/**
+ * Gets the key for the current entry.
+ * Only works for hash tables of type #DBUS_HASH_TWO_STRINGS
+ * @param iter the hash table iterator.
+ */
+const char*
+_dbus_hash_iter_get_two_strings_key (DBusHashIter *iter)
+{
+ DBusRealHashIter *real;
+
+ real = (DBusRealHashIter*) iter;
+
+ _dbus_assert (real->table != NULL);
+ _dbus_assert (real->entry != NULL);
+
+ return real->entry->key;
+}
+
+/**
* A low-level but efficient interface for manipulating the hash
* table. It's efficient because you can get, set, and optionally
* create the hash entry while only running the hash function one
@@ -803,64 +830,64 @@
return entry;
}
+/* This is g_str_hash from GLib which was
+ * extensively discussed/tested/profiled
+ */
static unsigned int
string_hash (const char *str)
{
- register unsigned int result;
- register int c;
+ const char *p = str;
+ unsigned int h = *p;
- /*
- * I tried a zillion different hash functions and asked many other
- * people for advice. Many people had their own favorite functions,
- * all different, but no-one had much idea why they were good ones.
- * I chose the one below (multiply by 9 and add new character)
- * because of the following reasons:
- *
- * 1. Multiplying by 10 is perfect for keys that are decimal strings,
- * and multiplying by 9 is just about as good.
- * 2. Times-9 is (shift-left-3) plus (old). This means that each
- * character's bits hang around in the low-order bits of the
- * hash value for ever, plus they spread fairly rapidly up to
- * the high-order bits to fill out the hash value. This seems
- * works well both for decimal and non-decimal strings.
- */
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
- /* FIXME the hash function in GLib is better than this one */
-
- result = 0;
- while (TRUE)
- {
- c = *str;
- str++;
- if (c == 0)
- break;
-
- result += (result << 3) + c;
- }
+ return h;
+}
+
+/* This hashes a memory block with two nul-terminated strings
+ * in it, used in dbus-object-registry.c at the moment.
+ */
+static unsigned int
+two_strings_hash (const char *str)
+{
+ const char *p = str;
+ unsigned int h = *p;
+
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
+
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
- return result;
+ return h;
}
+/** Key comparison function */
+typedef int (* KeyCompareFunc) (const void *key_a, const void *key_b);
+
static DBusHashEntry*
-find_string_function (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashEntry ***bucket,
- DBusPreallocatedHash *preallocated)
+find_generic_function (DBusHashTable *table,
+ void *key,
+ unsigned int idx,
+ KeyCompareFunc compare_func,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
{
DBusHashEntry *entry;
- unsigned int idx;
if (bucket)
*bucket = NULL;
-
- idx = string_hash (key) & table->mask;
/* Search all of the entries in this bucket. */
entry = table->buckets[idx];
while (entry != NULL)
{
- if (strcmp (key, entry->key) == 0)
+ if ((compare_func == NULL && key == entry->key) ||
+ (compare_func != NULL && (* compare_func) (key, entry->key) == 0))
{
if (bucket)
*bucket = &(table->buckets[idx]);
@@ -878,50 +905,75 @@
entry = add_entry (table, idx, key, bucket, preallocated);
else if (preallocated)
_dbus_hash_table_free_preallocated_entry (table, preallocated);
-
+
return entry;
}
static DBusHashEntry*
-find_direct_function (DBusHashTable *table,
+find_string_function (DBusHashTable *table,
void *key,
dbus_bool_t create_if_not_found,
DBusHashEntry ***bucket,
DBusPreallocatedHash *preallocated)
{
- DBusHashEntry *entry;
unsigned int idx;
+
+ idx = string_hash (key) & table->mask;
- if (bucket)
- *bucket = NULL;
+ return find_generic_function (table, key, idx,
+ (KeyCompareFunc) strcmp, create_if_not_found, bucket,
+ preallocated);
+}
+
+static int
+two_strings_cmp (const char *a,
+ const char *b)
+{
+ size_t len_a;
+ size_t len_b;
+ int res;
- idx = RANDOM_INDEX (table, key) & table->mask;
+ res = strcmp (a, b);
+ if (res != 0)
+ return res;
- /* Search all of the entries in this bucket. */
- entry = table->buckets[idx];
- while (entry != NULL)
- {
- if (key == entry->key)
- {
- if (bucket)
- *bucket = &(table->buckets[idx]);
+ len_a = strlen (a);
+ len_b = strlen (b);
- if (preallocated)
- _dbus_hash_table_free_preallocated_entry (table, preallocated);
-
- return entry;
- }
-
- entry = entry->next;
- }
+ return strcmp (a + len_a + 1, b + len_b + 1);
+}
- /* Entry not found. Add a new one to the bucket. */
- if (create_if_not_found)
- entry = add_entry (table, idx, key, bucket, preallocated);
- else if (preallocated)
- _dbus_hash_table_free_preallocated_entry (table, preallocated);
+static DBusHashEntry*
+find_two_strings_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
+{
+ unsigned int idx;
+
+ idx = two_strings_hash (key) & table->mask;
- return entry;
+ return find_generic_function (table, key, idx,
+ (KeyCompareFunc) two_strings_cmp, create_if_not_found, bucket,
+ preallocated);
+}
+
+static DBusHashEntry*
+find_direct_function (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashEntry ***bucket,
+ DBusPreallocatedHash *preallocated)
+{
+ unsigned int idx;
+
+ idx = RANDOM_INDEX (table, key) & table->mask;
+
+
+ return find_generic_function (table, key, idx,
+ NULL, create_if_not_found, bucket,
+ preallocated);
}
static void
@@ -1021,6 +1073,9 @@
case DBUS_HASH_STRING:
idx = string_hash (entry->key) & table->mask;
break;
+ case DBUS_HASH_TWO_STRINGS:
+ idx = two_strings_hash (entry->key) & table->mask;
+ break;
case DBUS_HASH_INT:
case DBUS_HASH_ULONG:
case DBUS_HASH_POINTER:
@@ -1070,6 +1125,31 @@
}
/**
+ * Looks up the value for a given string in a hash table
+ * of type #DBUS_HASH_TWO_STRINGS. Returns %NULL if the value
+ * is not present. (A not-present entry is indistinguishable
+ * from an entry with a value of %NULL.)
+ * @param table the hash table.
+ * @param key the string to look up.
+ * @returns the value of the hash entry.
+ */
+void*
+_dbus_hash_table_lookup_two_strings (DBusHashTable *table,
+ const char *key)
+{
+ DBusHashEntry *entry;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ entry = (* table->find_function) (table, (char*) key, FALSE, NULL, NULL);
+
+ if (entry)
+ return entry->value;
+ else
+ return NULL;
+}
+
+/**
* Looks up the value for a given integer in a hash table
* of type #DBUS_HASH_INT. Returns %NULL if the value
* is not present. (A not-present entry is indistinguishable
@@ -1184,6 +1264,34 @@
* @returns #TRUE if the entry existed
*/
dbus_bool_t
+_dbus_hash_table_remove_two_strings (DBusHashTable *table,
+ const char *key)
+{
+ DBusHashEntry *entry;
+ DBusHashEntry **bucket;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ entry = (* table->find_function) (table, (char*) key, FALSE, &bucket, NULL);
+
+ if (entry)
+ {
+ remove_entry (table, bucket, entry);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
+ * Removes the hash entry for the given key. If no hash entry
+ * for the key exists, does nothing.
+ *
+ * @param table the hash table.
+ * @param key the hash key.
+ * @returns #TRUE if the entry existed
+ */
+dbus_bool_t
_dbus_hash_table_remove_int (DBusHashTable *table,
int key)
{
@@ -1312,6 +1420,47 @@
* @param value the hash entry value.
*/
dbus_bool_t
+_dbus_hash_table_insert_two_strings (DBusHashTable *table,
+ char *key,
+ void *value)
+{
+ DBusHashEntry *entry;
+
+ _dbus_assert (table->key_type == DBUS_HASH_TWO_STRINGS);
+
+ entry = (* table->find_function) (table, key, TRUE, NULL, NULL);
+
+ if (entry == NULL)
+ return FALSE; /* no memory */
+
+ if (table->free_key_function && entry->key != key)
+ (* table->free_key_function) (entry->key);
+
+ if (table->free_value_function && entry->value != value)
+ (* table->free_value_function) (entry->value);
+
+ entry->key = key;
+ entry->value = value;
+
+ return TRUE;
+}
+
+/**
+ * Creates a hash entry with the given key and value.
+ * The key and value are not copied; they are stored
+ * in the hash table by reference. If an entry with the
+ * given key already exists, the previous key and value
+ * are overwritten (and freed if the hash table has
+ * a key_free_function and/or value_free_function).
+ *
+ * Returns #FALSE if memory for the new hash entry
+ * can't be allocated.
+ *
+ * @param table the hash table.
+ * @param key the hash entry key.
+ * @param value the hash entry value.
+ */
+dbus_bool_t
_dbus_hash_table_insert_int (DBusHashTable *table,
int key,
void *value)
@@ -1536,6 +1685,28 @@
return count;
}
+/* Copy the foo\0bar\0 double string thing */
+static char*
+_dbus_strdup2 (const char *str)
+{
+ size_t len;
+ char *copy;
+
+ if (str == NULL)
+ return NULL;
+
+ len = strlen (str);
+ len += strlen ((str + len + 1));
+
+ copy = dbus_malloc (len + 2);
+ if (copy == NULL)
+ return NULL;
+
+ memcpy (copy, str, len + 2);
+
+ return copy;
+}
+
/**
* @ingroup DBusHashTableInternals
* Unit test for DBusHashTable
@@ -1548,6 +1719,7 @@
DBusHashTable *table1;
DBusHashTable *table2;
DBusHashTable *table3;
+ DBusHashTable *table4;
DBusHashIter iter;
#define N_HASH_KEYS 5000
char **keys;
@@ -1569,7 +1741,16 @@
i = 0;
while (i < N_HASH_KEYS)
{
- sprintf (keys[i], "Hash key %d", i);
+ int len;
+
+ /* all the hash keys are TWO_STRINGS, but
+ * then we can also use those as regular strings.
+ */
+
+ len = sprintf (keys[i], "Hash key %d", i);
+ sprintf (keys[i] + len + 1, "Two string %d", i);
+ _dbus_assert (*(keys[i] + len) == '\0');
+ _dbus_assert (*(keys[i] + len + 1) != '\0');
++i;
}
printf ("... done.\n");
@@ -1588,6 +1769,12 @@
NULL, dbus_free);
if (table3 == NULL)
goto out;
+
+ table4 = _dbus_hash_table_new (DBUS_HASH_TWO_STRINGS,
+ dbus_free, dbus_free);
+ if (table4 == NULL)
+ goto out;
+
/* Insert and remove a bunch of stuff, counting the table in between
* to be sure it's not broken and that iteration works
@@ -1624,10 +1811,22 @@
if (!_dbus_hash_table_insert_ulong (table3,
i, value))
goto out;
+
+ key = _dbus_strdup2 (keys[i]);
+ if (key == NULL)
+ goto out;
+ value = _dbus_strdup ("Value!");
+ if (value == NULL)
+ goto out;
+
+ if (!_dbus_hash_table_insert_two_strings (table4,
+ key, value))
+ goto out;
_dbus_assert (count_entries (table1) == i + 1);
_dbus_assert (count_entries (table2) == i + 1);
_dbus_assert (count_entries (table3) == i + 1);
+ _dbus_assert (count_entries (table4) == i + 1);
value = _dbus_hash_table_lookup_string (table1, keys[i]);
_dbus_assert (value != NULL);
@@ -1640,6 +1839,10 @@
value = _dbus_hash_table_lookup_ulong (table3, i);
_dbus_assert (value != NULL);
_dbus_assert (strcmp (value, keys[i]) == 0);
+
+ value = _dbus_hash_table_lookup_two_strings (table4, keys[i]);
+ _dbus_assert (value != NULL);
+ _dbus_assert (strcmp (value, "Value!") == 0);
++i;
}
@@ -1654,9 +1857,13 @@
_dbus_hash_table_remove_ulong (table3, i);
+ _dbus_hash_table_remove_two_strings (table4,
+ keys[i]);
+
_dbus_assert (count_entries (table1) == i);
_dbus_assert (count_entries (table2) == i);
_dbus_assert (count_entries (table3) == i);
+ _dbus_assert (count_entries (table4) == i);
--i;
}
@@ -1664,12 +1871,15 @@
_dbus_hash_table_ref (table1);
_dbus_hash_table_ref (table2);
_dbus_hash_table_ref (table3);
+ _dbus_hash_table_ref (table4);
_dbus_hash_table_unref (table1);
_dbus_hash_table_unref (table2);
_dbus_hash_table_unref (table3);
+ _dbus_hash_table_unref (table4);
_dbus_hash_table_unref (table1);
_dbus_hash_table_unref (table2);
_dbus_hash_table_unref (table3);
+ _dbus_hash_table_unref (table4);
table3 = NULL;
/* Insert a bunch of stuff then check
Index: dbus-hash.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-hash.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- dbus-hash.h 11 Apr 2003 00:03:06 -0000 1.9
+++ dbus-hash.h 30 Sep 2003 02:32:52 -0000 1.10
@@ -29,17 +29,17 @@
DBUS_BEGIN_DECLS;
-/* The iterator is on the stack, but its real fields are
- * hidden privately.
+/** Hash iterator object. The iterator is on the stack, but its real
+ * fields are hidden privately.
*/
struct DBusHashIter
{
- void *dummy1;
- void *dummy2;
- void *dummy3;
- void *dummy4;
- int dummy5;
- int dummy6;
+ void *dummy1; /**< Do not use. */
+ void *dummy2; /**< Do not use. */
+ void *dummy3; /**< Do not use. */
+ void *dummy4; /**< Do not use. */
+ int dummy5; /**< Do not use. */
+ int dummy6; /**< Do not use. */
};
typedef struct DBusHashTable DBusHashTable;
@@ -52,61 +52,68 @@
*/
typedef enum
{
- DBUS_HASH_STRING, /**< Hash keys are strings. */
- DBUS_HASH_INT, /**< Hash keys are integers. */
- DBUS_HASH_POINTER, /**< Hash keys are pointers. */
- DBUS_HASH_ULONG /**< Hash keys are unsigned long. */
+ DBUS_HASH_STRING, /**< Hash keys are strings. */
+ DBUS_HASH_TWO_STRINGS, /**< Hash key is two strings in one memory block, i.e. foo\\0bar\\0 */
+ DBUS_HASH_INT, /**< Hash keys are integers. */
+ DBUS_HASH_POINTER, /**< Hash keys are pointers. */
+ DBUS_HASH_ULONG /**< Hash keys are unsigned long. */
} DBusHashType;
-
-DBusHashTable* _dbus_hash_table_new (DBusHashType type,
- DBusFreeFunction key_free_function,
- DBusFreeFunction value_free_function);
-void _dbus_hash_table_ref (DBusHashTable *table);
-void _dbus_hash_table_unref (DBusHashTable *table);
-void _dbus_hash_iter_init (DBusHashTable *table,
- DBusHashIter *iter);
-dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
-void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
-void* _dbus_hash_iter_get_value (DBusHashIter *iter);
-void _dbus_hash_iter_set_value (DBusHashIter *iter,
- void *value);
-int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
-const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
-unsigned long _dbus_hash_iter_get_ulong_key (DBusHashIter *iter);
-dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
- void *key,
- dbus_bool_t create_if_not_found,
- DBusHashIter *iter);
-void* _dbus_hash_table_lookup_string (DBusHashTable *table,
- const char *key);
-void* _dbus_hash_table_lookup_int (DBusHashTable *table,
- int key);
-void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
- void *key);
-void* _dbus_hash_table_lookup_ulong (DBusHashTable *table,
- unsigned long key);
-dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
- const char *key);
-dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
- int key);
-dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
- void *key);
-dbus_bool_t _dbus_hash_table_remove_ulong (DBusHashTable *table,
- unsigned long key);
-dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
- char *key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
- int key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
- void *key,
- void *value);
-dbus_bool_t _dbus_hash_table_insert_ulong (DBusHashTable *table,
- unsigned long key,
- void *value);
-int _dbus_hash_table_get_n_entries (DBusHashTable *table);
-
+DBusHashTable* _dbus_hash_table_new (DBusHashType type,
+ DBusFreeFunction key_free_function,
+ DBusFreeFunction value_free_function);
+void _dbus_hash_table_ref (DBusHashTable *table);
+void _dbus_hash_table_unref (DBusHashTable *table);
+void _dbus_hash_iter_init (DBusHashTable *table,
+ DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_next (DBusHashIter *iter);
+void _dbus_hash_iter_remove_entry (DBusHashIter *iter);
+void* _dbus_hash_iter_get_value (DBusHashIter *iter);
+void _dbus_hash_iter_set_value (DBusHashIter *iter,
+ void *value);
+int _dbus_hash_iter_get_int_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_string_key (DBusHashIter *iter);
+const char* _dbus_hash_iter_get_two_strings_key (DBusHashIter *iter);
+unsigned long _dbus_hash_iter_get_ulong_key (DBusHashIter *iter);
+dbus_bool_t _dbus_hash_iter_lookup (DBusHashTable *table,
+ void *key,
+ dbus_bool_t create_if_not_found,
+ DBusHashIter *iter);
+void* _dbus_hash_table_lookup_string (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_two_strings (DBusHashTable *table,
+ const char *key);
+void* _dbus_hash_table_lookup_int (DBusHashTable *table,
+ int key);
+void* _dbus_hash_table_lookup_pointer (DBusHashTable *table,
+ void *key);
+void* _dbus_hash_table_lookup_ulong (DBusHashTable *table,
+ unsigned long key);
+dbus_bool_t _dbus_hash_table_remove_string (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_two_strings (DBusHashTable *table,
+ const char *key);
+dbus_bool_t _dbus_hash_table_remove_int (DBusHashTable *table,
+ int key);
+dbus_bool_t _dbus_hash_table_remove_pointer (DBusHashTable *table,
+ void *key);
+dbus_bool_t _dbus_hash_table_remove_ulong (DBusHashTable *table,
+ unsigned long key);
+dbus_bool_t _dbus_hash_table_insert_string (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_two_strings (DBusHashTable *table,
+ char *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_int (DBusHashTable *table,
+ int key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_pointer (DBusHashTable *table,
+ void *key,
+ void *value);
+dbus_bool_t _dbus_hash_table_insert_ulong (DBusHashTable *table,
+ unsigned long key,
+ void *value);
+int _dbus_hash_table_get_n_entries (DBusHashTable *table);
/* Preallocation */
typedef struct DBusPreallocatedHash DBusPreallocatedHash;
Index: dbus-internals.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- dbus-internals.c 9 Jun 2003 22:09:34 -0000 1.30
+++ dbus-internals.c 30 Sep 2003 02:32:52 -0000 1.31
@@ -248,7 +248,7 @@
char*
_dbus_strdup (const char *str)
{
- int len;
+ size_t len;
char *copy;
if (str == NULL)
@@ -266,6 +266,29 @@
}
/**
+ * Duplicates a block of memory. Returns
+ * #NULL on failure.
+ *
+ * @param mem memory to copy
+ * @param n_bytes number of bytes to copy
+ * @returns the copy
+ */
+void*
+_dbus_memdup (const void *mem,
+ size_t n_bytes)
+{
+ void *copy;
+
+ copy = dbus_malloc (n_bytes);
+ if (copy == NULL)
+ return NULL;
+
+ memcpy (copy, mem, n_bytes);
+
+ return copy;
+}
+
+/**
* Duplicates a string array. Result may be freed with
* dbus_free_string_array(). Returns #NULL if memory allocation fails.
* If the array to be duplicated is #NULL, returns #NULL.
@@ -366,7 +389,40 @@
}
}
+/**
+ * Returns a string describing the given name.
+ *
+ * @param header_field the field to describe
+ * @returns a constant string describing the field
+ */
+const char *
+_dbus_header_field_to_string (int header_field)
+{
+ switch (header_field)
+ {
+ case DBUS_HEADER_FIELD_INVALID:
+ return "invalid";
+ case DBUS_HEADER_FIELD_PATH:
+ return "path";
+ case DBUS_HEADER_FIELD_INTERFACE:
+ return "interface";
+ case DBUS_HEADER_FIELD_MEMBER:
+ return "member";
+ case DBUS_HEADER_FIELD_ERROR_NAME:
+ return "error-name";
+ case DBUS_HEADER_FIELD_REPLY_SERIAL:
+ return "reply-serial";
+ case DBUS_HEADER_FIELD_SERVICE:
+ return "service";
+ case DBUS_HEADER_FIELD_SENDER_SERVICE:
+ return "sender-service";
+ default:
+ return "unknown";
+ }
+}
+
#ifndef DBUS_DISABLE_CHECKS
+/** String used in _dbus_return_if_fail macro */
const char _dbus_return_if_fail_warning_format[] =
"Arguments to %s were incorrect, assertion \"%s\" failed in file %s line %d.\n"
"This is normally a bug in some application using the D-BUS library.\n";
Index: dbus-internals.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- dbus-internals.h 22 Jun 2003 20:46:17 -0000 1.36
+++ dbus-internals.h 30 Sep 2003 02:32:52 -0000 1.37
@@ -144,6 +144,8 @@
((void*)_DBUS_ALIGN_VALUE(this, boundary))
char* _dbus_strdup (const char *str);
+void* _dbus_memdup (const void *mem,
+ size_t n_bytes);
dbus_bool_t _dbus_string_array_contains (const char **array,
const char *str);
char** _dbus_dup_string_array (const char **array);
@@ -182,7 +184,8 @@
int len);
-const char* _dbus_type_to_string (int type);
+const char* _dbus_type_to_string (int type);
+const char* _dbus_header_field_to_string (int header_field);
extern const char _dbus_no_memory_message[];
#define _DBUS_SET_OOM(error) dbus_set_error ((error), DBUS_ERROR_NO_MEMORY, _dbus_no_memory_message)
@@ -228,10 +231,10 @@
_DBUS_DECLARE_GLOBAL_LOCK (list);
_DBUS_DECLARE_GLOBAL_LOCK (connection_slots);
+_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);
_DBUS_DECLARE_GLOBAL_LOCK (server_slots);
_DBUS_DECLARE_GLOBAL_LOCK (message_slots);
_DBUS_DECLARE_GLOBAL_LOCK (atomic);
-_DBUS_DECLARE_GLOBAL_LOCK (message_handler);
_DBUS_DECLARE_GLOBAL_LOCK (bus);
_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);
_DBUS_DECLARE_GLOBAL_LOCK (system_users);
Index: dbus-keyring.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-keyring.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-keyring.c 5 May 2003 03:13:35 -0000 1.18
+++ dbus-keyring.c 30 Sep 2003 02:32:52 -0000 1.19
@@ -85,6 +85,9 @@
#define MAX_KEYS_IN_FILE 256
#endif
+/**
+ * A single key from the cookie file
+ */
typedef struct
{
dbus_int32_t id; /**< identifier used to refer to the key */
Index: dbus-mainloop.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-mainloop.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-mainloop.c 28 Jun 2003 22:56:27 -0000 1.12
+++ dbus-mainloop.c 30 Sep 2003 02:32:52 -0000 1.13
@@ -23,10 +23,12 @@
#include "dbus-mainloop.h"
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
#include <dbus/dbus-list.h>
#include <dbus/dbus-sysdeps.h>
-#define MAINLOOP_SPEW 1
+#define MAINLOOP_SPEW 0
struct DBusLoop
{
@@ -876,3 +878,4 @@
_dbus_sleep_milliseconds (_dbus_get_oom_wait ());
}
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
Index: dbus-mainloop.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-mainloop.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- dbus-mainloop.h 10 Apr 2003 05:12:19 -0000 1.3
+++ dbus-mainloop.h 30 Sep 2003 02:32:52 -0000 1.4
@@ -24,6 +24,8 @@
#ifndef DBUS_MAINLOOP_H
#define DBUS_MAINLOOP_H
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
#include <dbus/dbus.h>
typedef struct DBusLoop DBusLoop;
@@ -68,4 +70,7 @@
int _dbus_get_oom_wait (void);
void _dbus_wait_for_memory (void);
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
#endif /* DBUS_MAINLOOP_H */
+
Index: dbus-marshal.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- dbus-marshal.c 28 Jun 2003 23:03:26 -0000 1.41
+++ dbus-marshal.c 30 Sep 2003 02:32:52 -0000 1.42
@@ -73,13 +73,17 @@
}
#endif /* !DBUS_HAVE_INT64 */
+/**
+ * Union used to manipulate 8 bytes as if they
+ * were various types.
+ */
typedef union
{
#ifdef DBUS_HAVE_INT64
- dbus_int64_t s;
- dbus_uint64_t u;
+ dbus_int64_t s; /**< 64-bit integer */
+ dbus_uint64_t u; /**< 64-bit unsinged integer */
#endif
- double d;
+ double d; /**< double */
} DBusOctets8;
static DBusOctets8
@@ -98,7 +102,8 @@
r.u = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
#else
r.d = *(double*)data;
- swap_bytes (&r, sizeof (r));
+ if (byte_order != DBUS_COMPILER_BYTE_ORDER)
+ swap_bytes ((unsigned char*) &r, sizeof (r));
#endif
return r;
@@ -390,6 +395,10 @@
* an existing string or the wrong length will be deleted
* and replaced with the new string.
*
+ * Note: no attempt is made by this function to re-align
+ * any data which has been already marshalled after this
+ * string. Use with caution.
+ *
* @param str the string to write the marshalled string to
* @param offset the byte offset where string should be written
* @param byte_order the byte order to use
@@ -423,6 +432,30 @@
return TRUE;
}
+/**
+ * Sets the existing marshaled object path at the given offset to a new
+ * value. The given offset must point to an existing object path or this
+ * function doesn't make sense.
+ *
+ * @todo implement this function
+ *
+ * @param str the string to write the marshalled path to
+ * @param offset the byte offset where path should be written
+ * @param byte_order the byte order to use
+ * @param path the new path
+ * @param path_len number of elements in the path
+ */
+void
+_dbus_marshal_set_object_path (DBusString *str,
+ int byte_order,
+ int offset,
+ const char **path,
+ int path_len)
+{
+
+ /* FIXME */
+}
+
static dbus_bool_t
marshal_4_octets (DBusString *str,
int byte_order,
@@ -682,7 +715,7 @@
#ifdef DBUS_HAVE_INT64
*((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
#else
- swap_bytes (d, 8);
+ swap_bytes ((unsigned char*) d, 8);
#endif
d += 8;
}
@@ -844,6 +877,58 @@
return FALSE;
}
+/**
+ * Marshals an object path value.
+ *
+ * @param str the string to append the marshalled value to
+ * @param byte_order the byte order to use
+ * @param path the path
+ * @param path_len length of the path
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_marshal_object_path (DBusString *str,
+ int byte_order,
+ const char **path,
+ int path_len)
+{
+ int array_start, old_string_len;
+ int i;
+
+ old_string_len = _dbus_string_get_length (str);
+
+ /* Set the length to 0 temporarily */
+ if (!_dbus_marshal_uint32 (str, byte_order, 0))
+ goto nomem;
+
+ array_start = _dbus_string_get_length (str);
+
+ i = 0;
+ while (i < path_len)
+ {
+ if (!_dbus_string_append_byte (str, '/'))
+ goto nomem;
+
+ if (!_dbus_string_append (str, path[0]))
+ goto nomem;
+
+ ++i;
+ }
+
+ /* Write the length now that we know it */
+ _dbus_marshal_set_uint32 (str, byte_order,
+ _DBUS_ALIGN_VALUE (old_string_len, sizeof(dbus_uint32_t)),
+ _dbus_string_get_length (str) - array_start);
+
+ return TRUE;
+
+ nomem:
+ /* Restore the previous length */
+ _dbus_string_set_length (str, old_string_len);
+
+ return FALSE;
+}
+
static dbus_uint32_t
demarshal_4_octets (const DBusString *str,
int byte_order,
@@ -1174,7 +1259,7 @@
#ifdef DBUS_HAVE_INT64
retval[i].u = DBUS_UINT64_SWAP_LE_BE (retval[i].u);
#else
- swap_bytes (&retval[i], 8);
+ swap_bytes ((unsigned char *) &retval[i], 8);
#endif
}
}
@@ -1393,6 +1478,105 @@
return FALSE;
}
+/** Set to 1 to get a bunch of spew about disassembling the path string */
+#define VERBOSE_DECOMPOSE 0
+
+/**
+ * Demarshals an object path. A path of just "/" is
+ * represented as an empty vector of strings.
+ *
+ * @param str the string containing the data
+ * @param byte_order the byte order
+ * @param pos the position in the string
+ * @param new_pos the new position of the string
+ * @param path address to store new object path
+ * @param path_len length of stored path
+ */
+dbus_bool_t
+_dbus_demarshal_object_path (const DBusString *str,
+ int byte_order,
+ int pos,
+ int *new_pos,
+ char ***path,
+ int *path_len)
+{
+ int len;
+ char **retval;
+ const char *data;
+ int n_components;
+ int i, j, comp;
+
+ len = _dbus_demarshal_uint32 (str, byte_order, pos, &pos);
+ data = _dbus_string_get_const_data_len (str, pos, len + 1);
+ _dbus_assert (data != NULL);
+
+#if VERBOSE_DECOMPOSE
+ _dbus_verbose ("Decomposing path \"%s\"\n",
+ data);
+#endif
+
+ n_components = 0;
+ 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;
+ i = 0;
+ while (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;
+
+ if (new_pos)
+ *new_pos = pos + len + 1;
+
+ return TRUE;
+}
+
/**
* Returns the position right after the end of an argument. PERFORMS
* NO VALIDATION WHATSOEVER. The message must have been previously
@@ -1435,32 +1619,18 @@
break;
case DBUS_TYPE_INT32:
- *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int32_t)) + sizeof (dbus_int32_t);
-
- break;
-
case DBUS_TYPE_UINT32:
- *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint32_t)) + sizeof (dbus_uint32_t);
-
+ *end_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
break;
-#ifdef DBUS_HAVE_INT64
case DBUS_TYPE_INT64:
- *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_int64_t)) + sizeof (dbus_int64_t);
-
- break;
-
case DBUS_TYPE_UINT64:
- *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (dbus_uint64_t)) + sizeof (dbus_uint64_t);
-
- break;
-#endif /* DBUS_HAVE_INT64 */
-
case DBUS_TYPE_DOUBLE:
- *end_pos = _DBUS_ALIGN_VALUE (pos, sizeof (double)) + sizeof (double);
-
+
+ *end_pos = _DBUS_ALIGN_VALUE (pos, 8) + 8;
break;
+ case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
{
int len;
@@ -1664,6 +1834,7 @@
case DBUS_TYPE_NIL:
break;
+ case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
case DBUS_TYPE_NAMED:
case DBUS_TYPE_ARRAY:
@@ -1744,10 +1915,6 @@
* returns #TRUE if a valid arg begins at "pos"
*
* @todo security: need to audit this function.
- *
- * @todo For array types that can't be invalid, we should not
- * walk the whole array validating it. e.g. just skip all the
- * int values in an int array.
*
* @param str a string
* @param byte_order the byte order to use
@@ -1842,21 +2009,7 @@
break;
case DBUS_TYPE_INT64:
- case DBUS_TYPE_UINT64:
- {
- int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
-
- if (!_dbus_string_validate_nul (str, pos,
- align_8 - pos))
- {
- _dbus_verbose ("int64/uint64 alignment padding not initialized to nul\n");
- return FALSE;
- }
-
- *end_pos = align_8 + 8;
- }
- break;
-
+ case DBUS_TYPE_UINT64:
case DBUS_TYPE_DOUBLE:
{
int align_8 = _DBUS_ALIGN_VALUE (pos, 8);
@@ -1866,7 +2019,7 @@
if (!_dbus_string_validate_nul (str, pos,
align_8 - pos))
{
- _dbus_verbose ("double alignment padding not initialized to nul\n");
+ _dbus_verbose ("double/int64/uint64/objid alignment padding not initialized to nul\n");
return FALSE;
}
@@ -1874,6 +2027,7 @@
}
break;
+ case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_STRING:
{
int len;
@@ -1887,6 +2041,12 @@
if (!validate_string (str, pos, len, end_pos))
return FALSE;
+
+ if (type == DBUS_TYPE_OBJECT_PATH)
+ {
+ if (!_dbus_string_validate_path (str, pos, len))
+ return FALSE;
+ }
}
break;
@@ -2478,7 +2638,6 @@
s = _dbus_demarshal_string (&str, DBUS_BIG_ENDIAN, 0, NULL);
_dbus_assert (strcmp (s, "Hello") == 0);
dbus_free (s);
-
_dbus_string_free (&str);
Index: dbus-marshal.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-marshal.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dbus-marshal.h 23 Apr 2003 03:33:52 -0000 1.17
+++ dbus-marshal.h 30 Sep 2003 02:32:52 -0000 1.18
@@ -152,11 +152,17 @@
int offset,
dbus_uint64_t value);
#endif /* DBUS_HAVE_INT64 */
-dbus_bool_t _dbus_marshal_set_string (DBusString *str,
- int byte_order,
- int offset,
- const DBusString *value,
- int len);
+
+dbus_bool_t _dbus_marshal_set_string (DBusString *str,
+ int byte_order,
+ int offset,
+ const DBusString *value,
+ int len);
+void _dbus_marshal_set_object_path (DBusString *str,
+ int byte_order,
+ int offset,
+ const char **path,
+ int path_len);
dbus_bool_t _dbus_marshal_int32 (DBusString *str,
int byte_order,
@@ -208,6 +214,11 @@
int byte_order,
const char **value,
int len);
+dbus_bool_t _dbus_marshal_object_path (DBusString *str,
+ int byte_order,
+ const char **path,
+ int path_len);
+
double _dbus_demarshal_double (const DBusString *str,
int byte_order,
int pos,
@@ -278,9 +289,12 @@
int *new_pos,
char ***array,
int *array_len);
-
-
-
+dbus_bool_t _dbus_demarshal_object_path (const DBusString *str,
+ int byte_order,
+ int pos,
+ int *new_pos,
+ char ***path,
+ int *path_len);
dbus_bool_t _dbus_marshal_get_arg_end_pos (const DBusString *str,
int byte_order,
Index: dbus-md5.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-md5.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-md5.h 19 Feb 2003 03:18:54 -0000 1.1
+++ dbus-md5.h 30 Sep 2003 02:32:52 -0000 1.2
@@ -31,11 +31,14 @@
typedef struct DBusMD5Context DBusMD5Context;
+/**
+ * A context used to store the state of the MD5 algorithm
+ */
struct DBusMD5Context
{
- dbus_uint32_t count[2]; /* message length in bits, lsw first */
- dbus_uint32_t abcd[4]; /* digest buffer */
- unsigned char buf[64]; /* accumulate block */
+ dbus_uint32_t count[2]; /**< message length in bits, lsw first */
+ dbus_uint32_t abcd[4]; /**< digest buffer */
+ unsigned char buf[64]; /**< accumulate block */
};
void _dbus_md5_init (DBusMD5Context *context);
Index: dbus-message-builder.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message-builder.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-message-builder.c 1 Jul 2003 20:21:35 -0000 1.18
+++ dbus-message-builder.c 30 Sep 2003 02:32:53 -0000 1.19
@@ -40,9 +40,12 @@
* @{
*/
+/**
+ * Saved length
+ */
typedef struct
{
- DBusString name;
+ DBusString name; /**< Name of the length */
int start; /**< Calculate length since here */
int length; /**< length to write */
int offset; /**< where to write it into the data */
@@ -265,6 +268,73 @@
return TRUE;
}
+static int
+message_type_from_string (const DBusString *str,
+ int start)
+{
+ const char *s;
+
+ s = _dbus_string_get_const_data_len (str, start,
+ _dbus_string_get_length (str) - start);
+
+ if (strncmp (s, "method_call", strlen ("method_call")) == 0)
+ return DBUS_MESSAGE_TYPE_METHOD_CALL;
+ else if (strncmp (s, "method_return", strlen ("method_return")) == 0)
+ return DBUS_MESSAGE_TYPE_METHOD_RETURN;
+ else if (strncmp (s, "signal", strlen ("signal")) == 0)
+ return DBUS_MESSAGE_TYPE_SIGNAL;
+ else if (strncmp (s, "error", strlen ("error")) == 0)
+ return DBUS_MESSAGE_TYPE_ERROR;
+ else if (strncmp (s, "invalid", strlen ("invalid")) == 0)
+ return DBUS_MESSAGE_TYPE_INVALID;
+ else
+ return -1;
+}
+
+static dbus_bool_t
+append_string_field (DBusString *dest,
+ int endian,
+ int field,
+ int type,
+ const char *value)
+{
+ int len;
+
+ if (!_dbus_string_append_byte (dest, field))
+ {
+ _dbus_warn ("couldn't append field name byte\n");
+ return FALSE;
+ }
+
+ if (!_dbus_string_append_byte (dest, type))
+ {
+ _dbus_warn ("could not append typecode byte\n");
+ return FALSE;
+ }
+
+ len = strlen (value);
+
+ if (!_dbus_marshal_uint32 (dest, endian, len))
+ {
+ _dbus_warn ("couldn't append string length\n");
+ return FALSE;
+ }
+
+ if (!_dbus_string_append (dest, value))
+ {
+ _dbus_warn ("couldn't append field value\n");
+ return FALSE;
+ }
+
+ if (!_dbus_string_append_byte (dest, 0))
+ {
+ _dbus_warn ("couldn't append string nul term\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/**
* Reads the given filename, which should be in "message description
* language" (look at some examples), and builds up the message data
@@ -274,7 +344,8 @@
*
* The file format is:
* @code
- * VALID_HEADER normal header; byte order, padding, header len, body len, serial
+ * VALID_HEADER <type> normal header; byte order, type, padding, header len, body len, serial
+ * REQUIRED_FIELDS add required fields with placeholder values
* BIG_ENDIAN switch to big endian
* LITTLE_ENDIAN switch to little endian
* OPPOSITE_ENDIAN switch to opposite endian
@@ -286,7 +357,7 @@
* (or if no START_LENGTH, absolute length)
* LENGTH <name> inserts the saved length of the same name
* CHOP <N> chops last N bytes off the data
- * FIELD_NAME <abcd> inserts 4-byte field name
+ * HEADER_FIELD <fieldname> inserts a header field name byte
* TYPE <typename> inserts a typecode byte
* @endcode
*
@@ -299,6 +370,7 @@
* UINT64 <N> marshals a UINT64
* DOUBLE <N> marshals a double
* STRING 'Foo' marshals a string
+ * OBJECT_PATH '/foo/bar' marshals an object path
* BYTE_ARRAY { 'a', 3, 4, 5, 6} marshals a BYTE array
* BOOLEAN_ARRAY { false, true, false} marshals a BOOLEAN array
* INT32_ARRAY { 3, 4, 5, 6} marshals an INT32 array
@@ -386,6 +458,13 @@
{
int i;
DBusString name;
+ int message_type;
+
+ if (_dbus_string_get_length (&line) < (int) strlen ("VALID_HEADER "))
+ {
+ _dbus_warn ("no args to VALID_HEADER\n");
+ goto parse_failed;
+ }
if (!_dbus_string_append_byte (dest, endian))
{
@@ -393,8 +472,22 @@
goto parse_failed;
}
+ message_type = message_type_from_string (&line,
+ strlen ("VALID_HEADER "));
+ if (message_type < 0)
+ {
+ _dbus_warn ("VALID_HEADER not followed by space then known message type\n");
+ goto parse_failed;
+ }
+
+ if (!_dbus_string_append_byte (dest, message_type))
+ {
+ _dbus_warn ("could not append message type\n");
+ goto parse_failed;
+ }
+
i = 0;
- while (i < 3)
+ while (i < 2)
{
if (!_dbus_string_append_byte (dest, '\0'))
{
@@ -424,6 +517,25 @@
}
}
else if (_dbus_string_starts_with_c_str (&line,
+ "REQUIRED_FIELDS"))
+ {
+ if (!append_string_field (dest, endian,
+ DBUS_HEADER_FIELD_INTERFACE,
+ DBUS_TYPE_STRING,
+ "org.freedesktop.BlahBlahInterface"))
+ goto parse_failed;
+ if (!append_string_field (dest, endian,
+ DBUS_HEADER_FIELD_MEMBER,
+ DBUS_TYPE_STRING,
+ "BlahBlahMethod"))
+ goto parse_failed;
+ if (!append_string_field (dest, endian,
+ DBUS_HEADER_FIELD_PATH,
+ DBUS_TYPE_OBJECT_PATH,
+ "/blah/blah/path"))
+ goto parse_failed;
+ }
+ else if (_dbus_string_starts_with_c_str (&line,
"BIG_ENDIAN"))
{
endian = DBUS_BIG_ENDIAN;
@@ -561,25 +673,42 @@
PERFORM_UNALIGN (dest);
}
else if (_dbus_string_starts_with_c_str (&line,
- "FIELD_NAME"))
+ "HEADER_FIELD"))
{
+ int field;
+
_dbus_string_delete_first_word (&line);
- if (_dbus_string_get_length (&line) != 4)
+ if (_dbus_string_starts_with_c_str (&line, "INVALID"))
+ field = DBUS_HEADER_FIELD_INVALID;
+ else if (_dbus_string_starts_with_c_str (&line, "PATH"))
+ field = DBUS_HEADER_FIELD_PATH;
+ else if (_dbus_string_starts_with_c_str (&line, "INTERFACE"))
+ field = DBUS_HEADER_FIELD_INTERFACE;
+ else if (_dbus_string_starts_with_c_str (&line, "MEMBER"))
+ field = DBUS_HEADER_FIELD_MEMBER;
+ else if (_dbus_string_starts_with_c_str (&line, "ERROR_NAME"))
+ field = DBUS_HEADER_FIELD_ERROR_NAME;
+ else if (_dbus_string_starts_with_c_str (&line, "REPLY_SERIAL"))
+ field = DBUS_HEADER_FIELD_REPLY_SERIAL;
+ else if (_dbus_string_starts_with_c_str (&line, "SERVICE"))
+ field = DBUS_HEADER_FIELD_SERVICE;
+ else if (_dbus_string_starts_with_c_str (&line, "SENDER_SERVICE"))
+ field = DBUS_HEADER_FIELD_SENDER_SERVICE;
+ else if (_dbus_string_starts_with_c_str (&line, "UNKNOWN"))
+ field = 22; /* random unknown header field */
+ else
{
- _dbus_warn ("Field name must be four characters not \"%s\"\n",
- _dbus_string_get_const_data (&line));
+ _dbus_warn ("%s is not a valid header field name\n",
+ _dbus_string_get_const_data (&line));
goto parse_failed;
}
- if (unalign)
- unalign = FALSE;
- else
- _dbus_string_align_length (dest, 4);
-
- if (!_dbus_string_copy (&line, 0, dest,
- _dbus_string_get_length (dest)))
- goto parse_failed;
+ if (!_dbus_string_append_byte (dest, field))
+ {
+ _dbus_warn ("could not append header field name byte\n");
+ goto parse_failed;
+ }
}
else if (_dbus_string_starts_with_c_str (&line,
"TYPE"))
@@ -604,6 +733,8 @@
code = DBUS_TYPE_DOUBLE;
else if (_dbus_string_starts_with_c_str (&line, "STRING"))
code = DBUS_TYPE_STRING;
+ else if (_dbus_string_starts_with_c_str (&line, "OBJECT_PATH"))
+ code = DBUS_TYPE_OBJECT_PATH;
else if (_dbus_string_starts_with_c_str (&line, "NAMED"))
code = DBUS_TYPE_NAMED;
else if (_dbus_string_starts_with_c_str (&line, "ARRAY"))
@@ -1226,6 +1357,36 @@
PERFORM_UNALIGN (dest);
}
+ else if (_dbus_string_starts_with_c_str (&line,
+ "OBJECT_PATH"))
+ {
+ SAVE_FOR_UNALIGN (dest, 4);
+ int size_offset;
+ int old_len;
+
+ _dbus_string_delete_first_word (&line);
+
+ size_offset = _dbus_string_get_length (dest);
+ size_offset = _DBUS_ALIGN_VALUE (size_offset, 4);
+ if (!_dbus_marshal_uint32 (dest, endian, 0))
+ {
+ _dbus_warn ("Failed to append string size\n");
+ goto parse_failed;
+ }
+
+ old_len = _dbus_string_get_length (dest);
+ if (!append_quoted_string (dest, &line, 0, NULL))
+ {
+ _dbus_warn ("Failed to append quoted string\n");
+ goto parse_failed;
+ }
+
+ _dbus_marshal_set_uint32 (dest, endian, size_offset,
+ /* subtract 1 for nul */
+ _dbus_string_get_length (dest) - old_len - 1);
+
+ PERFORM_UNALIGN (dest);
+ }
else
goto parse_failed;
Index: dbus-message.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -u -d -r1.103 -r1.104
--- dbus-message.c 23 Jul 2003 15:11:39 -0000 1.103
+++ dbus-message.c 30 Sep 2003 02:32:53 -0000 1.104
@@ -42,37 +42,31 @@
* @{
*/
-enum
-{
- FIELD_HEADER_LENGTH,
- FIELD_BODY_LENGTH,
- FIELD_CLIENT_SERIAL,
- FIELD_NAME,
- FIELD_SERVICE,
- FIELD_SENDER,
- FIELD_REPLY_SERIAL,
-
- FIELD_LAST
-};
-
-static dbus_bool_t field_is_named[FIELD_LAST] =
-{
- FALSE, /* FIELD_HEADER_LENGTH */
- FALSE, /* FIELD_BODY_LENGTH */
- FALSE, /* FIELD_CLIENT_SERIAL */
- TRUE, /* FIELD_NAME */
- TRUE, /* FIELD_SERVICE */
- TRUE, /* FIELD_SENDER */
- TRUE /* FIELD_REPLY_SERIAL */
-};
-
+/**
+ * Cached information about a header field in the message
+ */
typedef struct
{
- int offset; /**< Offset to start of field (location of name of field
- * for named fields)
- */
+ int name_offset; /**< Offset to name of field */
+ int value_offset; /**< Offset to value of field */
} HeaderField;
+/** Offset to byte order from start of header */
+#define BYTE_ORDER_OFFSET 0
+/** Offset to type from start of header */
+#define TYPE_OFFSET 1
+/** Offset to flags from start of header */
+#define FLAGS_OFFSET 2
+/** Offset to version from start of header */
+#define VERSION_OFFSET 3
+/** Offset to header length from start of header */
+#define HEADER_LENGTH_OFFSET 4
+/** Offset to body length from start of header */
+#define BODY_LENGTH_OFFSET 8
+/** Offset to client serial from start of header */
+#define CLIENT_SERIAL_OFFSET 12
+
+
/**
* @brief Internals of DBusMessage
*
@@ -89,9 +83,9 @@
* independently realloc it.
*/
- HeaderField header_fields[FIELD_LAST]; /**< Track the location
- * of each field in "header"
- */
+ HeaderField header_fields[DBUS_HEADER_FIELD_LAST + 1]; /**< Track the location
+ * of each field in "header"
+ */
dbus_uint32_t client_serial; /**< Cached client serial value for speed */
dbus_uint32_t reply_serial; /**< Cached reply serial value for speed */
@@ -188,26 +182,6 @@
return TRUE;
}
-static void
-adjust_field_offsets (DBusMessage *message,
- int offsets_after,
- int delta)
-{
- int i;
-
- if (delta == 0)
- return;
-
- i = 0;
- while (i < FIELD_LAST)
- {
- if (message->header_fields[i].offset > offsets_after)
- message->header_fields[i].offset += delta;
-
- ++i;
- }
-}
-
#ifdef DBUS_BUILD_TESTS
/* tests-only until it's actually used */
static dbus_int32_t
@@ -216,9 +190,9 @@
{
int offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
- offset = message->header_fields[field].offset;
+ offset = message->header_fields[field].value_offset;
if (offset < 0)
return -1; /* useless if -1 is a valid value of course */
@@ -236,9 +210,9 @@
{
int offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
- offset = message->header_fields[field].offset;
+ offset = message->header_fields[field].value_offset;
if (offset < 0)
return -1; /* useless if -1 is a valid value of course */
@@ -257,9 +231,9 @@
int offset;
const char *data;
- offset = message->header_fields[field].offset;
+ offset = message->header_fields[field].value_offset;
- _dbus_assert (field < FIELD_LAST);
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
if (offset < 0)
return NULL;
@@ -280,25 +254,45 @@
return data + (offset + 4);
}
+/* returns FALSE if no memory, TRUE with NULL path if no field */
+static dbus_bool_t
+get_path_field_decomposed (DBusMessage *message,
+ int field,
+ char ***path)
+{
+ int offset;
+
+ offset = message->header_fields[field].value_offset;
+
+ _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
+
+ if (offset < 0)
+ {
+ *path = NULL;
+ return TRUE;
+ }
+
+ return _dbus_demarshal_object_path (&message->header,
+ message->byte_order,
+ offset,
+ NULL,
+ path, NULL);
+}
+
#ifdef DBUS_BUILD_TESTS
static dbus_bool_t
append_int_field (DBusMessage *message,
int field,
- const char *name,
int value)
{
- int orig_len;
-
_dbus_assert (!message->locked);
clear_header_padding (message);
- orig_len = _dbus_string_get_length (&message->header);
-
- if (!_dbus_string_align_length (&message->header, 4))
- goto failed;
+ message->header_fields[field].name_offset =
+ _dbus_string_get_length (&message->header);
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_INT32))
@@ -307,7 +301,7 @@
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- message->header_fields[field].offset =
+ message->header_fields[field].value_offset =
_dbus_string_get_length (&message->header);
if (!_dbus_marshal_int32 (&message->header, message->byte_order,
@@ -320,8 +314,10 @@
return TRUE;
failed:
- message->header_fields[field].offset = -1;
- _dbus_string_set_length (&message->header, orig_len);
+ _dbus_string_set_length (&message->header,
+ message->header_fields[field].name_offset);
+ message->header_fields[field].name_offset = -1;
+ message->header_fields[field].value_offset = -1;
/* this must succeed because it was allocated on function entry and
* DBusString doesn't ever realloc smaller
@@ -335,21 +331,16 @@
static dbus_bool_t
append_uint_field (DBusMessage *message,
int field,
- const char *name,
- int value)
+ int value)
{
- int orig_len;
-
_dbus_assert (!message->locked);
clear_header_padding (message);
- orig_len = _dbus_string_get_length (&message->header);
-
- if (!_dbus_string_align_length (&message->header, 4))
- goto failed;
+ message->header_fields[field].name_offset =
+ _dbus_string_get_length (&message->header);
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_UINT32))
@@ -358,7 +349,7 @@
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- message->header_fields[field].offset =
+ message->header_fields[field].value_offset =
_dbus_string_get_length (&message->header);
if (!_dbus_marshal_uint32 (&message->header, message->byte_order,
@@ -371,8 +362,10 @@
return TRUE;
failed:
- message->header_fields[field].offset = -1;
- _dbus_string_set_length (&message->header, orig_len);
+ _dbus_string_set_length (&message->header,
+ message->header_fields[field].name_offset);
+ message->header_fields[field].name_offset = -1;
+ message->header_fields[field].value_offset = -1;
/* this must succeed because it was allocated on function entry and
* DBusString doesn't ever realloc smaller
@@ -385,30 +378,26 @@
static dbus_bool_t
append_string_field (DBusMessage *message,
int field,
- const char *name,
+ int type,
const char *value)
{
- int orig_len;
-
_dbus_assert (!message->locked);
clear_header_padding (message);
- orig_len = _dbus_string_get_length (&message->header);
-
- if (!_dbus_string_align_length (&message->header, 4))
- goto failed;
+ message->header_fields[field].name_offset =
+ _dbus_string_get_length (&message->header);
- if (!_dbus_string_append_len (&message->header, name, 4))
+ if (!_dbus_string_append_byte (&message->header, field))
goto failed;
- if (!_dbus_string_append_byte (&message->header, DBUS_TYPE_STRING))
+ if (!_dbus_string_append_byte (&message->header, type))
goto failed;
if (!_dbus_string_align_length (&message->header, 4))
goto failed;
- message->header_fields[field].offset =
+ message->header_fields[field].value_offset =
_dbus_string_get_length (&message->header);
if (!_dbus_marshal_string (&message->header, message->byte_order,
@@ -421,8 +410,10 @@
return TRUE;
failed:
- message->header_fields[field].offset = -1;
- _dbus_string_set_length (&message->header, orig_len);
+ _dbus_string_set_length (&message->header,
+ message->header_fields[field].name_offset);
+ message->header_fields[field].name_offset = -1;
+ message->header_fields[field].value_offset = -1;
/* this must succeed because it was allocated on function entry and
* DBusString doesn't ever realloc smaller
@@ -433,73 +424,205 @@
return FALSE;
}
-#ifdef DBUS_BUILD_TESTS
-/* This isn't used, but building it when tests are enabled just to
- * keep it compiling if we need it in future
- */
-static void
-delete_int_or_uint_field (DBusMessage *message,
- int field)
+static int
+get_next_field (DBusMessage *message,
+ int field)
{
- int offset = message->header_fields[field].offset;
+ int offset = message->header_fields[field].name_offset;
+ int closest;
+ int i;
+ int retval = DBUS_HEADER_FIELD_INVALID;
- _dbus_assert (!message->locked);
- _dbus_assert (field_is_named[field]);
-
- if (offset < 0)
- return;
+ i = 0;
+ closest = _DBUS_INT_MAX;
+ while (i < DBUS_HEADER_FIELD_LAST)
+ {
+ if (message->header_fields[i].name_offset > offset &&
+ message->header_fields[i].name_offset < closest)
+ {
+ closest = message->header_fields[i].name_offset;
+ retval = i;
+ }
+ ++i;
+ }
- clear_header_padding (message);
-
- /* The field typecode and name take up 8 bytes */
- _dbus_string_delete (&message->header,
- offset - 8,
- 12);
+ return retval;
+}
- message->header_fields[field].offset = -1;
-
- adjust_field_offsets (message,
- offset - 8,
- - 12);
+static dbus_bool_t
+re_align_field_recurse (DBusMessage *message,
+ int field,
+ int offset)
+{
+ int old_name_offset = message->header_fields[field].name_offset;
+ int old_value_offset = message->header_fields[field].value_offset;
+ int prev_padding, padding, delta;
+ int type;
+ int next_field;
+ int pos = offset;
- append_header_padding (message);
+ /* padding between the typecode byte and the value itself */
+ prev_padding = old_value_offset - old_name_offset + 2;
+
+ pos++;
+ type = _dbus_string_get_byte (&message->header, pos);
+
+ pos++;
+ switch (type)
+ {
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ padding = 0;
+ break;
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ padding = _DBUS_ALIGN_VALUE (pos, 4) - pos;
+ break;
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ case DBUS_TYPE_DOUBLE:
+ padding = _DBUS_ALIGN_VALUE (pos, 8) - pos;
+ break;
+ case DBUS_TYPE_NAMED:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_DICT:
+ _dbus_assert_not_reached ("no defined header fields may contain a named, array or dict value");
+ break;
+ case DBUS_TYPE_INVALID:
+ default:
+ _dbus_assert_not_reached ("invalid type in marshalled header");
+ break;
+ }
+
+ delta = padding - prev_padding;
+ if (delta > 0)
+ {
+ if (!_dbus_string_insert_bytes (&message->header, pos, delta, 0))
+ return FALSE;
+ }
+ else if (delta < 0)
+ {
+ _dbus_string_delete (&message->header, pos, -delta);
+ }
+
+ next_field = get_next_field (message, field);
+ if (next_field != DBUS_HEADER_FIELD_INVALID)
+ {
+ int next_offset = message->header_fields[next_field].name_offset;
+
+ _dbus_assert (next_offset > 0);
+
+ if (!re_align_field_recurse (message, field,
+ pos + padding + (next_offset - old_value_offset)))
+ goto failed;
+ }
+ else
+ {
+ if (!append_header_padding (message))
+ goto failed;
+ }
+
+ message->header_fields[field].name_offset = offset;
+ message->header_fields[field].value_offset = pos + padding;
+
+ return TRUE;
+
+ failed:
+ if (delta > 0)
+ {
+ _dbus_string_delete (&message->header, pos, delta);
+ }
+ else if (delta < 0)
+ {
+ /* this must succeed because it was allocated on function entry and
+ * DBusString doesn't ever realloc smaller
+ */
+ _dbus_string_insert_bytes (&message->header, pos, -delta, 0);
+ }
+
+ return FALSE;
}
-#endif
-static void
-delete_string_field (DBusMessage *message,
- int field)
+static dbus_bool_t
+delete_field (DBusMessage *message,
+ int field)
{
- int offset = message->header_fields[field].offset;
- int len;
- int delete_len;
-
+ int offset = message->header_fields[field].name_offset;
+ int next_field;
+
_dbus_assert (!message->locked);
- _dbus_assert (field_is_named[field]);
if (offset < 0)
- return;
+ return FALSE;
clear_header_padding (message);
-
- get_string_field (message, field, &len);
-
- /* The field typecode and name take up 8 bytes, and the nul
- * termination is 1 bytes, string length integer is 4 bytes
- */
- delete_len = 8 + 4 + 1 + len;
-
- _dbus_string_delete (&message->header,
- offset - 8,
- delete_len);
- message->header_fields[field].offset = -1;
-
- adjust_field_offsets (message,
- offset - 8,
- - delete_len);
+ next_field = get_next_field (message, field);
+ if (next_field == DBUS_HEADER_FIELD_INVALID)
+ {
+ _dbus_string_set_length (&message->header, offset);
- append_header_padding (message);
+ message->header_fields[field].name_offset = -1;
+ message->header_fields[field].value_offset = -1;
+
+ /* this must succeed because it was allocated on function entry and
+ * DBusString doesn't ever realloc smaller
+ */
+ if (!append_header_padding (message))
+ _dbus_assert_not_reached ("failed to reappend header padding");
+
+ return TRUE;
+ }
+ else
+ {
+ DBusString deleted;
+ int next_offset = message->header_fields[next_field].name_offset;
+
+ _dbus_assert (next_offset > 0);
+
+ if (!_dbus_string_init (&deleted))
+ goto failed;
+
+ if (!_dbus_string_move_len (&message->header,
+ offset, next_offset - offset,
+ &deleted, 0))
+ {
+ _dbus_string_free (&deleted);
+ goto failed;
+ }
+
+ /* appends the header padding */
+ if (!re_align_field_recurse (message, next_field, offset))
+ {
+ /* this must succeed because it was allocated on function entry and
+ * DBusString doesn't ever realloc smaller
+ */
+ if (!_dbus_string_copy (&deleted, 0, &message->header, offset))
+ _dbus_assert_not_reached ("failed to revert to original field");
+
+ _dbus_string_free (&deleted);
+ goto failed;
+ }
+
+ _dbus_string_free (&deleted);
+
+ message->header_fields[field].name_offset = -1;
+ message->header_fields[field].value_offset = -1;
+
+ return TRUE;
+
+ failed:
+ /* this must succeed because it was allocated on function entry and
+ * DBusString doesn't ever realloc smaller
+ */
+ if (!append_header_padding (message))
+ _dbus_assert_not_reached ("failed to reappend header padding");
+
+ return FALSE;
+ }
}
#ifdef DBUS_BUILD_TESTS
@@ -508,20 +631,14 @@
int field,
int value)
{
- int offset = message->header_fields[field].offset;
+ int offset = message->header_fields[field].value_offset;
_dbus_assert (!message->locked);
if (offset < 0)
{
/* need to append the field */
-
- switch (field)
- {
- default:
- _dbus_assert_not_reached ("appending an int field we don't support appending");
- return FALSE;
- }
+ return append_int_field (message, field, value);
}
else
{
@@ -539,24 +656,14 @@
int field,
dbus_uint32_t value)
{
- int offset = message->header_fields[field].offset;
+ int offset = message->header_fields[field].value_offset;
_dbus_assert (!message->locked);
if (offset < 0)
{
/* need to append the field */
-
- switch (field)
- {
- case FIELD_REPLY_SERIAL:
- return append_uint_field (message, field,
- DBUS_HEADER_FIELD_REPLY,
- value);
- default:
- _dbus_assert_not_reached ("appending a uint field we don't support appending");
- return FALSE;
- }
+ return append_uint_field (message, field, value);
}
else
{
@@ -571,9 +678,10 @@
static dbus_bool_t
set_string_field (DBusMessage *message,
int field,
+ int type,
const char *value)
{
- int offset = message->header_fields[field].offset;
+ int offset = message->header_fields[field].value_offset;
_dbus_assert (!message->locked);
_dbus_assert (value != NULL);
@@ -581,48 +689,59 @@
if (offset < 0)
{
/* need to append the field */
-
- switch (field)
- {
- case FIELD_SENDER:
- return append_string_field (message, field,
- DBUS_HEADER_FIELD_SENDER,
- value);
- default:
- _dbus_assert_not_reached ("appending a string field we don't support appending");
- return FALSE;
- }
+ return append_string_field (message, field, type, value);
}
else
{
DBusString v;
- int old_len;
- int new_len;
+ char *old_value;
+ int next_field;
+ int next_offset;
int len;
clear_header_padding (message);
-
- old_len = _dbus_string_get_length (&message->header);
+
+ old_value = _dbus_demarshal_string (&message->header,
+ message->byte_order,
+ offset,
+ &next_offset);
+ if (!old_value)
+ goto failed;
len = strlen (value);
-
+
_dbus_string_init_const_len (&v, value,
len + 1); /* include nul */
if (!_dbus_marshal_set_string (&message->header,
message->byte_order,
- offset, &v,
- len))
- goto failed;
-
- new_len = _dbus_string_get_length (&message->header);
+ offset, &v, len))
+ {
+ dbus_free (old_value);
+ goto failed;
+ }
- adjust_field_offsets (message,
- offset,
- new_len - old_len);
+ next_field = get_next_field (message, field);
+ if (next_field != DBUS_HEADER_FIELD_INVALID)
+ {
+ /* re-appends the header padding */
+ if (!re_align_field_recurse (message, next_field, next_offset))
+ {
+ len = strlen (old_value);
+
+ _dbus_string_init_const_len (&v, old_value,
+ len + 1); /* include nul */
+ if (!_dbus_marshal_set_string (&message->header,
+ message->byte_order,
+ offset, &v, len))
+ _dbus_assert_not_reached ("failed to revert to original string");
+
+ dbus_free (old_value);
+ goto failed;
+ }
+ }
+
+ dbus_free (old_value);
- if (!append_header_padding (message))
- goto failed;
-
return TRUE;
failed:
@@ -649,9 +768,12 @@
{
_dbus_assert (!message->locked);
_dbus_assert (dbus_message_get_serial (message) == 0);
-
- set_uint_field (message, FIELD_CLIENT_SERIAL,
- serial);
+
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ serial);
+
message->client_serial = serial;
}
@@ -669,7 +791,8 @@
{
_dbus_assert (!message->locked);
- if (set_uint_field (message, FIELD_REPLY_SERIAL,
+ if (set_uint_field (message,
+ DBUS_HEADER_FIELD_REPLY_SERIAL,
reply_serial))
{
message->reply_serial = reply_serial;
@@ -803,14 +926,25 @@
static dbus_bool_t
dbus_message_create_header (DBusMessage *message,
- const char *name,
- const char *service)
+ int type,
+ const char *service,
+ const char *path,
+ const char *interface,
+ const char *member,
+ const char *error_name)
{
unsigned int flags;
+
+ _dbus_assert ((interface && member) ||
+ (error_name) ||
+ !(interface || member || error_name));
if (!_dbus_string_append_byte (&message->header, message->byte_order))
return FALSE;
+ if (!_dbus_string_append_byte (&message->header, type))
+ return FALSE;
+
flags = 0;
if (!_dbus_string_append_byte (&message->header, flags))
return FALSE;
@@ -818,37 +952,61 @@
if (!_dbus_string_append_byte (&message->header, DBUS_MAJOR_PROTOCOL_VERSION))
return FALSE;
- if (!_dbus_string_append_byte (&message->header, 0))
- return FALSE;
-
- message->header_fields[FIELD_HEADER_LENGTH].offset = 4;
if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
return FALSE;
- message->header_fields[FIELD_BODY_LENGTH].offset = 8;
if (!_dbus_marshal_uint32 (&message->header, message->byte_order, 0))
return FALSE;
- message->header_fields[FIELD_CLIENT_SERIAL].offset = 12;
if (!_dbus_marshal_int32 (&message->header, message->byte_order, -1))
return FALSE;
- /* Marshal message service */
+ /* Marshal all the fields (Marshall Fields?) */
+
+ if (path != NULL)
+ {
+ if (!append_string_field (message,
+ DBUS_HEADER_FIELD_PATH,
+ DBUS_TYPE_OBJECT_PATH,
+ path))
+ return FALSE;
+ }
+
if (service != NULL)
{
if (!append_string_field (message,
- FIELD_SERVICE,
DBUS_HEADER_FIELD_SERVICE,
+ DBUS_TYPE_STRING,
service))
return FALSE;
}
- _dbus_assert (name != NULL);
- if (!append_string_field (message,
- FIELD_NAME,
- DBUS_HEADER_FIELD_NAME,
- name))
- return FALSE;
+ if (interface != NULL)
+ {
+ if (!append_string_field (message,
+ DBUS_HEADER_FIELD_INTERFACE,
+ DBUS_TYPE_STRING,
+ interface))
+ return FALSE;
+ }
+
+ if (member != NULL)
+ {
+ if (!append_string_field (message,
+ DBUS_HEADER_FIELD_MEMBER,
+ DBUS_TYPE_STRING,
+ member))
+ return FALSE;
+ }
+
+ if (error_name != NULL)
+ {
+ if (!append_string_field (message,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ DBUS_TYPE_STRING,
+ error_name))
+ return FALSE;
+ }
return TRUE;
}
@@ -868,13 +1026,15 @@
if (!message->locked)
{
/* Fill in our lengths */
- set_uint_field (message,
- FIELD_HEADER_LENGTH,
- _dbus_string_get_length (&message->header));
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ HEADER_LENGTH_OFFSET,
+ _dbus_string_get_length (&message->header));
- set_uint_field (message,
- FIELD_BODY_LENGTH,
- _dbus_string_get_length (&message->body));
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ BODY_LENGTH_OFFSET,
+ _dbus_string_get_length (&message->body));
message->locked = TRUE;
}
@@ -920,9 +1080,10 @@
_dbus_data_slot_list_init (&message->slot_list);
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
- message->header_fields[i].offset = -1;
+ message->header_fields[i].name_offset = -1;
+ message->header_fields[i].value_offset = -1;
++i;
}
@@ -942,31 +1103,71 @@
return message;
}
-
/**
- * Constructs a new message. Returns #NULL if memory can't be
- * allocated for the message. The service may be #NULL in which case
- * no service is set; this is appropriate when using D-BUS in a
- * peer-to-peer context (no message bus).
+ * Constructs a new message of the given message type.
+ * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL,
+ * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth.
*
- * @param name name of the message
- * @param destination_service service that the message should be sent to or #NULL
+ * @param message_type type of message
+ * @returns new message or #NULL If no memory
+ */
+DBusMessage*
+dbus_message_new (int message_type)
+{
+ DBusMessage *message;
+
+ _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
+
+ message = dbus_message_new_empty_header ();
+ if (message == NULL)
+ return NULL;
+
+ if (!dbus_message_create_header (message,
+ message_type,
+ NULL, NULL, NULL, NULL, NULL))
+ {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ return message;
+}
+
+/**
+ * Constructs a new message to invoke a method on a remote
+ * object. Returns #NULL if memory can't be allocated for the
+ * message. The service may be #NULL in which case no service is set;
+ * this is appropriate when using D-BUS in a peer-to-peer context (no
+ * message bus). The interface may be #NULL, which means that
+ * if multiple methods with the given name exist it is undefined
+ * which one will be invoked.
+ *
+ * @param service service that the message should be sent to or #NULL
+ * @param path object path the message should be sent to
+ * @param interface interface to invoke method on
+ * @param method method to invoke
+ *
* @returns a new DBusMessage, free with dbus_message_unref()
* @see dbus_message_unref()
*/
DBusMessage*
-dbus_message_new (const char *name,
- const char *destination_service)
+dbus_message_new_method_call (const char *service,
+ const char *path,
+ const char *interface,
+ const char *method)
{
DBusMessage *message;
- _dbus_return_val_if_fail (name != NULL, NULL);
+ _dbus_return_val_if_fail (path != NULL, NULL);
+ _dbus_return_val_if_fail (method != NULL, NULL);
message = dbus_message_new_empty_header ();
if (message == NULL)
return NULL;
- if (!dbus_message_create_header (message, name, destination_service))
+ if (!dbus_message_create_header (message,
+ DBUS_MESSAGE_TYPE_METHOD_CALL,
+ service, path, interface, method, NULL))
{
dbus_message_unref (message);
return NULL;
@@ -976,37 +1177,42 @@
}
/**
- * Constructs a message that is a reply to some other
- * message. Returns #NULL if memory can't be allocated
- * for the message.
+ * Constructs a message that is a reply to a method call. Returns
+ * #NULL if memory can't be allocated for the message.
*
- * @param original_message the message which the created
+ * @param method_call the message which the created
* message is a reply to.
* @returns a new DBusMessage, free with dbus_message_unref()
- * @see dbus_message_new(), dbus_message_unref()
+ * @see dbus_message_new_method_call(), dbus_message_unref()
*/
DBusMessage*
-dbus_message_new_reply (DBusMessage *original_message)
+dbus_message_new_method_return (DBusMessage *method_call)
{
DBusMessage *message;
- const char *sender, *name;
-
- _dbus_return_val_if_fail (original_message != NULL, NULL);
-
- sender = get_string_field (original_message,
- FIELD_SENDER, NULL);
- name = get_string_field (original_message,
- FIELD_NAME, NULL);
+ const char *sender;
- /* sender is allowed to be null here in peer-to-peer case */
+ _dbus_return_val_if_fail (method_call != NULL, NULL);
- message = dbus_message_new (name, sender);
+ sender = get_string_field (method_call,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
+ /* sender is allowed to be null here in peer-to-peer case */
+
+ message = dbus_message_new_empty_header ();
if (message == NULL)
return NULL;
+
+ if (!dbus_message_create_header (message,
+ DBUS_MESSAGE_TYPE_METHOD_RETURN,
+ sender, NULL, NULL, NULL, NULL))
+ {
+ dbus_message_unref (message);
+ return NULL;
+ }
if (!dbus_message_set_reply_serial (message,
- dbus_message_get_serial (original_message)))
+ dbus_message_get_serial (method_call)))
{
dbus_message_unref (message);
return NULL;
@@ -1016,40 +1222,86 @@
}
/**
+ * Constructs a new message representing a signal emission. Returns
+ * #NULL if memory can't be allocated for the message.
+ * A signal is identified by its originating interface, and
+ * the name of the signal.
+ *
+ * @param path the path to the object emitting the signal
+ * @param interface the interface the signal is emitted from
+ * @param name name of the signal
+ * @returns a new DBusMessage, free with dbus_message_unref()
+ * @see dbus_message_unref()
+ */
+DBusMessage*
+dbus_message_new_signal (const char *path,
+ const char *interface,
+ const char *name)
+{
+ DBusMessage *message;
+
+ _dbus_return_val_if_fail (path != NULL, NULL);
+ _dbus_return_val_if_fail (interface != NULL, NULL);
+ _dbus_return_val_if_fail (name != NULL, NULL);
+
+ message = dbus_message_new_empty_header ();
+ if (message == NULL)
+ return NULL;
+
+ if (!dbus_message_create_header (message,
+ DBUS_MESSAGE_TYPE_SIGNAL,
+ NULL, path, interface, name, NULL))
+ {
+ dbus_message_unref (message);
+ return NULL;
+ }
+
+ return message;
+}
+
+/**
* Creates a new message that is an error reply to a certain message.
+ * Error replies are possible in response to method calls primarily.
*
- * @param original_message the original message
+ * @param reply_to the original message
* @param error_name the error name
* @param error_message the error message string or #NULL for none
* @returns a new error message
*/
DBusMessage*
-dbus_message_new_error_reply (DBusMessage *original_message,
- const char *error_name,
- const char *error_message)
+dbus_message_new_error (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_message)
{
DBusMessage *message;
const char *sender;
DBusMessageIter iter;
- _dbus_return_val_if_fail (original_message != NULL, NULL);
+ _dbus_return_val_if_fail (reply_to != NULL, NULL);
_dbus_return_val_if_fail (error_name != NULL, NULL);
- sender = get_string_field (original_message,
- FIELD_SENDER, NULL);
+ sender = get_string_field (reply_to,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
/* sender may be NULL for non-message-bus case or
* when the message bus is dealing with an unregistered
* connection.
*/
-
- message = dbus_message_new (error_name, sender);
-
+ message = dbus_message_new_empty_header ();
if (message == NULL)
return NULL;
+
+ if (!dbus_message_create_header (message,
+ DBUS_MESSAGE_TYPE_ERROR,
+ sender, NULL, NULL, NULL, error_name))
+ {
+ dbus_message_unref (message);
+ return NULL;
+ }
if (!dbus_message_set_reply_serial (message,
- dbus_message_get_serial (original_message)))
+ dbus_message_get_serial (reply_to)))
{
dbus_message_unref (message);
return NULL;
@@ -1064,8 +1316,6 @@
return NULL;
}
}
-
- dbus_message_set_is_error (message, TRUE);
return message;
}
@@ -1129,9 +1379,9 @@
return NULL;
}
- for (i = 0; i < FIELD_LAST; i++)
+ for (i = 0; i <= DBUS_HEADER_FIELD_LAST; i++)
{
- retval->header_fields[i].offset = message->header_fields[i].offset;
+ retval->header_fields[i] = message->header_fields[i];
}
return retval;
@@ -1201,17 +1451,268 @@
}
/**
- * Gets the name of a message.
+ * Gets the type of a message. Types include
+ * DBUS_MESSAGE_TYPE_METHOD_CALL, DBUS_MESSAGE_TYPE_METHOD_RETURN,
+ * DBUS_MESSAGE_TYPE_ERROR, DBUS_MESSAGE_TYPE_SIGNAL, but other types
+ * are allowed and all code must silently ignore messages of unknown
+ * type. DBUS_MESSAGE_TYPE_INVALID will never be returned, however.
+ *
*
* @param message the message
- * @returns the message name (should not be freed)
+ * @returns the type of the message
+ */
+int
+dbus_message_get_type (DBusMessage *message)
+{
+ int type;
+
+ type = _dbus_string_get_byte (&message->header, 1);
+ _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
+
+ return type;
+}
+
+/**
+ * Sets the object path this message is being sent to (for
+ * DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being
+ * emitted from (for DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @param object_path the path
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_path (DBusMessage *message,
+ const char *object_path)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (object_path == NULL)
+ {
+ delete_field (message, DBUS_HEADER_FIELD_PATH);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_PATH,
+ DBUS_TYPE_OBJECT_PATH,
+ object_path);
+ }
+}
+
+/**
+ * Gets the object path this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
+ * from (for DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @returns the path (should not be freed)
*/
const char*
-dbus_message_get_name (DBusMessage *message)
+dbus_message_get_path (DBusMessage *message)
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_NAME, NULL);
+ return get_string_field (message, DBUS_HEADER_FIELD_PATH, NULL);
+}
+
+/**
+ * Gets the object path this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
+ * from (for DBUS_MESSAGE_TYPE_SIGNAL) in a decomposed
+ * format (one array element per path component).
+ * Free the returned array with dbus_free_string_array().
+ *
+ * An empty but non-NULL path array means the path "/".
+ * So the path "/foo/bar" becomes { "foo", "bar", NULL }
+ * and the path "/" becomes { NULL }.
+ *
+ * @param message the message
+ * @param path place to store allocated array of path components; #NULL set here if no path field exists
+ * @returns #FALSE if no memory to allocate the array
+ */
+dbus_bool_t
+dbus_message_get_path_decomposed (DBusMessage *message,
+ char ***path)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (path != NULL, FALSE);
+
+ return get_path_field_decomposed (message,
+ DBUS_HEADER_FIELD_PATH,
+ path);
+}
+
+/**
+ * Sets the interface this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or
+ * the interface a signal is being emitted from
+ * (for DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @param interface the interface
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_interface (DBusMessage *message,
+ const char *interface)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (interface == NULL)
+ {
+ delete_field (message, DBUS_HEADER_FIELD_INTERFACE);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_INTERFACE,
+ DBUS_TYPE_STRING,
+ interface);
+ }
+}
+
+/**
+ * Gets the interface this message is being sent to
+ * (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted
+ * from (for DBUS_MESSAGE_TYPE_SIGNAL).
+ * The interface name is fully-qualified (namespaced).
+ *
+ * @param message the message
+ * @returns the message interface (should not be freed)
+ */
+const char*
+dbus_message_get_interface (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return get_string_field (message, DBUS_HEADER_FIELD_INTERFACE, NULL);
+}
+
+/**
+ * Sets the interface member being invoked
+ * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
+ * (DBUS_MESSAGE_TYPE_SIGNAL).
+ * The interface name is fully-qualified (namespaced).
+ *
+ * @param message the message
+ * @param member the member
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_member (DBusMessage *message,
+ const char *member)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (member == NULL)
+ {
+ delete_field (message, DBUS_HEADER_FIELD_MEMBER);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_MEMBER,
+ DBUS_TYPE_STRING,
+ member);
+ }
+}
+
+/**
+ * Gets the interface member being invoked
+ * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted
+ * (DBUS_MESSAGE_TYPE_SIGNAL).
+ *
+ * @param message the message
+ * @returns the member name (should not be freed)
+ */
+const char*
+dbus_message_get_member (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_MEMBER,
+ NULL);
+}
+
+/**
+ * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
+ * The name is fully-qualified (namespaced).
+ *
+ * @param message the message
+ * @param error_name the name
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_error_name (DBusMessage *message,
+ const char *error_name)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (error_name == NULL)
+ {
+ delete_field (message, DBUS_HEADER_FIELD_ERROR_NAME);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ DBUS_TYPE_STRING,
+ error_name);
+ }
+}
+
+/**
+ * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only).
+ *
+ * @param message the message
+ * @returns the error name (should not be freed)
+ */
+const char*
+dbus_message_get_error_name (DBusMessage *message)
+{
+ _dbus_return_val_if_fail (message != NULL, NULL);
+
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_ERROR_NAME,
+ NULL);
+}
+
+/**
+ * Sets the message's destination service.
+ *
+ * @param message the message
+ * @param destination the destination service name
+ * @returns #FALSE if not enough memory
+ */
+dbus_bool_t
+dbus_message_set_destination (DBusMessage *message,
+ const char *destination)
+{
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (!message->locked, FALSE);
+
+ if (destination == NULL)
+ {
+ delete_field (message, DBUS_HEADER_FIELD_SERVICE);
+ return TRUE;
+ }
+ else
+ {
+ return set_string_field (message,
+ DBUS_HEADER_FIELD_SERVICE,
+ DBUS_TYPE_STRING,
+ destination);
+ }
}
/**
@@ -1225,7 +1726,9 @@
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_SERVICE, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_SERVICE,
+ NULL);
}
/**
@@ -3677,58 +4180,62 @@
if (sender == NULL)
{
- delete_string_field (message, FIELD_SENDER);
+ delete_field (message, DBUS_HEADER_FIELD_SENDER_SERVICE);
return TRUE;
}
else
{
return set_string_field (message,
- FIELD_SENDER,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ DBUS_TYPE_STRING,
sender);
}
}
/**
- * Sets a flag indicating that the message is an error reply
- * message, i.e. an "exception" rather than a normal response.
+ * Sets a flag indicating that the message does not want a reply; if
+ * this flag is set, the other end of the connection may (but is not
+ * required to) optimize by not sending method return or error
+ * replies. If this flag is set, there is no way to know whether the
+ * message successfully arrived at the remote end.
*
* @param message the message
- * @param is_error_reply #TRUE if this is an error message.
+ * @param no_reply #TRUE if no reply is desired
*/
void
-dbus_message_set_is_error (DBusMessage *message,
- dbus_bool_t is_error_reply)
+dbus_message_set_no_reply (DBusMessage *message,
+ dbus_bool_t no_reply)
{
char *header;
_dbus_return_if_fail (message != NULL);
_dbus_return_if_fail (!message->locked);
- header = _dbus_string_get_data_len (&message->header, 1, 1);
+ header = _dbus_string_get_data_len (&message->header, FLAGS_OFFSET, 1);
- if (is_error_reply)
- *header |= DBUS_HEADER_FLAG_ERROR;
+ if (no_reply)
+ *header |= DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
else
- *header &= ~DBUS_HEADER_FLAG_ERROR;
+ *header &= ~DBUS_HEADER_FLAG_NO_REPLY_EXPECTED;
}
/**
- * Returns #TRUE if the message is an error
- * reply to some previous message we sent.
+ * Returns #TRUE if the message does not expect
+ * a reply.
*
* @param message the message
- * @returns #TRUE if the message is an error
+ * @returns #TRUE if the message sender isn't waiting for a reply
*/
dbus_bool_t
-dbus_message_get_is_error (DBusMessage *message)
+dbus_message_get_no_reply (DBusMessage *message)
{
const char *header;
_dbus_return_val_if_fail (message != NULL, FALSE);
- header = _dbus_string_get_const_data_len (&message->header, 1, 1);
+ header = _dbus_string_get_const_data_len (&message->header, FLAGS_OFFSET, 1);
- return (*header & DBUS_HEADER_FLAG_ERROR) != 0;
+ return (*header & DBUS_HEADER_FLAG_NO_REPLY_EXPECTED) != 0;
}
/**
@@ -3743,31 +4250,120 @@
{
_dbus_return_val_if_fail (message != NULL, NULL);
- return get_string_field (message, FIELD_SENDER, NULL);
+ return get_string_field (message,
+ DBUS_HEADER_FIELD_SENDER_SERVICE,
+ NULL);
+}
+
+static dbus_bool_t
+_dbus_message_has_type_interface_member (DBusMessage *message,
+ int type,
+ const char *interface,
+ const char *method)
+{
+ const char *n;
+
+ _dbus_assert (message != NULL);
+ _dbus_assert (interface != NULL);
+ _dbus_assert (method != NULL);
+
+ if (dbus_message_get_type (message) != type)
+ return FALSE;
+
+ /* Optimize by checking the short method name first
+ * instead of the longer interface name
+ */
+
+ n = dbus_message_get_member (message);
+
+ if (n && strcmp (n, method) == 0)
+ {
+ n = dbus_message_get_interface (message);
+
+ if (n && strcmp (n, interface) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
}
/**
- * Checks whether the message has the given name.
- * If the message has no name or has a different
- * name, returns #FALSE.
+ * Checks whether the message is a method call with the given
+ * interface and member fields. If the message is not
+ * #DBUS_MESSAGE_TYPE_METHOD_CALL, or has a different interface or member field,
+ * returns #FALSE.
*
* @param message the message
- * @param name the name to check (must not be #NULL)
+ * @param interface the name to check (must not be #NULL)
+ * @param method the name to check (must not be #NULL)
*
- * @returns #TRUE if the message has the given name
+ * @returns #TRUE if the message is the specified method call
*/
dbus_bool_t
-dbus_message_has_name (DBusMessage *message,
- const char *name)
+dbus_message_is_method_call (DBusMessage *message,
+ const char *interface,
+ const char *method)
{
- const char *n;
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (interface != NULL, FALSE);
+ _dbus_return_val_if_fail (method != NULL, FALSE);
+ return _dbus_message_has_type_interface_member (message,
+ DBUS_MESSAGE_TYPE_METHOD_CALL,
+ interface, method);
+}
+
+/**
+ * Checks whether the message is a signal with the given
+ * interface and member fields. If the message is not
+ * #DBUS_MESSAGE_TYPE_SIGNAL, or has a different interface or member field,
+ * returns #FALSE.
+ *
+ * @param message the message
+ * @param interface the name to check (must not be #NULL)
+ * @param signal_name the name to check (must not be #NULL)
+ *
+ * @returns #TRUE if the message is the specified signal
+ */
+dbus_bool_t
+dbus_message_is_signal (DBusMessage *message,
+ const char *interface,
+ const char *signal_name)
+{
_dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (name != NULL, FALSE);
+ _dbus_return_val_if_fail (interface != NULL, FALSE);
+ _dbus_return_val_if_fail (signal_name != NULL, FALSE);
+
+ return _dbus_message_has_type_interface_member (message,
+ DBUS_MESSAGE_TYPE_SIGNAL,
+ interface, signal_name);
+}
+
+/**
+ * Checks whether the message is an error reply with the given error
+ * name. If the message is not #DBUS_MESSAGE_TYPE_ERROR, or has a
+ * different name, returns #FALSE.
+ *
+ * @param message the message
+ * @param error_name the name to check (must not be #NULL)
+ *
+ * @returns #TRUE if the message is the specified error
+ */
+dbus_bool_t
+dbus_message_is_error (DBusMessage *message,
+ const char *error_name)
+{
+ const char *n;
- n = dbus_message_get_name (message);
+ _dbus_return_val_if_fail (message != NULL, FALSE);
+ _dbus_return_val_if_fail (error_name != NULL, FALSE);
- if (n && strcmp (n, name) == 0)
+ if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
+ return FALSE;
+
+ n = dbus_message_get_error_name (message);
+
+ if (n && strcmp (n, error_name) == 0)
return TRUE;
else
return FALSE;
@@ -3833,7 +4429,7 @@
/**
* Sets a #DBusError based on the contents of the given
* message. The error is only set if the message
- * is an error message, as in dbus_message_get_is_error().
+ * is an error message, as in DBUS_MESSAGE_TYPE_ERROR.
* The name of the error is set to the name of the message,
* and the error message is set to the first argument
* if the argument exists and is a string.
@@ -3856,7 +4452,7 @@
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_error_is_set (error, FALSE);
- if (!dbus_message_get_is_error (message))
+ if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
return FALSE;
str = NULL;
@@ -3864,7 +4460,7 @@
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID);
- dbus_set_error (error, dbus_message_get_name (message),
+ dbus_set_error (error, dbus_message_get_error_name (message),
str ? "%s" : NULL, str);
dbus_free (str);
@@ -4039,51 +4635,31 @@
*/
#define DBUS_MINIMUM_HEADER_SIZE 16
-/** Pack four characters as in "abcd" into a uint32 */
-#define FOUR_CHARS_TO_UINT32(a, b, c, d) \
- ((((dbus_uint32_t)a) << 24) | \
- (((dbus_uint32_t)b) << 16) | \
- (((dbus_uint32_t)c) << 8) | \
- ((dbus_uint32_t)d))
-
-/** DBUS_HEADER_FIELD_NAME packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_NAME_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('n', 'a', 'm', 'e')
-
-/** DBUS_HEADER_FIELD_SERVICE packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_SERVICE_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('s', 'r', 'v', 'c')
-
-/** DBUS_HEADER_FIELD_REPLY packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_REPLY_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('r', 'p', 'l', 'y')
-
-/** DBUS_HEADER_FIELD_SENDER Packed into a dbus_uint32_t */
-#define DBUS_HEADER_FIELD_SENDER_AS_UINT32 \
- FOUR_CHARS_TO_UINT32 ('s', 'n', 'd', 'r')
-
static dbus_bool_t
decode_string_field (const DBusString *data,
- HeaderField fields[FIELD_LAST],
+ int field,
+ HeaderField *header_field,
+ DBusString *field_data,
int pos,
- int type,
- int field,
- const char *field_name)
+ int type)
{
- DBusString tmp;
int string_data_pos;
+
+ _dbus_assert (header_field != NULL);
+ _dbus_assert (field_data != NULL);
- if (fields[field].offset >= 0)
+ if (header_field->name_offset >= 0)
{
_dbus_verbose ("%s field provided twice\n",
- field_name);
+ _dbus_header_field_to_string (field));
return FALSE;
}
if (type != DBUS_TYPE_STRING)
{
_dbus_verbose ("%s field has wrong type %s\n",
- field_name, _dbus_type_to_string (type));
+ _dbus_header_field_to_string (field),
+ _dbus_type_to_string (type));
return FALSE;
}
@@ -4094,40 +4670,16 @@
string_data_pos = _DBUS_ALIGN_VALUE (pos, 4) + 4;
_dbus_assert (string_data_pos < _dbus_string_get_length (data));
- _dbus_string_init_const (&tmp,
+ _dbus_string_init_const (field_data,
_dbus_string_get_const_data (data) + string_data_pos);
- if (field == FIELD_NAME)
- {
- if (!_dbus_string_validate_name (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
-
- if (_dbus_string_starts_with_c_str (&tmp,
- DBUS_NAMESPACE_LOCAL_MESSAGE))
- {
- _dbus_verbose ("Message is in the local namespace\n");
- return FALSE;
- }
- }
- else
- {
- if (!_dbus_string_validate_service (&tmp, 0, _dbus_string_get_length (&tmp)))
- {
- _dbus_verbose ("%s field has invalid content \"%s\"\n",
- field_name, _dbus_string_get_const_data (&tmp));
- return FALSE;
- }
- }
-
- fields[field].offset = _DBUS_ALIGN_VALUE (pos, 4);
+ header_field->name_offset = pos;
+ header_field->value_offset = _DBUS_ALIGN_VALUE (pos, 4);
#if 0
- _dbus_verbose ("Found field %s name at offset %d\n",
- field_name, fields[field].offset);
+ _dbus_verbose ("Found field %s at offset %d\n",
+ _dbus_header_field_to_string (field),
+ header_field->value_offset);
#endif
return TRUE;
@@ -4137,47 +4689,38 @@
decode_header_data (const DBusString *data,
int header_len,
int byte_order,
- HeaderField fields[FIELD_LAST],
+ int message_type,
+ HeaderField fields[DBUS_HEADER_FIELD_LAST + 1],
int *message_padding)
{
- const char *field;
+ DBusString field_data;
int pos, new_pos;
int i;
+ int field;
int type;
if (header_len < 16)
- return FALSE;
+ {
+ _dbus_verbose ("Header length %d is too short\n", header_len);
+ return FALSE;
+ }
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
- fields[i].offset = -1;
+ fields[i].name_offset = -1;
+ fields[i].value_offset = -1;
++i;
}
- fields[FIELD_HEADER_LENGTH].offset = 4;
- fields[FIELD_BODY_LENGTH].offset = 8;
- fields[FIELD_CLIENT_SERIAL].offset = 12;
-
- /* Now handle the named fields. A real named field is at least 4
- * bytes for the name, plus a type code (1 byte) plus padding. So
- * if we have less than 8 bytes left, it must be alignment padding,
- * not a field. While >= 8 bytes can't be entirely alignment
- * padding.
- */
pos = 16;
- while ((pos + 7) < header_len)
+ while (pos < header_len)
{
- pos = _DBUS_ALIGN_VALUE (pos, 4);
-
- if ((pos + 4) > header_len)
- return FALSE;
-
- field =_dbus_string_get_const_data_len (data, pos, 4);
- pos += 4;
+ field = _dbus_string_get_byte (data, pos);
+ if (field == DBUS_HEADER_FIELD_INVALID)
+ break; /* Must be padding */
+ pos++;
- _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
-
if (!_dbus_marshal_validate_type (data, pos, &type, &pos))
{
_dbus_verbose ("Failed to validate type of named header field\n");
@@ -4196,51 +4739,146 @@
return FALSE;
}
- switch (DBUS_UINT32_FROM_BE (*(int*)field))
+ switch (field)
{
- case DBUS_HEADER_FIELD_SERVICE_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_SERVICE,
- DBUS_HEADER_FIELD_SERVICE))
+ case DBUS_HEADER_FIELD_SERVICE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_service (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("service field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_NAME_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_NAME,
- DBUS_HEADER_FIELD_NAME))
+ case DBUS_HEADER_FIELD_INTERFACE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_interface (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("interface field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
+
+ if (_dbus_string_equal_c_str (&field_data,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL))
+ {
+ _dbus_verbose ("Message is on the local interface\n");
+ return FALSE;
+ }
break;
- case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
- if (!decode_string_field (data, fields, pos, type,
- FIELD_SENDER,
- DBUS_HEADER_FIELD_SENDER))
+ case DBUS_HEADER_FIELD_MEMBER:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
+ return FALSE;
+
+ if (!_dbus_string_validate_member (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("member field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
+ break;
+
+ case DBUS_HEADER_FIELD_ERROR_NAME:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
+ return FALSE;
+
+ if (!_dbus_string_validate_error_name (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("error-name field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
+ break;
+
+ case DBUS_HEADER_FIELD_SENDER_SERVICE:
+ if (!decode_string_field (data, field, &fields[field],
+ &field_data, pos, type))
return FALSE;
+
+ if (!_dbus_string_validate_service (&field_data, 0,
+ _dbus_string_get_length (&field_data)))
+ {
+ _dbus_verbose ("sender-service field has invalid content \"%s\"\n",
+ _dbus_string_get_const_data (&field_data));
+ return FALSE;
+ }
break;
+
+ case DBUS_HEADER_FIELD_PATH:
+
+ /* Path was already validated as part of standard
+ * type validation, since there's an OBJECT_PATH
+ * type.
+ */
- case DBUS_HEADER_FIELD_REPLY_AS_UINT32:
- if (fields[FIELD_REPLY_SERIAL].offset >= 0)
+ if (fields[field].name_offset >= 0)
{
- _dbus_verbose ("%s field provided twice\n",
- DBUS_HEADER_FIELD_REPLY);
+ _dbus_verbose ("path field provided twice\n");
+ return FALSE;
+ }
+ if (type != DBUS_TYPE_OBJECT_PATH)
+ {
+ _dbus_verbose ("path field has wrong type\n");
+ return FALSE;
+ }
+
+ fields[field].name_offset = pos;
+ fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
+
+ /* No forging signals from the local path */
+ {
+ const char *s;
+ s = _dbus_string_get_const_data_len (data,
+ fields[field].value_offset,
+ _dbus_string_get_length (data) -
+ fields[field].value_offset);
+ if (strcmp (s, DBUS_PATH_ORG_FREEDESKTOP_LOCAL) == 0)
+ {
+ _dbus_verbose ("Message is on the local path\n");
+ return FALSE;
+ }
+ }
+
+ _dbus_verbose ("Found path at offset %d\n",
+ fields[field].value_offset);
+ break;
+
+ case DBUS_HEADER_FIELD_REPLY_SERIAL:
+ if (fields[field].name_offset >= 0)
+ {
+ _dbus_verbose ("reply field provided twice\n");
return FALSE;
}
if (type != DBUS_TYPE_UINT32)
{
- _dbus_verbose ("%s field has wrong type\n", DBUS_HEADER_FIELD_REPLY);
+ _dbus_verbose ("reply field has wrong type\n");
return FALSE;
}
- fields[FIELD_REPLY_SERIAL].offset = _DBUS_ALIGN_VALUE (pos, 4);
+ fields[field].name_offset = pos;
+ fields[field].value_offset = _DBUS_ALIGN_VALUE (pos, 4);
_dbus_verbose ("Found reply serial at offset %d\n",
- fields[FIELD_REPLY_SERIAL].offset);
+ fields[field].value_offset);
break;
default:
- _dbus_verbose ("Ignoring an unknown header field: %.4s at offset %d\n",
+ _dbus_verbose ("Ignoring an unknown header field: %d at offset %d\n",
field, pos);
}
@@ -4250,7 +4888,11 @@
if (pos < header_len)
{
/* Alignment padding, verify that it's nul */
- _dbus_assert ((header_len - pos) < 8);
+ if ((header_len - pos) >= 8)
+ {
+ _dbus_verbose ("too much header alignment padding\n");
+ return FALSE;
+ }
if (!_dbus_string_validate_nul (data,
pos, (header_len - pos)))
@@ -4260,12 +4902,40 @@
}
}
- /* Name field is mandatory */
- if (fields[FIELD_NAME].offset < 0)
+ /* Depending on message type, enforce presence of certain fields. */
+ switch (message_type)
{
- _dbus_verbose ("No %s field provided\n",
- DBUS_HEADER_FIELD_NAME);
- return FALSE;
+ case DBUS_MESSAGE_TYPE_SIGNAL:
+ case DBUS_MESSAGE_TYPE_METHOD_CALL:
+ if (fields[DBUS_HEADER_FIELD_PATH].value_offset < 0)
+ {
+ _dbus_verbose ("No path field provided\n");
+ return FALSE;
+ }
+ /* FIXME make this optional, only for method calls */
+ if (fields[DBUS_HEADER_FIELD_INTERFACE].value_offset < 0)
+ {
+ _dbus_verbose ("No interface field provided\n");
+ return FALSE;
+ }
+ if (fields[DBUS_HEADER_FIELD_MEMBER].value_offset < 0)
+ {
+ _dbus_verbose ("No member field provided\n");
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ if (fields[DBUS_HEADER_FIELD_ERROR_NAME].value_offset < 0)
+ {
+ _dbus_verbose ("No error-name field provided\n");
+ return FALSE;
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ break;
+ default:
+ /* An unknown type, spec requires us to ignore it */
+ break;
}
if (message_padding)
@@ -4298,6 +4968,13 @@
/**
* Converts buffered data into messages.
*
+ * @todo we need to check that the proper named header fields exist
+ * for each message type.
+ *
+ * @todo If a message has unknown type, we should probably eat it
+ * right here rather than passing it out to applications. However
+ * it's not an error to see messages of unknown type.
+ *
* @param loader the loader.
* @returns #TRUE if we had enough memory to finish.
*/
@@ -4311,22 +4988,22 @@
{
DBusMessage *message;
const char *header_data;
- int byte_order, header_len, body_len, header_padding;
+ int byte_order, message_type, header_len, body_len, header_padding;
dbus_uint32_t header_len_unsigned, body_len_unsigned;
header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
_dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
- if (header_data[2] != DBUS_MAJOR_PROTOCOL_VERSION)
+ if (header_data[VERSION_OFFSET] != DBUS_MAJOR_PROTOCOL_VERSION)
{
_dbus_verbose ("Message has protocol version %d ours is %d\n",
- (int) header_data[2], DBUS_MAJOR_PROTOCOL_VERSION);
+ (int) header_data[VERSION_OFFSET], DBUS_MAJOR_PROTOCOL_VERSION);
loader->corrupted = TRUE;
return TRUE;
}
- byte_order = header_data[0];
+ byte_order = header_data[BYTE_ORDER_OFFSET];
if (byte_order != DBUS_LITTLE_ENDIAN &&
byte_order != DBUS_BIG_ENDIAN)
@@ -4337,6 +5014,18 @@
return TRUE;
}
+ /* Unknown types are ignored, but INVALID is
+ * disallowed
+ */
+ message_type = header_data[TYPE_OFFSET];
+ if (message_type == DBUS_MESSAGE_TYPE_INVALID)
+ {
+ _dbus_verbose ("Message with bad type '%d' received\n",
+ message_type);
+ loader->corrupted = TRUE;
+ return TRUE;
+ }
+
header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
body_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 8);
@@ -4383,14 +5072,16 @@
if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
{
- HeaderField fields[FIELD_LAST];
+ HeaderField fields[DBUS_HEADER_FIELD_LAST + 1];
int i;
int next_arg;
#if 0
_dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
#endif
- if (!decode_header_data (&loader->data, header_len, byte_order,
+ if (!decode_header_data (&loader->data,
+ header_len, byte_order,
+ message_type,
fields, &header_padding))
{
_dbus_verbose ("Header was invalid\n");
@@ -4448,7 +5139,7 @@
/* Copy in the offsets we found */
i = 0;
- while (i < FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
message->header_fields[i] = fields[i];
++i;
@@ -4498,9 +5189,12 @@
* earlier)
*/
message->reply_serial = get_uint_field (message,
- FIELD_REPLY_SERIAL);
- message->client_serial = get_uint_field (message,
- FIELD_CLIENT_SERIAL);
+ DBUS_HEADER_FIELD_REPLY_SERIAL);
+
+ message->client_serial = _dbus_demarshal_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ NULL);
_dbus_verbose ("Loaded message %p\n", message);
}
@@ -5076,8 +5770,10 @@
client_serial = dbus_message_get_serial (message);
/* can't use set_serial due to the assertions at the start of it */
- set_uint_field (message, FIELD_CLIENT_SERIAL,
- client_serial);
+ _dbus_marshal_set_uint32 (&message->header,
+ message->byte_order,
+ CLIENT_SERIAL_OFFSET,
+ client_serial);
if (client_serial != dbus_message_get_serial (message))
{
@@ -5467,7 +6163,7 @@
goto failed;
}
- printf ("Testing:\n");
+ printf ("Testing %s:\n", subdir);
next:
while (_dbus_directory_get_next_file (dir, &filename, &error))
@@ -5499,10 +6195,11 @@
printf (" %s\n",
_dbus_string_get_const_data (&filename));
- _dbus_verbose (" expecting %s\n",
+ _dbus_verbose (" expecting %s for %s\n",
validity == _DBUS_MESSAGE_VALID ? "valid" :
(validity == _DBUS_MESSAGE_INVALID ? "invalid" :
- (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")));
+ (validity == _DBUS_MESSAGE_INCOMPLETE ? "incomplete" : "unknown")),
+ _dbus_string_get_const_data (&filename));
if (! (*function) (&full_path, is_raw, validity, user_data))
{
@@ -5821,26 +6518,37 @@
_dbus_assert (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
- message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
- _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
+ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
+ "/org/freedesktop/TestPath",
+ "Foo.TestInterface",
+ "TestMethod");
+ _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
+ _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
+ "TestMethod"));
_dbus_message_set_serial (message, 1234);
- dbus_message_set_sender (message, "org.foo.bar");
- _dbus_assert (dbus_message_has_sender (message, "org.foo.bar"));
+ /* string length including nul byte not a multiple of 4 */
+ dbus_message_set_sender (message, "org.foo.bar1");
+ _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
+ dbus_message_set_reply_serial (message, 5678);
dbus_message_set_sender (message, NULL);
- _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar"));
+ _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
_dbus_assert (dbus_message_get_serial (message) == 1234);
- _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.Test"));
+ _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
+ _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
- _dbus_assert (dbus_message_get_is_error (message) == FALSE);
- dbus_message_set_is_error (message, TRUE);
- _dbus_assert (dbus_message_get_is_error (message) == TRUE);
- dbus_message_set_is_error (message, FALSE);
- _dbus_assert (dbus_message_get_is_error (message) == FALSE);
+ _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
+ dbus_message_set_no_reply (message, TRUE);
+ _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
+ dbus_message_set_no_reply (message, FALSE);
+ _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
dbus_message_unref (message);
/* Test the vararg functions */
- message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
+ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
+ "/org/freedesktop/TestPath",
+ "Foo.TestInterface",
+ "TestMethod");
_dbus_message_set_serial (message, 1);
dbus_message_append_args (message,
DBUS_TYPE_INT32, -0x12345678,
@@ -5855,10 +6563,12 @@
_DBUS_N_ELEMENTS (our_uint32_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, our_int32_array,
_DBUS_N_ELEMENTS (our_int32_array),
+#ifdef DBUS_HAVE_INT64
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, our_uint64_array,
_DBUS_N_ELEMENTS (our_uint64_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, our_int64_array,
_DBUS_N_ELEMENTS (our_int64_array),
+#endif
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, our_string_array,
_DBUS_N_ELEMENTS (our_string_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, our_double_array,
@@ -5896,15 +6606,24 @@
verify_test_message (copy);
- name1 = dbus_message_get_name (message);
- name2 = dbus_message_get_name (copy);
+ name1 = dbus_message_get_interface (message);
+ name2 = dbus_message_get_interface (copy);
+
+ _dbus_assert (strcmp (name1, name2) == 0);
+
+ name1 = dbus_message_get_member (message);
+ name2 = dbus_message_get_member (copy);
_dbus_assert (strcmp (name1, name2) == 0);
dbus_message_unref (message);
dbus_message_unref (copy);
-
- message = dbus_message_new ("test.Message", "org.freedesktop.DBus.Test");
+
+ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
+ "/org/freedesktop/TestPath",
+ "Foo.TestInterface",
+ "TestMethod");
+
_dbus_message_set_serial (message, 1);
dbus_message_set_reply_serial (message, 0x12345678);
Index: dbus-message.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.h,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- dbus-message.h 22 Jun 2003 20:46:17 -0000 1.42
+++ dbus-message.h 30 Sep 2003 02:32:53 -0000 1.43
@@ -31,6 +31,7 @@
#include <dbus/dbus-types.h>
#include <dbus/dbus-arch-deps.h>
#include <dbus/dbus-memory.h>
+#include <dbus/dbus-errors.h>
#include <stdarg.h>
DBUS_BEGIN_DECLS;
@@ -38,45 +39,74 @@
typedef struct DBusMessage DBusMessage;
typedef struct DBusMessageIter DBusMessageIter;
+/**
+ * DBusMessageIter struct; contains no public fields
+ */
struct DBusMessageIter
-{
- void *dummy1;
- void *dummy2;
- dbus_uint32_t dummy3;
- int dummy4;
- int dummy5;
- int dummy6;
- int dummy7;
- int dummy8;
- int dummy9;
- int dummy10;
- int dummy11;
- int pad1;
- int pad2;
- void *pad3;
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy3; /**< Don't use this */
+ int dummy4; /**< Don't use this */
+ int dummy5; /**< Don't use this */
+ int dummy6; /**< Don't use this */
+ int dummy7; /**< Don't use this */
+ int dummy8; /**< Don't use this */
+ int dummy9; /**< Don't use this */
+ int dummy10; /**< Don't use this */
+ int dummy11; /**< Don't use this */
+ int pad1; /**< Don't use this */
+ int pad2; /**< Don't use this */
+ void *pad3; /**< Don't use this */
};
+DBusMessage* dbus_message_new (int message_type);
+DBusMessage* dbus_message_new_method_call (const char *service,
+ const char *path,
+ const char *interface,
+ const char *method);
+DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
+DBusMessage* dbus_message_new_signal (const char *path,
+ const char *interface,
+ const char *name);
+DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
+ const char *error_name,
+ const char *error_message);
-DBusMessage* dbus_message_new (const char *name,
- const char *destination_service);
-DBusMessage* dbus_message_new_reply (DBusMessage *original_message);
-DBusMessage* dbus_message_new_error_reply (DBusMessage *original_message,
- const char *error_name,
- const char *error_message);
-DBusMessage *dbus_message_copy (const DBusMessage *message);
+DBusMessage *dbus_message_copy (const DBusMessage *message);
void dbus_message_ref (DBusMessage *message);
void dbus_message_unref (DBusMessage *message);
-const char* dbus_message_get_name (DBusMessage *message);
+int dbus_message_get_type (DBusMessage *message);
+dbus_bool_t dbus_message_set_path (DBusMessage *message,
+ const char *object_path);
+const char* dbus_message_get_path (DBusMessage *message);
+dbus_bool_t dbus_message_set_interface (DBusMessage *message,
+ const char *interface);
+const char* dbus_message_get_interface (DBusMessage *message);
+dbus_bool_t dbus_message_set_member (DBusMessage *message,
+ const char *member);
+const char* dbus_message_get_member (DBusMessage *message);
+dbus_bool_t dbus_message_set_error_name (DBusMessage *message,
+ const char *name);
+const char* dbus_message_get_error_name (DBusMessage *message);
+dbus_bool_t dbus_message_set_destination (DBusMessage *message,
+ const char *destination);
const char* dbus_message_get_destination (DBusMessage *message);
dbus_bool_t dbus_message_set_sender (DBusMessage *message,
const char *sender);
const char* dbus_message_get_sender (DBusMessage *message);
-void dbus_message_set_is_error (DBusMessage *message,
- dbus_bool_t is_error_reply);
-dbus_bool_t dbus_message_get_is_error (DBusMessage *message);
-dbus_bool_t dbus_message_has_name (DBusMessage *message,
- const char *name);
+void dbus_message_set_no_reply (DBusMessage *message,
+ dbus_bool_t no_reply);
+dbus_bool_t dbus_message_get_no_reply (DBusMessage *message);
+dbus_bool_t dbus_message_is_method_call (DBusMessage *message,
+ const char *interface,
+ const char *method);
+dbus_bool_t dbus_message_is_signal (DBusMessage *message,
+ const char *interface,
+ const char *signal_name);
+dbus_bool_t dbus_message_is_error (DBusMessage *message,
+ const char *error_name);
dbus_bool_t dbus_message_has_destination (DBusMessage *message,
const char *service);
dbus_bool_t dbus_message_has_sender (DBusMessage *message,
@@ -86,6 +116,9 @@
dbus_uint32_t reply_serial);
dbus_uint32_t dbus_message_get_reply_serial (DBusMessage *message);
+dbus_bool_t dbus_message_get_path_decomposed (DBusMessage *message,
+ char ***path);
+
dbus_bool_t dbus_message_append_args (DBusMessage *message,
int first_arg_type,
...);
Index: dbus-protocol.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-protocol.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- dbus-protocol.h 23 Apr 2003 03:33:52 -0000 1.20
+++ dbus-protocol.h 30 Sep 2003 02:32:53 -0000 1.21
@@ -53,25 +53,54 @@
#define DBUS_TYPE_NAMED 10
#define DBUS_TYPE_ARRAY 11
#define DBUS_TYPE_DICT 12
+#define DBUS_TYPE_OBJECT_PATH 13
+
+#define DBUS_TYPE_LAST DBUS_TYPE_OBJECT_PATH
-#define DBUS_TYPE_LAST DBUS_TYPE_DICT
-
-/* Max length in bytes of a service or message name */
+/* Max length in bytes of a service or interface or member name */
#define DBUS_MAXIMUM_NAME_LENGTH 256
+/* Types of message */
+#define DBUS_MESSAGE_TYPE_INVALID 0
+#define DBUS_MESSAGE_TYPE_METHOD_CALL 1
+#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2
+#define DBUS_MESSAGE_TYPE_ERROR 3
+#define DBUS_MESSAGE_TYPE_SIGNAL 4
+
/* Header flags */
-#define DBUS_HEADER_FLAG_ERROR 0x1
+#define DBUS_HEADER_FLAG_NO_REPLY_EXPECTED 0x1
/* Header fields */
-#define DBUS_HEADER_FIELD_NAME "name"
-#define DBUS_HEADER_FIELD_SERVICE "srvc"
-#define DBUS_HEADER_FIELD_REPLY "rply"
-#define DBUS_HEADER_FIELD_SENDER "sndr"
+#define DBUS_HEADER_FIELD_INVALID 0
+#define DBUS_HEADER_FIELD_PATH 1
+#define DBUS_HEADER_FIELD_INTERFACE 2
+#define DBUS_HEADER_FIELD_MEMBER 3
+#define DBUS_HEADER_FIELD_ERROR_NAME 4
+#define DBUS_HEADER_FIELD_REPLY_SERIAL 5
+#define DBUS_HEADER_FIELD_SERVICE 6
+#define DBUS_HEADER_FIELD_SENDER_SERVICE 7
+#define DBUS_HEADER_FIELD_LAST DBUS_HEADER_FIELD_SENDER_SERVICE
+
/* Services */
-#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
-#define DBUS_SERVICE_BROADCAST "org.freedesktop.DBus.Broadcast"
+#define DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+/* Paths */
+#define DBUS_PATH_ORG_FREEDESKTOP_DBUS "/org/freedesktop/DBus"
+#define DBUS_PATH_ORG_FREEDESKTOP_LOCAL "/org/freedesktop/Local"
+
+/* Interfaces, these #define don't do much other than
+ * catch typos at compile time
+ */
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "org.freedesktop.DBus"
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_INTROSPECTABLE "org.freedesktop.Introspectable"
+
+/* This is a special interface whose methods can only be invoked
+ * by the local implementation (messages from remote apps aren't
+ * allowed to specify this interface).
+ */
+#define DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL "org.freedesktop.Local"
+
/* Service owner flags */
#define DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT 0x1
#define DBUS_SERVICE_FLAG_REPLACE_EXISTING 0x2
@@ -86,24 +115,6 @@
#define DBUS_ACTIVATION_REPLY_ACTIVATED 0x0
#define DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE 0x1
-/* Messages */
-#define DBUS_MESSAGE_ACTIVATE_SERVICE "org.freedesktop.DBus.ActivateService"
-#define DBUS_MESSAGE_SERVICE_EXISTS "org.freedesktop.DBus.ServiceExists"
-#define DBUS_MESSAGE_HELLO "org.freedesktop.DBus.Hello"
-#define DBUS_MESSAGE_LIST_SERVICES "org.freedesktop.DBus.ListServices"
-#define DBUS_MESSAGE_ACQUIRE_SERVICE "org.freedesktop.DBus.AcquireService"
-#define DBUS_MESSAGE_SERVICE_ACQUIRED "org.freedesktop.DBus.ServiceAcquired"
-#define DBUS_MESSAGE_SERVICE_CREATED "org.freedesktop.DBus.ServiceCreated"
-#define DBUS_MESSAGE_SERVICE_DELETED "org.freedesktop.DBus.ServiceDeleted"
-#define DBUS_MESSAGE_SERVICE_LOST "org.freedesktop.DBus.ServiceLost"
-
-
-/* This namespace is reserved for locally-synthesized messages, you can't
- * send messages that have this namespace.
- */
-#define DBUS_NAMESPACE_LOCAL_MESSAGE "org.freedesktop.Local."
-#define DBUS_MESSAGE_LOCAL_DISCONNECT DBUS_NAMESPACE_LOCAL_MESSAGE"Disconnect"
-
#ifdef __cplusplus
}
#endif
Index: dbus-server-debug-pipe.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-debug-pipe.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-server-debug-pipe.c 18 Apr 2003 04:18:57 -0000 1.12
+++ dbus-server-debug-pipe.c 30 Sep 2003 02:32:53 -0000 1.13
@@ -27,6 +27,7 @@
#include "dbus-transport-unix.h"
#include "dbus-connection-internal.h"
#include "dbus-hash.h"
+#include "dbus-string.h"
#ifdef DBUS_BUILD_TESTS
Index: dbus-server-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-protected.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dbus-server-protected.h 18 Apr 2003 04:18:57 -0000 1.10
+++ dbus-server-protected.h 30 Sep 2003 02:32:53 -0000 1.11
@@ -34,6 +34,9 @@
typedef struct DBusServerVTable DBusServerVTable;
+/**
+ * Virtual table to be implemented by all server "subclasses"
+ */
struct DBusServerVTable
{
void (* finalize) (DBusServer *server);
@@ -43,6 +46,9 @@
/**< Disconnect this server. */
};
+/**
+ * Internals of DBusServer object
+ */
struct DBusServer
{
int refcount; /**< Reference count. */
Index: dbus-server-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-unix.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-server-unix.c 4 Jun 2003 05:20:19 -0000 1.18
+++ dbus-server-unix.c 30 Sep 2003 02:32:53 -0000 1.19
@@ -25,6 +25,7 @@
#include "dbus-server-unix.h"
#include "dbus-transport-unix.h"
#include "dbus-connection-internal.h"
+#include "dbus-string.h"
#include <sys/types.h>
#include <unistd.h>
Index: dbus-server.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- dbus-server.c 22 Jun 2003 19:39:47 -0000 1.29
+++ dbus-server.c 30 Sep 2003 02:32:53 -0000 1.30
@@ -23,6 +23,7 @@
#include "dbus-server.h"
#include "dbus-server-unix.h"
+#include "dbus-string.h"
#ifdef DBUS_BUILD_TESTS
#include "dbus-server-debug-pipe.h"
#endif
Index: dbus-sha.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sha.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbus-sha.h 22 Feb 2003 17:29:48 -0000 1.1
+++ dbus-sha.h 30 Sep 2003 02:32:53 -0000 1.2
@@ -31,11 +31,14 @@
typedef struct DBusSHAContext DBusSHAContext;
+/**
+ * Struct storing state of the SHA algorithm
+ */
struct DBusSHAContext
{
dbus_uint32_t digest[5]; /**< Message digest */
dbus_uint32_t count_lo; /**< 64-bit bit count */
- dbus_uint32_t count_hi;
+ dbus_uint32_t count_hi; /**< No clue */
dbus_uint32_t data[16]; /**< SHA data buffer */
};
Index: dbus-spawn.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-spawn.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-spawn.c 11 May 2003 07:59:08 -0000 1.12
+++ dbus-spawn.c 30 Sep 2003 02:32:53 -0000 1.13
@@ -176,28 +176,31 @@
CHILD_PID /* Followed by pid_t */
};
+/**
+ * Babysitter implementation details
+ */
struct DBusBabysitter
{
- int refcount;
+ int refcount; /**< Reference count */
char *executable; /**< executable name to use in error messages */
- int socket_to_babysitter;
- int error_pipe_from_child;
+ int socket_to_babysitter; /**< Connection to the babysitter process */
+ int error_pipe_from_child; /**< Connection to the process that does the exec() */
- pid_t sitter_pid;
- pid_t grandchild_pid;
+ pid_t sitter_pid; /**< PID Of the babysitter */
+ pid_t grandchild_pid; /**< PID of the grandchild */
- DBusWatchList *watches;
+ DBusWatchList *watches; /**< Watches */
- DBusWatch *error_watch;
- DBusWatch *sitter_watch;
+ DBusWatch *error_watch; /**< Error pipe watch */
+ DBusWatch *sitter_watch; /**< Sitter pipe watch */
- int errnum;
- int status;
- unsigned int have_child_status : 1;
- unsigned int have_fork_errnum : 1;
- unsigned int have_exec_errnum : 1;
+ int errnum; /**< Error number */
+ int status; /**< Exit status code */
+ unsigned int have_child_status : 1; /**< True if child status has been reaped */
+ unsigned int have_fork_errnum : 1; /**< True if we have an error code from fork() */
+ unsigned int have_exec_errnum : 1; /**< True if we have an error code from exec() */
};
static DBusBabysitter*
Index: dbus-string.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- dbus-string.c 12 May 2003 02:44:44 -0000 1.41
+++ dbus-string.c 30 Sep 2003 02:32:53 -0000 1.42
@@ -25,6 +25,8 @@
#include "dbus-string.h"
/* we allow a system header here, for speed/convenience */
#include <string.h>
+/* for vsnprintf */
+#include <stdio.h>
#include "dbus-marshal.h"
#define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1
#include "dbus-string-private.h"
@@ -560,26 +562,30 @@
}
/**
- * Inserts the given byte at the given position.
+ * Inserts a number of bytes of a given value at the
+ * given position.
*
* @param str the string
* @param i the position
+ * @param n_bytes number of bytes
* @param byte the value to insert
* @returns #TRUE on success
*/
dbus_bool_t
-_dbus_string_insert_byte (DBusString *str,
- int i,
- unsigned char byte)
+_dbus_string_insert_bytes (DBusString *str,
+ int i,
+ int n_bytes,
+ unsigned char byte)
{
DBUS_STRING_PREAMBLE (str);
_dbus_assert (i <= real->len);
_dbus_assert (i >= 0);
+ _dbus_assert (n_bytes > 0);
- if (!open_gap (1, real, i))
+ if (!open_gap (n_bytes, real, i))
return FALSE;
- real->str[i] = byte;
+ memset (real->str + i, byte, n_bytes);
return TRUE;
}
@@ -964,7 +970,7 @@
p = (dbus_uint64_t*) (real->str + (real->len - 8));
*p = *((dbus_uint64_t*)octets);
#else
- char *p;
+ unsigned char *p;
DBUS_STRING_PREAMBLE (str);
if (!align_length_then_lengthen (str, 8, 8))
@@ -987,6 +993,59 @@
}
/**
+ * Appends a printf-style formatted string
+ * to the #DBusString.
+ *
+ * @param str the string
+ * @param format printf format
+ * @param args variable argument list
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_string_append_printf_valist (DBusString *str,
+ const char *format,
+ va_list args)
+{
+ int len;
+ char c;
+ DBUS_STRING_PREAMBLE (str);
+
+ /* Measure the message length without terminating nul */
+ len = vsnprintf (&c, 1, format, args);
+
+ if (!_dbus_string_lengthen (str, len))
+ return FALSE;
+
+ vsprintf (real->str + (real->len - len),
+ format, args);
+
+ return TRUE;
+}
+
+/**
+ * Appends a printf-style formatted string
+ * to the #DBusString.
+ *
+ * @param str the string
+ * @param format printf format
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_string_append_printf (DBusString *str,
+ const char *format,
+ ...)
+{
+ va_list args;
+ dbus_bool_t retval;
+
+ va_start (args, format);
+ retval = _dbus_string_append_printf_valist (str, format, args);
+ va_end (args);
+
+ return retval;
+}
+
+/**
* Appends block of bytes with the given length to a DBusString.
*
* @param str the DBusString
@@ -1752,7 +1811,7 @@
}
/**
- * Assigns a newline-terminated or \r\n-terminated line from the front
+ * Assigns a newline-terminated or \\r\\n-terminated line from the front
* of the string to the given dest string. The dest string's previous
* contents are deleted. If the source string contains no newline,
* moves the entire source string to the dest string.
@@ -2791,13 +2850,84 @@
}
/**
- * Checks that the given range of the string is a valid message name
+ * Checks that the given range of the string is a valid object path
+ * name in the D-BUS protocol. This includes a length restriction,
+ * etc., see the specification. It does not validate UTF-8, that has
+ * to be done separately for now.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that isn't in the string.
+ *
+ * @todo change spec to disallow more things, such as spaces in the
+ * path name
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid name
+ */
+dbus_bool_t
+_dbus_string_validate_path (const DBusString *str,
+ int start,
+ int len)
+{
+ const unsigned char *s;
+ const unsigned char *end;
+ const unsigned char *last_slash;
+
+ DBUS_CONST_STRING_PREAMBLE (str);
+ _dbus_assert (start >= 0);
+ _dbus_assert (len >= 0);
+ _dbus_assert (start <= real->len);
+
+ if (len > real->len - start)
+ return FALSE;
+
+ if (len > DBUS_MAXIMUM_NAME_LENGTH)
+ return FALSE;
+
+ if (len == 0)
+ return FALSE;
+
+ s = real->str + start;
+ end = s + len;
+
+ if (*s != '/')
+ return FALSE;
+ last_slash = s;
+ ++s;
+
+ while (s != end)
+ {
+ if (*s == '/')
+ {
+ if ((s - last_slash) < 2)
+ return FALSE; /* no empty path components allowed */
+
+ last_slash = s;
+ }
+
+ ++s;
+ }
+
+ if ((end - last_slash) < 2 &&
+ len > 1)
+ return FALSE; /* trailing slash not allowed unless the string is "/" */
+
+ return TRUE;
+}
+
+/**
+ * Checks that the given range of the string is a valid interface name
* in the D-BUS protocol. This includes a length restriction, etc.,
* see the specification. It does not validate UTF-8, that has to be
* done separately for now.
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that isn't in the string.
+ *
+ * @todo change spec to disallow more things, such as spaces in the
+ * interface name
*
* @param str the string
* @param start first byte index to check
@@ -2805,9 +2935,9 @@
* @returns #TRUE if the byte range exists and is a valid name
*/
dbus_bool_t
-_dbus_string_validate_name (const DBusString *str,
- int start,
- int len)
+_dbus_string_validate_interface (const DBusString *str,
+ int start,
+ int len)
{
const unsigned char *s;
const unsigned char *end;
@@ -2847,6 +2977,89 @@
return TRUE;
}
+/**
+ * Checks that the given range of the string is a valid member name
+ * in the D-BUS protocol. This includes a length restriction, etc.,
+ * see the specification. It does not validate UTF-8, that has to be
+ * done separately for now.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that isn't in the string.
+ *
+ * @todo change spec to disallow more things, such as spaces in the
+ * member name
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid name
+ */
+dbus_bool_t
+_dbus_string_validate_member (const DBusString *str,
+ int start,
+ int len)
+{
+ const unsigned char *s;
+ const unsigned char *end;
+ dbus_bool_t saw_dot;
+
+ DBUS_CONST_STRING_PREAMBLE (str);
+ _dbus_assert (start >= 0);
+ _dbus_assert (len >= 0);
+ _dbus_assert (start <= real->len);
+
+ if (len > real->len - start)
+ return FALSE;
+
+ if (len > DBUS_MAXIMUM_NAME_LENGTH)
+ return FALSE;
+
+ if (len == 0)
+ return FALSE;
+
+ saw_dot = FALSE;
+ s = real->str + start;
+ end = s + len;
+ while (s != end)
+ {
+ if (*s == '.')
+ {
+ saw_dot = TRUE;
+ break;
+ }
+
+ ++s;
+ }
+
+ /* No dot allowed in member names */
+ if (saw_dot)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Checks that the given range of the string is a valid error name
+ * in the D-BUS protocol. This includes a length restriction, etc.,
+ * see the specification. It does not validate UTF-8, that has to be
+ * done separately for now.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that isn't in the string.
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid name
+ */
+dbus_bool_t
+_dbus_string_validate_error_name (const DBusString *str,
+ int start,
+ int len)
+{
+ /* Same restrictions as interface name at the moment */
+ return _dbus_string_validate_interface (str, start, len);
+}
/**
* Checks that the given range of the string is a valid service name
@@ -2856,6 +3069,9 @@
*
* @todo this is inconsistent with most of DBusString in that
* it allows a start,len range that isn't in the string.
+ *
+ * @todo change spec to disallow more things, such as spaces in the
+ * service name
*
* @param str the string
* @param start first byte index to check
@@ -3107,6 +3323,24 @@
int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 };
char *s;
dbus_unichar_t ch;
+ const char *valid_paths[] = {
+ "/",
+ "/foo/bar",
+ "/foo",
+ "/foo/bar/baz"
+ };
+ const char *invalid_paths[] = {
+ "bar",
+ "bar/baz",
+ "/foo/bar/",
+ "/foo/"
+ "foo/",
+ "boo//blah",
+ "//",
+ "///",
+ "foo///blah/",
+ "Hello World"
+ };
i = 0;
while (i < _DBUS_N_ELEMENTS (lens))
@@ -3342,23 +3576,26 @@
_dbus_string_set_byte (&str, 1, 'q');
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'q');
- if (!_dbus_string_insert_byte (&str, 0, 255))
+ if (!_dbus_string_insert_bytes (&str, 0, 1, 255))
_dbus_assert_not_reached ("can't insert byte");
- if (!_dbus_string_insert_byte (&str, 2, 'Z'))
+ if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z'))
_dbus_assert_not_reached ("can't insert byte");
- if (!_dbus_string_insert_byte (&str, _dbus_string_get_length (&str), 'W'))
+ if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W'))
_dbus_assert_not_reached ("can't insert byte");
_dbus_assert (_dbus_string_get_byte (&str, 0) == 255);
_dbus_assert (_dbus_string_get_byte (&str, 1) == 'H');
_dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z');
- _dbus_assert (_dbus_string_get_byte (&str, 3) == 'q');
- _dbus_assert (_dbus_string_get_byte (&str, 4) == 'l');
- _dbus_assert (_dbus_string_get_byte (&str, 5) == 'l');
- _dbus_assert (_dbus_string_get_byte (&str, 6) == 'o');
- _dbus_assert (_dbus_string_get_byte (&str, 7) == 'W');
+ _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z');
+ _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z');
+ _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z');
+ _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q');
+ _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l');
+ _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l');
+ _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o');
+ _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W');
_dbus_string_free (&str);
@@ -3481,7 +3718,38 @@
/* Base 64 and Hex encoding */
test_roundtrips (test_base64_roundtrip);
test_roundtrips (test_hex_roundtrip);
-
+
+ /* Path validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
+ {
+ _dbus_string_init_const (&str, valid_paths[i]);
+
+ if (!_dbus_string_validate_path (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
+ _dbus_assert_not_reached ("invalid path");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
+ {
+ _dbus_string_init_const (&str, invalid_paths[i]);
+
+ if (_dbus_string_validate_path (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
+ _dbus_assert_not_reached ("valid path");
+ }
+
+ ++i;
+ }
+
return TRUE;
}
Index: dbus-string.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- dbus-string.h 12 May 2003 02:44:44 -0000 1.20
+++ dbus-string.h 30 Sep 2003 02:32:53 -0000 1.21
@@ -28,11 +28,15 @@
#include <dbus/dbus-memory.h>
#include <dbus/dbus-types.h>
+#include <dbus/dbus-sysdeps.h>
-DBUS_BEGIN_DECLS;
+#include <stdarg.h>
-typedef struct DBusString DBusString;
+DBUS_BEGIN_DECLS;
+/**
+ * DBusString object
+ */
struct DBusString
{
void *dummy1; /**< placeholder */
@@ -68,8 +72,9 @@
unsigned char byte);
unsigned char _dbus_string_get_byte (const DBusString *str,
int start);
-dbus_bool_t _dbus_string_insert_byte (DBusString *str,
+dbus_bool_t _dbus_string_insert_bytes (DBusString *str,
int i,
+ int n_bytes,
unsigned char byte);
dbus_bool_t _dbus_string_steal_data (DBusString *str,
char **data_return);
@@ -111,6 +116,12 @@
const unsigned char octets[4]);
dbus_bool_t _dbus_string_append_8_aligned (DBusString *str,
const unsigned char octets[8]);
+dbus_bool_t _dbus_string_append_printf (DBusString *str,
+ const char *format,
+ ...) _DBUS_GNUC_PRINTF (2, 3);
+dbus_bool_t _dbus_string_append_printf_valist (DBusString *str,
+ const char *format,
+ va_list args);
void _dbus_string_delete (DBusString *str,
int start,
int len);
@@ -216,7 +227,16 @@
dbus_bool_t _dbus_string_validate_nul (const DBusString *str,
int start,
int len);
-dbus_bool_t _dbus_string_validate_name (const DBusString *str,
+dbus_bool_t _dbus_string_validate_path (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_interface (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_member (const DBusString *str,
+ int start,
+ int len);
+dbus_bool_t _dbus_string_validate_error_name (const DBusString *str,
int start,
int len);
dbus_bool_t _dbus_string_validate_service (const DBusString *str,
Index: dbus-sysdeps.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -d -r1.64 -r1.65
--- dbus-sysdeps.c 15 Jun 2003 10:45:06 -0000 1.64
+++ dbus-sysdeps.c 30 Sep 2003 02:32:53 -0000 1.65
@@ -2515,9 +2515,12 @@
return FALSE;
}
+/**
+ * Internals of directory iterator
+ */
struct DBusDirIter
{
- DIR *d;
+ DIR *d; /**< The DIR* from opendir() */
};
Index: dbus-sysdeps.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- dbus-sysdeps.h 4 Jun 2003 05:20:20 -0000 1.35
+++ dbus-sysdeps.h 30 Sep 2003 02:32:53 -0000 1.36
@@ -25,7 +25,6 @@
#ifndef DBUS_SYSDEPS_H
#define DBUS_SYSDEPS_H
-#include <dbus/dbus-string.h>
#include <dbus/dbus-errors.h>
/* this is perhaps bogus, but strcmp() etc. are faster if we use the
@@ -47,6 +46,8 @@
* dbus-memory.c)
*/
+typedef struct DBusString DBusString;
+
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define _DBUS_GNUC_PRINTF( format_idx, arg_idx ) \
__attribute__((__format__ (__printf__, format_idx, arg_idx)))
@@ -96,12 +97,14 @@
#define DBUS_UID_FORMAT "%lu"
#define DBUS_GID_FORMAT "%lu"
+/**
+ * Struct representing socket credentials
+ */
typedef struct
{
- /* Set to DBUS_PID_UNSET etc. if not available */
- dbus_pid_t pid;
- dbus_uid_t uid;
- dbus_gid_t gid;
+ dbus_pid_t pid; /**< process ID or DBUS_PID_UNSET */
+ dbus_uid_t uid; /**< user ID or DBUS_UID_UNSET */
+ dbus_gid_t gid; /**< group ID or DBUS_GID_UNSET */
} DBusCredentials;
int _dbus_connect_unix_socket (const char *path,
@@ -134,6 +137,9 @@
typedef struct DBusUserInfo DBusUserInfo;
typedef struct DBusGroupInfo DBusGroupInfo;
+/**
+ * Information about a UNIX user
+ */
struct DBusUserInfo
{
dbus_uid_t uid; /**< UID */
@@ -144,6 +150,9 @@
char *homedir; /**< Home directory */
};
+/**
+ * Information about a UNIX group
+ */
struct DBusGroupInfo
{
dbus_gid_t gid; /**< GID */
@@ -172,9 +181,13 @@
dbus_gid_t _dbus_getgid (void);
typedef struct DBusAtomic DBusAtomic;
+
+/**
+ * An atomic integer.
+ */
struct DBusAtomic
{
- volatile dbus_int32_t value;
+ volatile dbus_int32_t value; /**< Value of the atomic integer. */
};
dbus_int32_t _dbus_atomic_inc (DBusAtomic *atomic);
@@ -187,11 +200,14 @@
#define _DBUS_POLLHUP 0x0010 /* Hung up */
#define _DBUS_POLLNVAL 0x0020 /* Invalid request: fd not open */
+/**
+ * A portable struct pollfd wrapper.
+ */
typedef struct
{
- int fd;
- short events;
- short revents;
+ int fd; /**< File descriptor */
+ short events; /**< Events to poll for */
+ short revents; /**< Events that occurred */
} DBusPollFD;
int _dbus_poll (DBusPollFD *fds,
@@ -248,16 +264,19 @@
void _dbus_exit (int code) _DBUS_GNUC_NORETURN;
+/**
+ * Portable struct with stat() results
+ */
typedef struct
{
- unsigned long mode;
- unsigned long nlink;
- dbus_uid_t uid;
- dbus_gid_t gid;
- unsigned long size;
- unsigned long atime;
- unsigned long mtime;
- unsigned long ctime;
+ unsigned long mode; /**< File mode */
+ unsigned long nlink; /**< Number of hard links */
+ dbus_uid_t uid; /**< User owning file */
+ dbus_gid_t gid; /**< Group owning file */
+ unsigned long size; /**< Size of file */
+ unsigned long atime; /**< Access time */
+ unsigned long mtime; /**< Modify time */
+ unsigned long ctime; /**< Creation time */
} DBusStat;
dbus_bool_t _dbus_stat (const DBusString *filename,
Index: dbus-test.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-test.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- dbus-test.c 28 Jun 2003 23:12:11 -0000 1.30
+++ dbus-test.c 30 Sep 2003 02:32:53 -0000 1.31
@@ -81,7 +81,7 @@
die ("strings");
check_memleaks ();
-
+
printf ("%s: running sysdeps tests\n", "dbus-test");
if (!_dbus_sysdeps_test ())
die ("sysdeps");
@@ -99,6 +99,12 @@
die ("address parsing");
check_memleaks ();
+
+ printf ("%s: running object tree tests\n", "dbus-test");
+ if (!_dbus_object_tree_test ())
+ die ("object tree");
+
+ check_memleaks ();
printf ("%s: running marshalling tests\n", "dbus-test");
if (!_dbus_marshal_test ())
@@ -129,12 +135,6 @@
die ("messages");
check_memleaks ();
-
- printf ("%s: running message handler tests\n", "dbus-test");
- if (!_dbus_message_handler_test (test_data_dir))
- die ("message handler");
-
- check_memleaks ();
printf ("%s: running hash table tests\n", "dbus-test");
if (!_dbus_hash_test ())
@@ -179,6 +179,12 @@
die ("auth");
check_memleaks ();
+
+ printf ("%s: running pending call tests\n", "dbus-test");
+ if (!_dbus_pending_call_test (test_data_dir))
+ die ("auth");
+
+ check_memleaks ();
printf ("%s: completed successfully\n", "dbus-test");
#else
Index: dbus-test.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-test.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- dbus-test.h 28 Jun 2003 23:12:11 -0000 1.22
+++ dbus-test.h 30 Sep 2003 02:32:53 -0000 1.23
@@ -43,7 +43,6 @@
dbus_bool_t _dbus_string_test (void);
dbus_bool_t _dbus_address_test (void);
dbus_bool_t _dbus_message_test (const char *test_data_dir);
-dbus_bool_t _dbus_message_handler_test (const char *test_data_dir);
dbus_bool_t _dbus_auth_test (const char *test_data_dir);
dbus_bool_t _dbus_md5_test (void);
dbus_bool_t _dbus_sha_test (const char *test_data_dir);
@@ -53,7 +52,8 @@
dbus_bool_t _dbus_spawn_test (const char *test_data_dir);
dbus_bool_t _dbus_userdb_test (const char *test_data_dir);
dbus_bool_t _dbus_memory_test (void);
-
+dbus_bool_t _dbus_object_tree_test (void);
+dbus_bool_t _dbus_pending_call_test (const char *test_data_dir);
void dbus_internal_do_not_use_run_tests (const char *test_data_dir);
dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename,
Index: dbus-threads.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dbus-threads.c 23 Jun 2003 02:12:19 -0000 1.17
+++ dbus-threads.c 30 Sep 2003 02:32:53 -0000 1.18
@@ -223,10 +223,10 @@
#define LOCK_ADDR(name) (& _dbus_lock_##name)
LOCK_ADDR (list),
LOCK_ADDR (connection_slots),
+ LOCK_ADDR (pending_call_slots),
LOCK_ADDR (server_slots),
LOCK_ADDR (message_slots),
LOCK_ADDR (atomic),
- LOCK_ADDR (message_handler),
LOCK_ADDR (bus),
LOCK_ADDR (shutdown_funcs),
LOCK_ADDR (system_users)
Index: dbus-threads.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-threads.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- dbus-threads.h 15 Feb 2003 16:25:08 -0000 1.3
+++ dbus-threads.h 30 Sep 2003 02:32:53 -0000 1.4
@@ -66,30 +66,34 @@
DBUS_THREAD_FUNCTIONS_ALL_MASK = (1 << 10) - 1
} DBusThreadFunctionsMask;
+/**
+ * Functions that must be implemented to make the D-BUS
+ * library thread-aware.
+ */
typedef struct
{
- unsigned int mask;
+ unsigned int mask; /**< Mask indicating which functions are present. */
- DBusMutexNewFunction mutex_new;
- DBusMutexFreeFunction mutex_free;
- DBusMutexLockFunction mutex_lock;
- DBusMutexUnlockFunction mutex_unlock;
+ DBusMutexNewFunction mutex_new; /**< Function to create a mutex */
+ DBusMutexFreeFunction mutex_free; /**< Function to free a mutex */
+ DBusMutexLockFunction mutex_lock; /**< Function to lock a mutex */
+ DBusMutexUnlockFunction mutex_unlock; /**< Function to unlock a mutex */
- DBusCondVarNewFunction condvar_new;
- DBusCondVarFreeFunction condvar_free;
- DBusCondVarWaitFunction condvar_wait;
- DBusCondVarWaitTimeoutFunction condvar_wait_timeout;
- DBusCondVarWakeOneFunction condvar_wake_one;
- DBusCondVarWakeAllFunction condvar_wake_all;
+ DBusCondVarNewFunction condvar_new; /**< Function to create a condition variable */
+ DBusCondVarFreeFunction condvar_free; /**< Function to free a condition variable */
+ DBusCondVarWaitFunction condvar_wait; /**< Function to wait on a condition */
+ DBusCondVarWaitTimeoutFunction condvar_wait_timeout; /**< Function to wait on a condition with a timeout */
+ DBusCondVarWakeOneFunction condvar_wake_one; /**< Function to wake one thread waiting on the condition */
+ DBusCondVarWakeAllFunction condvar_wake_all; /**< Function to wake all threads waiting on the condition */
- void (* padding1) (void);
- void (* padding2) (void);
- void (* padding3) (void);
- void (* padding4) (void);
- void (* padding5) (void);
- void (* padding6) (void);
- void (* padding7) (void);
- void (* padding8) (void);
+ void (* padding1) (void); /**< Reserved for future expansion */
+ void (* padding2) (void); /**< Reserved for future expansion */
+ void (* padding3) (void); /**< Reserved for future expansion */
+ void (* padding4) (void); /**< Reserved for future expansion */
+ void (* padding5) (void); /**< Reserved for future expansion */
+ void (* padding6) (void); /**< Reserved for future expansion */
+ void (* padding7) (void); /**< Reserved for future expansion */
+ void (* padding8) (void); /**< Reserved for future expansion */
} DBusThreadFunctions;
Index: dbus-timeout.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-timeout.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dbus-timeout.c 12 May 2003 02:44:44 -0000 1.10
+++ dbus-timeout.c 30 Sep 2003 02:32:53 -0000 1.11
@@ -33,6 +33,9 @@
* @{
*/
+/**
+ * Internals of DBusTimeout
+ */
struct DBusTimeout
{
int refcount; /**< Reference count */
Index: dbus-transport-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-protected.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- dbus-transport-protected.h 14 Apr 2003 02:29:21 -0000 1.9
+++ dbus-transport-protected.h 30 Sep 2003 02:32:53 -0000 1.10
@@ -34,6 +34,10 @@
typedef struct DBusTransportVTable DBusTransportVTable;
+/**
+ * The virtual table that must be implemented to
+ * create a new kind of transport.
+ */
struct DBusTransportVTable
{
void (* finalize) (DBusTransport *transport);
@@ -69,6 +73,12 @@
/**< Outstanding messages counter changed */
};
+/**
+ * Object representing a transport such as a socket.
+ * A transport can shuttle messages from point A to point B,
+ * and is the backend for a #DBusConnection.
+ *
+ */
struct DBusTransport
{
int refcount; /**< Reference count. */
Index: dbus-transport.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- dbus-transport.c 4 Jun 2003 05:20:20 -0000 1.33
+++ dbus-transport.c 30 Sep 2003 02:32:53 -0000 1.34
@@ -813,7 +813,9 @@
{
DBusDispatchStatus status;
+#if 0
_dbus_verbose ("_dbus_transport_queue_messages()\n");
+#endif
/* Queue any messages */
while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
Index: dbus-types.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-types.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- dbus-types.h 29 Apr 2003 22:57:13 -0000 1.7
+++ dbus-types.h 30 Sep 2003 02:32:53 -0000 1.8
@@ -83,6 +83,10 @@
*
* A 64-bit unsigned integer on all platforms that support it.
* If supported, #DBUS_HAVE_INT64 will be defined.
+ *
+ * C99 requires a 64-bit type and most likely all interesting
+ * compilers support one. GLib for example flat-out requires
+ * a 64-bit type.
*/
/**
@@ -90,6 +94,10 @@
*
* A 64-bit signed integer on all platforms that support it.
* If supported, #DBUS_HAVE_INT64 will be defined.
+ *
+ * C99 requires a 64-bit type and most likely all interesting
+ * compilers support one. GLib for example flat-out requires
+ * a 64-bit type.
*/
/**
Index: dbus-userdb.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-userdb.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- dbus-userdb.c 28 Apr 2003 19:29:42 -0000 1.4
+++ dbus-userdb.c 30 Sep 2003 02:32:53 -0000 1.5
@@ -26,14 +26,17 @@
#include "dbus-internals.h"
#include <string.h>
+/**
+ * Internals of DBusUserDatabase
+ */
struct DBusUserDatabase
{
- int refcount;
+ int refcount; /**< Reference count */
- DBusHashTable *users;
- DBusHashTable *groups;
- DBusHashTable *users_by_name;
- DBusHashTable *groups_by_name;
+ DBusHashTable *users; /**< Users in the database by UID */
+ DBusHashTable *groups; /**< Groups in the database by GID */
+ DBusHashTable *users_by_name; /**< Users in the database by name */
+ DBusHashTable *groups_by_name; /**< Groups in the database by name */
};
static void
Index: dbus-watch.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-watch.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- dbus-watch.c 16 May 2003 20:09:25 -0000 1.13
+++ dbus-watch.c 30 Sep 2003 02:32:53 -0000 1.14
@@ -33,6 +33,9 @@
* @{
*/
+/**
+ * Implementation of DBusWatch
+ */
struct DBusWatch
{
int refcount; /**< Reference count */
Index: dbus.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- dbus.h 29 Apr 2003 21:56:37 -0000 1.15
+++ dbus.h 30 Sep 2003 02:32:53 -0000 1.16
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus.h Convenience header including all other headers
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2003 Red Hat Inc.
*
* Licensed under the Academic Free License version 1.2
*
@@ -37,7 +37,7 @@
#include <dbus/dbus-errors.h>
#include <dbus/dbus-macros.h>
#include <dbus/dbus-message.h>
-#include <dbus/dbus-message-handler.h>
+#include <dbus/dbus-pending-call.h>
#include <dbus/dbus-protocol.h>
#include <dbus/dbus-server.h>
#include <dbus/dbus-threads.h>
- Previous message: dbus/bus signals.c,1.1,1.2 signals.h,1.1,1.2 Makefile.am,1.27,1.28 activation.c,1.27,1.28 bus.c,1.38,1.39 bus.h,1.18,1.19 config-parser.c,1.21,1.22 connection.c,1.43,1.44 connection.h,1.15,1.16 dbus-daemon-1.1.in,1.3,1.4 desktop-file.c,1.7,1.8 dispatch.c,1.50,1.51 dispatch.h,1.3,1.4 driver.c,1.41,1.42 policy.c,1.13,1.14 policy.h,1.9,1.10 services.c,1.15,1.16 session.conf.in,1.5,1.6 system.conf.in,1.10,1.11 test-main.c,1.12,1.13 test.c,1.21,1.22 test.h,1.10,1.11
- Next message: dbus/doc TODO,1.23,1.24 dbus-specification.sgml,1.40,1.41
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]