From afa4ffbd852686633086569cd34942917c5c49af Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 21 Oct 2006 17:08:08 +0000 Subject: 2006-10-21 Havoc Pennington * dbus/dbus-message.h: put #ifndef DBUS_DISABLE_DEPRECATED around dbus_message_iter_get_array_len(). * throughout: documentation improvements. --- ChangeLog | 7 + dbus/dbus-bus.c | 217 +++++++++++--- dbus/dbus-connection.c | 9 +- dbus/dbus-errors.c | 36 ++- dbus/dbus-marshal-recursive.c | 6 +- dbus/dbus-memory.c | 51 +++- dbus/dbus-message.c | 655 +++++++++++++++++++++++++----------------- dbus/dbus-message.h | 5 + dbus/dbus-timeout.c | 3 + dbus/dbus-watch.c | 3 + doc/dbus-specification.xml | 12 +- 11 files changed, 675 insertions(+), 329 deletions(-) diff --git a/ChangeLog b/ChangeLog index 44d029f2..d2f8acb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-10-21 Havoc Pennington + + * dbus/dbus-message.h: put #ifndef DBUS_DISABLE_DEPRECATED around + dbus_message_iter_get_array_len(). + + * throughout: documentation improvements. + 2006-10-20 Havoc Pennington * doc/TODO: remove the int64 thing from 1.0 since it doesn't diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 1661f246..b2072b88 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -36,6 +36,21 @@ * @ingroup DBus * @brief Functions for communicating with the message bus * + * dbus_bus_get() allows all modules and libraries in a given + * process to share the same connection to the bus daemon by storing + * the connection globally. + * + * All other functions in this module are just convenience functions; + * most of them invoke methods on the bus daemon, by sending method + * call messages to #DBUS_SERVICE_DBUS. These convenience functions + * often make blocking method calls. If you don't want to block, + * you can send the method call messages manually in the same way + * you would any other method call message. + * + * This module is the only one in libdbus that's specific to + * communicating with the message bus daemon. The rest of the API can + * also be used for connecting to another application directly. + * * @todo right now the default address of the system bus is hardcoded, * so if you change it in the global config file suddenly you have to * set DBUS_SYSTEM_BUS_ADDRESS env variable. Might be nice if the @@ -472,6 +487,11 @@ internal_bus_get (DBusBusType type, * will exit if the connection closes. You can undo this * by calling dbus_connection_set_exit_on_disconnect() yourself * after you get the connection. + * + * dbus_bus_get() calls dbus_bus_register() for you. + * + * If returning a newly-created connection, this function will block + * until authentication and bus registration are complete. * * @param type bus type * @param error address where an error can be returned. @@ -485,11 +505,11 @@ dbus_bus_get (DBusBusType type, } /** - * Connects to a bus daemon and registers the client with it as with dbus_bus_register(). - * Unlike dbus_bus_get(), always creates a new connection. This connection - * will not be saved or recycled by libdbus. Caller owns a reference - * to the bus and must either close it or know it to be closed - * prior to releasing this reference. + * Connects to a bus daemon and registers the client with it as with + * dbus_bus_register(). Unlike dbus_bus_get(), always creates a new + * connection. This connection will not be saved or recycled by + * libdbus. Caller owns a reference to the bus and must either close + * it or know it to be closed prior to releasing this reference. * * See dbus_connection_open_private() for more details on when to * close and unref this connection. @@ -500,6 +520,11 @@ dbus_bus_get (DBusBusType type, * by calling dbus_connection_set_exit_on_disconnect() yourself * after you get the connection. * + * dbus_bus_get_private() calls dbus_bus_register() for you. + * + * This function will block until authentication and bus registration + * are complete. + * * @param type bus type * @param error address where an error can be returned. * @returns a DBusConnection with new ref @@ -519,6 +544,13 @@ dbus_bus_get_private (DBusBusType type, * * If you use dbus_bus_get() or dbus_bus_get_private() this * function will be called for you. + * + * If you open a bus connection with dbus_connection_open() or + * dbus_connection_open_private() you will have to dbus_bus_register() + * yourself, or make the appropriate registration method calls + * yourself. + * + * This function will block until registration is complete. * * @param connection the connection * @param error place to store errors @@ -598,9 +630,11 @@ dbus_bus_register (DBusConnection *connection, /** - * Sets the unique name of the connection. Can only be used if you - * registered with the bus manually (i.e. if you did not call - * dbus_bus_register()). Can only be called once per connection. + * Sets the unique name of the connection, as assigned by the message + * bus. Can only be used if you registered with the bus manually + * (i.e. if you did not call dbus_bus_register()). Can only be called + * once per connection. After the unique name is set, you can get it + * with dbus_bus_get_unique_name(). * * @param connection the connection * @param unique_name the unique name @@ -626,11 +660,17 @@ dbus_bus_set_unique_name (DBusConnection *connection, } /** - * Gets the unique name of the connection. Only possible after the - * connection has been registered with the message bus. + * Gets the unique name of the connection as assigned by the message + * bus. Only possible after the connection has been registered with + * the message bus. * - * The name remains valid for the duration of the connection and + * The name remains valid until the connection is freed, and * should not be freed by the caller. + * + * There are two ways to set the unique name; one is + * dbus_bus_register(), the other is dbus_bus_set_unique_name(). + * You are responsible for calling dbus_bus_set_unique_name() + * if you register by hand instead of using dbus_bus_register(). * * @param connection the connection * @returns the unique name or NULL on error @@ -650,16 +690,22 @@ dbus_bus_get_unique_name (DBusConnection *connection) } /** - * Asks the bus to return the uid of the named - * connection. + * Asks the bus to return the uid of the named connection. + * Only works on UNIX; only works for connections on the same + * machine as the bus. If you are not on the same machine + * as the bus, then calling this is probably a bad idea, + * since the uid will mean little to your application. * - * Not going to work on Windows, the bus should return - * an error then. + * For the system message bus you're guaranteed to be on the same + * machine since it only listens on a UNIX domain socket (at least, + * as shipped by default). + * + * This function will just return an error on Windows. * * @param connection the connection * @param name a name owned by the connection * @param error location to store the error - * @returns a result code, -1 if error is set + * @returns the unix user id, or ((unsigned)-1) if error is set */ unsigned long dbus_bus_get_unix_user (DBusConnection *connection, @@ -734,17 +780,46 @@ dbus_bus_get_unix_user (DBusConnection *connection, * result codes are discussed here, but the specification is the * canonical version of this information. * - * The #DBUS_NAME_FLAG_ALLOW_REPLACEMENT flag indicates that the caller - * will allow other services to take over the name from the current owner. + * First you should know that for each bus name, the bus stores + * a queue of connections that would like to own it. Only + * one owns it at a time - called the primary owner. If the primary + * owner releases the name or disconnects, then the next owner in the + * queue atomically takes over. + * + * So for example if you have an application org.freedesktop.TextEditor + * and multiple instances of it can be run, you can have all of them + * sitting in the queue. The first one to start up will receive messages + * sent to org.freedesktop.TextEditor, but if that one exits another + * will become the primary owner and receive messages. + * + * The queue means you don't need to manually watch for the current owner to + * disappear and then request the name again. + * + * When requesting a name, you can specify several flags. + * + * #DBUS_NAME_FLAG_ALLOW_REPLACEMENT and #DBUS_NAME_FLAG_DO_NOT_QUEUE + * are properties stored by the bus for this connection with respect to + * each requested bus name. These properties are stored even if the + * connection is queued and does not become the primary owner. + * You can update these flags by calling RequestName again (even if + * you already own the name). + * + * #DBUS_NAME_FLAG_ALLOW_REPLACEMENT means that another requestor of the + * name can take it away from you by specifying #DBUS_NAME_FLAG_REPLACE_EXISTING. + * + * #DBUS_NAME_FLAG_DO_NOT_QUEUE means that if you aren't the primary owner, + * you don't want to be queued up - you only care about being the + * primary owner. * - * The #DBUS_NAME_FLAG_REPLACE_EXISTING flag indicates that the caller - * would like to take over the name from the current owner. - * If the current name owner did not use #DBUS_NAME_FLAG_ALLOW_REPLACEMENT - * then this flag indicates that the caller would like to be placed - * in the queue to own the name when the current owner lets go. + * Unlike the other two flags, #DBUS_NAME_FLAG_REPLACE_EXISTING is a property + * of the individual RequestName call, i.e. the bus does not persistently + * associate it with the connection-name pair. If a RequestName call includes + * the #DBUS_NAME_FLAG_REPLACE_EXISTING flag, and the current primary + * owner has #DBUS_NAME_FLAG_ALLOW_REPLACEMENT set, then the current primary + * owner will be kicked off. * * If no flags are given, an application will receive the requested - * name only if the name is currently unowned; it will NOT give + * name only if the name is currently unowned; and it will NOT give * up the name if another application asks to take it over using * #DBUS_NAME_FLAG_REPLACE_EXISTING. * @@ -770,7 +845,9 @@ dbus_bus_get_unix_user (DBusConnection *connection, * #DBUS_NAME_FLAG_REPLACE_EXISTING. * * #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER happens if an application - * requests a name it already owns. + * requests a name it already owns. (Re-requesting a name is useful if + * you want to change the #DBUS_NAME_FLAG_ALLOW_REPLACEMENT or + * #DBUS_NAME_FLAG_DO_NOT_QUEUE settings.) * * When a service represents an application, say "text editor," then * it should specify #DBUS_NAME_FLAG_ALLOW_REPLACEMENT if it wants @@ -779,7 +856,19 @@ dbus_bus_get_unix_user (DBusConnection *connection, * specify #DBUS_NAME_FLAG_REPLACE_EXISTING to either take over * (last-started-wins) or be queued up (first-started-wins) according * to whether #DBUS_NAME_FLAG_ALLOW_REPLACEMENT was given. - * + * + * Conventionally, single-instance applications often offer a command + * line option called --replace which means to replace the current + * instance. To implement this, always set + * #DBUS_NAME_FLAG_ALLOW_REPLACEMENT when you request your + * application's bus name. When you lose ownership of your bus name, + * you need to exit. Look for the signal "NameLost" from + * #DBUS_SERVICE_DBUS and #DBUS_INTERFACE_DBUS (the signal's first + * argument is the bus name that was lost). If starting up without + * --replace, do not specify #DBUS_NAME_FLAG_REPLACE_EXISTING, and + * exit if you fail to become the bus name owner. If --replace is + * given, ask to replace the old owner. + * * @param connection the connection * @param name the name to request * @param flags flags @@ -855,10 +944,18 @@ dbus_bus_request_name (DBusConnection *connection, /** - * Asks the bus to unassign the given name to this connection by invoking - * the ReleaseName method on the bus. This method is fully documented - * in the D-Bus specification. + * Asks the bus to unassign the given name from this connection by + * invoking the ReleaseName method on the bus. The "ReleaseName" + * method is canonically documented in the D-Bus specification. * + * Possible results are: #DBUS_RELEASE_NAME_REPLY_RELEASED + * which means you owned the name or were in the queue to own it, + * and and now you don't own it and aren't in the queue. + * #DBUS_RELEASE_NAME_REPLY_NOT_OWNER which means someone else + * owns the name so you can't release it. + * #DBUS_RELEASE_NAME_REPLY_NON_EXISTENT + * which means nobody owned the name. + * * @param connection the connection * @param name the name to remove * @param error location to store the error @@ -930,8 +1027,17 @@ dbus_bus_release_name (DBusConnection *connection, } /** - * Checks whether a certain name has an owner. + * Asks the bus whether a certain name has an owner. * + * Using this can easily result in a race condition, + * since an owner can appear or disappear after you + * call this. + * + * If you want to request a name, just request it; + * if you want to avoid replacing a current owner, + * don't specify #DBUS_NAME_FLAG_REPLACE_EXISTING and + * you will get an error if there's already an owner. + * * @param connection the connection * @param name the name * @param error location to store any errors @@ -1000,6 +1106,12 @@ dbus_bus_name_has_owner (DBusConnection *connection, * The flags parameter is for future expansion, currently you should * specify 0. * + * It's often easier to avoid explicitly starting services, and + * just send a method call to the service's bus name instead. + * Method calls start a service to handle them by default + * unless you call dbus_message_set_auto_start() to disable this + * behavior. + * * @param connection the connection * @param name the name we want the new service to request * @param flags the flags (should always be 0 for now) @@ -1119,11 +1231,13 @@ send_no_return_values (DBusConnection *connection, * path='/bar/foo',destination=':452345.34'" * * Possible keys you can match on are type, sender, - * interface, member, path, destination and the special - * arg keys. Excluding a key from the rule indicates - * a wildcard match. For instance excluding the + * interface, member, path, destination and numbered + * keys to match message args (keys are 'arg0', 'arg1', etc.). + * Omitting a key from the rule indicates + * a wildcard match. For instance omitting * the member from a match rule but adding a sender would - * let all messages from that sender through. + * let all messages from that sender through regardless of + * the member. * * Matches are inclusive not exclusive so as long as one * rule matches the message will get through. It is important @@ -1132,12 +1246,31 @@ send_no_return_values (DBusConnection *connection, * can cause performance problems such as draining batteries * on embedded platforms. * - * The special arg keys are used for further restricting the - * match based on the parameters sent by the signal or method. - * For instance arg1='foo' will check the first argument, - * arg2='bar' the second and so on. For performance reasons - * there is a set limit on the highest number parameter that - * can be checked which is set in dbus-protocol.h + * If you match message args ('arg0', 'arg1', and so forth) + * only string arguments will match. That is, arg0='5' means + * match the string "5" not the integer 5. + * + * Currently there is no way to match against non-string arguments. + * + * Matching on interface is tricky because method call + * messages only optionally specify the interface. + * If a message omits the interface, then it will NOT match + * if the rule specifies an interface name. This means match + * rules on method calls should not usually give an interface. + * + * However, signal messages are required to include the interface + * so when matching signals usually you should specify the interface + * in the match rule. + * + * For security reasons, you can match arguments only up to + * #DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER. + * + * Match rules have a maximum length of #DBUS_MAXIMUM_MATCH_RULE_LENGTH + * bytes. + * + * Both of these maximums are much higher than you're likely to need, + * they only exist because the D-Bus bus daemon has fixed limits on + * all resource usage. * * @param connection connection to the message bus * @param rule textual form of match rule @@ -1181,6 +1314,10 @@ dbus_bus_add_match (DBusConnection *connection, * recently-added identical rule gets removed). The "rule" argument * is the string form of a match rule. * + * The bus compares match rules semantically, not textually, so + * whitespace and ordering don't have to be identical to + * the rule you passed to dbus_bus_add_match(). + * * 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(). diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 69afd100..81c7cadf 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -2940,16 +2940,19 @@ _dbus_connection_send_unlocked_no_update (DBusConnection *connection, * The function will never fail for other reasons; even if the * connection is disconnected, you can queue an outgoing message, * though obviously it won't be sent. + * + * The message serial is used by the remote application to send a + * reply; see dbus_message_get_serial() or the D-Bus specification. * * @param connection the connection. * @param message the message to write. - * @param client_serial return location for client serial. + * @param serial return location for message serial, or #NULL if you don't care * @returns #TRUE on success. */ dbus_bool_t dbus_connection_send (DBusConnection *connection, DBusMessage *message, - dbus_uint32_t *client_serial) + dbus_uint32_t *serial) { _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (message != NULL, FALSE); @@ -2958,7 +2961,7 @@ dbus_connection_send (DBusConnection *connection, return _dbus_connection_send_and_unlock (connection, message, - client_serial); + serial); } static dbus_bool_t diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c index fb230852..a20610a6 100644 --- a/dbus/dbus-errors.c +++ b/dbus/dbus-errors.c @@ -124,6 +124,9 @@ message_from_error (const char *error) * } * @endcode * + * By convention, all functions allow #NULL instead of a DBusError*, + * so callers who don't care about the error can ignore it. + * * 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, @@ -137,13 +140,19 @@ message_from_error (const char *error) * You can check the specific error that occurred using * dbus_error_has_name(). * + * Errors will not be set for programming errors, such as passing + * invalid arguments to the libdbus API. Instead, libdbus will print + * warnings, exit on a failed assertion, or even crash in those cases + * (in other words, incorrect use of the API results in undefined + * behavior, possibly accompanied by helpful debugging output if + * you're lucky). + * * @{ */ /** - * Initializes a DBusError structure. Does not allocate - * any memory; the error only needs to be freed - * if it is set at some point. + * Initializes a DBusError structure. Does not allocate any memory; + * the error only needs to be freed if it is set at some point. * * @param error the DBusError. */ @@ -190,11 +199,15 @@ dbus_error_free (DBusError *error) /** * Assigns an error name and message to a DBusError. Does nothing if - * error is #NULL. The message may be NULL, which means a default - * message will be deduced from the name. If the error name is unknown - * to D-Bus the default message will be totally useless, though. + * error is #NULL. The message may be #NULL, which means a default + * message will be deduced from the name. The default message will be + * totally useless, though, so using a #NULL message is not recommended. * - * @param error the error. + * Because this function does not copy the error name or message, you + * must ensure the name and message are global data that won't be + * freed. You probably want dbus_set_error() instead, in most cases. + * + * @param error the error.or #NULL * @param name the error name (not copied!!!) * @param message the error message (not copied!!!) */ @@ -297,14 +310,15 @@ dbus_error_is_set (const DBusError *error) * Assigns an error name and message to a DBusError. * Does nothing if error is #NULL. * - * The format may be NULL, which means a default message will be - * deduced from the name. If the error name is unknown to D-Bus the - * default message will be totally useless, though. + * The format may be #NULL, which means a (pretty much useless) + * default message will be deduced from the name. This is not a good + * idea, just go ahead and provide a useful error message. It won't + * hurt you. * * If no memory can be allocated for the error message, * an out-of-memory error message will be set instead. * - * @param error the error. + * @param error the error.or #NULL * @param name the error name * @param format printf-style format string. */ diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index 501e9a53..bcea4c36 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -560,7 +560,7 @@ array_reader_next (DBusTypeReader *reader, _dbus_assert (reader->value_pos >= reader->u.array.start_pos); switch (_dbus_first_type_in_signature (reader->type_str, - reader->type_pos)) + reader->type_pos)) { case DBUS_TYPE_DICT_ENTRY: case DBUS_TYPE_STRUCT: @@ -875,10 +875,10 @@ _dbus_type_reader_read_basic (const DBusTypeReader *reader, } /** - * Returns the number of values remaining in the current array reader. + * Returns the number of bytes in the array. * * @param reader the reader to read from - * @returns the number of elements remaining in the array + * @returns the number of bytes in the array */ int _dbus_type_reader_get_array_length (const DBusTypeReader *reader) diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c index fbc02c1e..f2400af7 100644 --- a/dbus/dbus-memory.c +++ b/dbus/dbus-memory.c @@ -430,6 +430,9 @@ set_guards (void *real_block, * on all platforms. Returns #NULL if the allocation fails. * The memory must be released with dbus_free(). * + * dbus_malloc() memory is NOT safe to free with regular free() from + * the C library. Free it with dbus_free() only. + * * @param bytes number of bytes to allocate * @return allocated memory, or #NULL if the allocation fails. */ @@ -481,6 +484,9 @@ dbus_malloc (size_t bytes) * return #NULL if bytes is zero on all platforms. Returns #NULL if the * allocation fails. The memory must be released with dbus_free(). * + * dbus_malloc0() memory is NOT safe to free with regular free() from + * the C library. Free it with dbus_free() only. + * * @param bytes number of bytes to allocate * @return allocated memory, or #NULL if the allocation fails. */ @@ -741,16 +747,41 @@ _dbus_register_shutdown_func (DBusShutdownFunction func, */ /** - * The D-Bus library keeps some internal global variables, for example - * to cache the username of the current process. This function is - * used to free these global variables. It is really useful only for - * leak-checking cleanliness and the like. WARNING: this function is - * NOT thread safe, it must be called while NO other threads are using - * D-Bus. You cannot continue using D-Bus after calling this function, - * as it does things like free global mutexes created by - * dbus_threads_init(). To use a D-Bus function after calling - * dbus_shutdown(), you have to start over from scratch, e.g. calling - * dbus_threads_init() again. + * Frees all memory allocated internally by libdbus and + * reverses the effects of dbus_threads_init(). libdbus keeps internal + * global variables, for example caches and thread locks, and it + * can be useful to free these internal data structures. + * + * dbus_shutdown() does NOT free memory that was returned + * to the application. It only returns libdbus-internal + * data structures. + * + * You MUST free all memory and release all reference counts + * returned to you by libdbus prior to calling dbus_shutdown(). + * + * You can't continue to use any D-Bus objects, such as connections, + * that were allocated prior to dbus_shutdown(). You can, however, + * start over; call dbus_threads_init() again, create new connections, + * and so forth. + * + * WARNING: dbus_shutdown() is NOT thread safe, it must be called + * while NO other threads are using D-Bus. (Remember, you have to free + * all D-Bus objects and memory before you call dbus_shutdown(), so no + * thread can be using libdbus.) + * + * The purpose of dbus_shutdown() is to allow applications to get + * clean output from memory leak checkers. dbus_shutdown() may also be + * useful if you want to dlopen() libdbus instead of linking to it, + * and want to be able to unload the library again. + * + * There is absolutely no requirement to call dbus_shutdown() - in fact, + * most applications won't bother and should not feel guilty. + * + * You have to know that nobody is using libdbus in your application's + * process before you can call dbus_shutdown(). One implication of this + * is that calling dbus_shutdown() from a library is almost certainly + * wrong, since you don't know what the rest of the app is up to. + * */ void dbus_shutdown (void) diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index aa6f65bd..7e53ce12 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -579,18 +579,229 @@ dbus_message_cache_or_finalize (DBusMessage *message) dbus_message_finalize (message); } +/** + * Implementation of the varargs arg-getting functions. + * dbus_message_get_args() is the place to go for complete + * documentation. + * + * @see dbus_message_get_args + * @param iter the message iter + * @param error error to be filled in + * @param first_arg_type type of the first argument + * @param var_args return location for first argument, followed by list of type/location pairs + * @returns #FALSE if error was set + */ +dbus_bool_t +_dbus_message_iter_get_args_valist (DBusMessageIter *iter, + DBusError *error, + int first_arg_type, + va_list var_args) +{ + DBusMessageRealIter *real = (DBusMessageRealIter *)iter; + int spec_type, msg_type, i; + dbus_bool_t retval; + + _dbus_assert (_dbus_message_iter_check (real)); + + retval = FALSE; + + spec_type = first_arg_type; + i = 0; + + while (spec_type != DBUS_TYPE_INVALID) + { + msg_type = dbus_message_iter_get_arg_type (iter); + + if (msg_type != spec_type) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Argument %d is specified to be of type \"%s\", but " + "is actually of type \"%s\"\n", i, + _dbus_type_to_string (spec_type), + _dbus_type_to_string (msg_type)); + + goto out; + } + + if (dbus_type_is_basic (spec_type)) + { + DBusBasicValue *ptr; + + ptr = va_arg (var_args, DBusBasicValue*); + + _dbus_assert (ptr != NULL); + + _dbus_type_reader_read_basic (&real->u.reader, + ptr); + } + else if (spec_type == DBUS_TYPE_ARRAY) + { + int element_type; + int spec_element_type; + const DBusBasicValue **ptr; + int *n_elements_p; + DBusTypeReader array; + + spec_element_type = va_arg (var_args, int); + element_type = _dbus_type_reader_get_element_type (&real->u.reader); + + if (spec_element_type != element_type) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Argument %d is specified to be an array of \"%s\", but " + "is actually an array of \"%s\"\n", + i, + _dbus_type_to_string (spec_element_type), + _dbus_type_to_string (element_type)); + + goto out; + } + + if (dbus_type_is_fixed (spec_element_type)) + { + ptr = va_arg (var_args, const DBusBasicValue**); + n_elements_p = va_arg (var_args, int*); + + _dbus_assert (ptr != NULL); + _dbus_assert (n_elements_p != NULL); + + _dbus_type_reader_recurse (&real->u.reader, &array); + + _dbus_type_reader_read_fixed_multi (&array, + ptr, n_elements_p); + } + else if (spec_element_type == DBUS_TYPE_STRING || + spec_element_type == DBUS_TYPE_SIGNATURE || + spec_element_type == DBUS_TYPE_OBJECT_PATH) + { + char ***str_array_p; + int n_elements; + char **str_array; + + str_array_p = va_arg (var_args, char***); + n_elements_p = va_arg (var_args, int*); + + _dbus_assert (str_array_p != NULL); + _dbus_assert (n_elements_p != NULL); + + /* Count elements in the array */ + _dbus_type_reader_recurse (&real->u.reader, &array); + + n_elements = 0; + while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) + { + ++n_elements; + _dbus_type_reader_next (&array); + } + + str_array = dbus_new0 (char*, n_elements + 1); + if (str_array == NULL) + { + _DBUS_SET_OOM (error); + goto out; + } + + /* Now go through and dup each string */ + _dbus_type_reader_recurse (&real->u.reader, &array); + + i = 0; + while (i < n_elements) + { + const char *s; + _dbus_type_reader_read_basic (&array, + &s); + + str_array[i] = _dbus_strdup (s); + if (str_array[i] == NULL) + { + dbus_free_string_array (str_array); + _DBUS_SET_OOM (error); + goto out; + } + + ++i; + + if (!_dbus_type_reader_next (&array)) + _dbus_assert (i == n_elements); + } + + _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID); + _dbus_assert (i == n_elements); + _dbus_assert (str_array[i] == NULL); + + *str_array_p = str_array; + *n_elements_p = n_elements; + } +#ifndef DBUS_DISABLE_CHECKS + else + { + _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n", + _DBUS_FUNCTION_NAME); + goto out; + } +#endif + } +#ifndef DBUS_DISABLE_CHECKS + else + { + _dbus_warn ("you can only read arrays and basic types with %s for now\n", + _DBUS_FUNCTION_NAME); + goto out; + } +#endif + + spec_type = va_arg (var_args, int); + if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID) + { + dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, + "Message has only %d arguments, but more were expected", i); + goto out; + } + + i++; + } + + retval = TRUE; + + out: + + return retval; +} + /** @} */ /** * @defgroup DBusMessage DBusMessage * @ingroup DBus - * @brief Message to be sent or received over a DBusConnection. + * @brief Message to be sent or received over a #DBusConnection. * * A DBusMessage is the most basic unit of communication over a * DBusConnection. A DBusConnection represents a stream of messages * received from a remote application, and a stream of messages * sent to a remote application. * + * A message has a message type, returned from + * dbus_message_get_type(). This indicates whether the message is a + * method call, a reply to a method call, a signal, or an error reply. + * + * A message has header fields such as the sender, destination, method + * or signal name, and so forth. DBusMessage has accessor functions for + * these, such as dbus_message_get_member(). + * + * Convenience functions dbus_message_is_method_call(), dbus_message_is_signal(), + * and dbus_message_is_error() check several header fields at once and are + * slightly more efficient than checking the header fields with individual + * accessor functions. + * + * Finally, a message has arguments. The number and types of arguments + * are in the message's signature header field (accessed with + * dbus_message_get_signature()). Simple argument values are usually + * retrieved with dbus_message_get_args() but more complex values such + * as structs may require the use of #DBusMessageIter. + * + * The D-Bus specification goes into some more detail about header fields and + * message types. + * * @{ */ @@ -604,12 +815,16 @@ dbus_message_cache_or_finalize (DBusMessage *message) /** * Returns the serial of a message or 0 if none has been specified. * The message's serial number is provided by the application sending - * the message and is used to identify replies to this message. All - * messages received on a connection will have a serial, but messages - * you haven't sent yet may return 0. + * the message and is used to identify replies to this message. + * + * All messages received on a connection will have a serial provided + * by the remote application. + * + * For messages you're sending, dbus_connection_send() will assign a + * serial and return it to you. * * @param message the message - * @returns the client serial + * @returns the serial */ dbus_uint32_t dbus_message_get_serial (DBusMessage *message) @@ -620,11 +835,11 @@ dbus_message_get_serial (DBusMessage *message) } /** - * Sets the reply serial of a message (the client serial - * of the message this is a reply to). + * Sets the reply serial of a message (the serial of the message this + * is a reply to). * * @param message the message - * @param reply_serial the client serial + * @param reply_serial the serial we're replying to * @returns #FALSE if not enough memory */ dbus_bool_t @@ -748,8 +963,12 @@ dbus_message_new_empty_header (void) * Types include #DBUS_MESSAGE_TYPE_METHOD_CALL, * #DBUS_MESSAGE_TYPE_SIGNAL, and so forth. * + * Usually you want to use dbus_message_new_method_call(), + * dbus_message_new_method_return(), dbus_message_new_signal(), + * or dbus_message_new_error() instead. + * * @param message_type type of message - * @returns new message or #NULL If no memory + * @returns new message or #NULL if no memory */ DBusMessage* dbus_message_new (int message_type) @@ -781,14 +1000,18 @@ dbus_message_new (int message_type) * 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. - * + * + * The path and method names may not be #NULL. + * + * Destination, path, interface, and method name can't contain + * any invalid characters (see the D-Bus specification). + * * @param destination name 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 interface interface to invoke method on, or #NULL * @param method method to invoke * * @returns a new DBusMessage, free with dbus_message_unref() - * @see dbus_message_unref() */ DBusMessage* dbus_message_new_method_call (const char *destination, @@ -826,10 +1049,8 @@ dbus_message_new_method_call (const char *destination, * Constructs a message that is a reply to a method call. Returns * #NULL if memory can't be allocated for the message. * - * @param method_call the message which the created - * message is a reply to. + * @param method_call the message being replied to * @returns a new DBusMessage, free with dbus_message_unref() - * @see dbus_message_new_method_call(), dbus_message_unref() */ DBusMessage* dbus_message_new_method_return (DBusMessage *method_call) @@ -870,14 +1091,16 @@ dbus_message_new_method_return (DBusMessage *method_call) /** * 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. + * identified by its originating object path, interface, and the name + * of the signal. * + * Path, interface, and signal name must all be valid (the D-Bus + * specification defines the syntax of these fields). + * * @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, @@ -911,13 +1134,18 @@ dbus_message_new_signal (const char *path, } /** - * Creates a new message that is an error reply to a certain message. - * Error replies are possible in response to method calls primarily. + * Creates a new message that is an error reply to another message. + * Error replies are most common in response to method calls, but + * can be returned in reply to any message. * - * @param reply_to the original message + * The error name must be a valid error name according to the syntax + * given in the D-Bus specification. If you don't want to make + * up an error name just use #DBUS_ERROR_FAILED. + * + * @param reply_to the message we're replying to * @param error_name the error name - * @param error_message the error message string or #NULL for none - * @returns a new error message + * @param error_message the error message string (or #NULL for none, but please give a message) + * @returns a new error message object, free with dbus_message_unref() */ DBusMessage* dbus_message_new_error (DBusMessage *reply_to, @@ -975,8 +1203,11 @@ dbus_message_new_error (DBusMessage *reply_to, } /** - * Creates a new message that is an error reply to a certain message. - * Error replies are possible in response to method calls primarily. + * Creates a new message that is an error reply to another message, allowing + * you to use printf formatting. + * + * See dbus_message_new_error() for details - this function is the same + * aside from the printf formatting. * * @param reply_to the original message * @param error_name the error name @@ -1024,8 +1255,8 @@ dbus_message_new_error_printf (DBusMessage *reply_to, * outgoing message queue and thus not modifiable) the new message * will not be locked. * - * @param message the message. - * @returns the new message. + * @param message the message + * @returns the new message.or #NULL if not enough memory */ DBusMessage * dbus_message_copy (const DBusMessage *message) @@ -1077,7 +1308,7 @@ dbus_message_copy (const DBusMessage *message) /** * Increments the reference count of a DBusMessage. * - * @param message The message + * @param message the message * @returns the message * @see dbus_message_unref */ @@ -1097,9 +1328,10 @@ dbus_message_ref (DBusMessage *message) } /** - * Decrements the reference count of a DBusMessage. + * Decrements the reference count of a DBusMessage, freeing the + * message if the count reaches 0. * - * @param message The message + * @param message the message * @see dbus_message_ref */ void @@ -1127,8 +1359,7 @@ dbus_message_unref (DBusMessage *message) * #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. + * unknown type. #DBUS_MESSAGE_TYPE_INVALID will never be returned. * * @param message the message * @returns the type of the message @@ -1156,8 +1387,10 @@ dbus_message_get_type (DBusMessage *message) * * dbus_int32_t v_INT32 = 42; * const char *v_STRING = "Hello World"; - * DBUS_TYPE_INT32, &v_INT32, - * DBUS_TYPE_STRING, &v_STRING, + * dbus_message_append_args (message, + * DBUS_TYPE_INT32, &v_INT32, + * DBUS_TYPE_STRING, &v_STRING, + * DBUS_TYPE_INVALID); * @endcode * * To append an array of fixed-length basic types, pass in the @@ -1167,7 +1400,9 @@ dbus_message_get_type (DBusMessage *message) * @code * const dbus_int32_t array[] = { 1, 2, 3 }; * const dbus_int32_t *v_ARRAY = array; - * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3 + * dbus_message_append_args (message, + * DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3, + * DBUS_TYPE_INVALID); * @endcode * * @warning in C, given "int array[]", "&array == array" (the @@ -1178,7 +1413,8 @@ dbus_message_get_type (DBusMessage *message) * const char *array = "Hello" and then use &array though. * * The last argument to this function must be #DBUS_TYPE_INVALID, - * marking the end of the argument list. + * marking the end of the argument list. If you don't do this + * then libdbus won't know to stop and will read invalid memory. * * String/signature/path arrays should be passed in as "const char*** * address_of_array" and "int n_elements" @@ -1213,8 +1449,7 @@ dbus_message_append_args (DBusMessage *message, } /** - * This function takes a va_list for use by language bindings. - * It's otherwise the same as dbus_message_append_args(). + * Like dbus_message_append_args() but takes a va_list for use by language bindings. * * @todo for now, if this function fails due to OOM it will leave * the message half-written and you have to discard the message @@ -1353,12 +1588,15 @@ dbus_message_append_args_valist (DBusMessage *message, * followed by a pointer to where the value should be stored. The list * is terminated with #DBUS_TYPE_INVALID. * - * The returned values are constant; do not free them. They point - * into the #DBusMessage. + * Except for string arrays, the returned values are constant; do not + * free them. They point into the #DBusMessage. * * If the requested arguments are not present, or do not have the * requested types, then an error will be set. * + * If more arguments than requested are present, the requested + * arguments are returned and the extra arguments are ignored. + * * @todo support DBUS_TYPE_STRUCT and DBUS_TYPE_VARIANT and complex arrays * * @param message the message @@ -1387,8 +1625,7 @@ dbus_message_get_args (DBusMessage *message, } /** - * This function takes a va_list for use by language bindings. It is - * otherwise the same as dbus_message_get_args(). + * Like dbus_message_get_args but takes a va_list for use by language bindings. * * @see dbus_message_get_args * @param message the message @@ -1434,6 +1671,20 @@ _dbus_message_iter_init_common (DBusMessage *message, * Initializes a #DBusMessageIter for reading the arguments of the * message passed in. * + * When possible, dbus_message_get_args() is much more convenient. + * Some types of argument can only be read with #DBusMessageIter + * however. + * + * The easiest way to iterate is like this: + * @code + * dbus_message_iter_init (&iter); + * while ((current_type = dbus_message_iter_get_arg_type (&iter)) != DBUS_TYPE_INVALID) + * dbus_message_iter_next (&iter); + * @endcode + * + * #DBusMessageIter contains no allocated memory; it need not be + * freed, and can be copied by assignment or memcpy(). + * * @param message the message * @param iter pointer to an iterator to initialize * @returns #FALSE if the message has no arguments @@ -1469,7 +1720,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) { if (iter == NULL) { - _dbus_warn ("dbus message iterator is NULL\n"); + _dbus_warn_check_failed ("dbus message iterator is NULL\n"); return FALSE; } @@ -1477,7 +1728,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) { if (iter->u.reader.byte_order != iter->message->byte_order) { - _dbus_warn ("dbus message changed byte order since iterator was created\n"); + _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n"); return FALSE; } /* because we swap the message into compiler order when you init an iter */ @@ -1487,7 +1738,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) { if (iter->u.writer.byte_order != iter->message->byte_order) { - _dbus_warn ("dbus message changed byte order since append iterator was created\n"); + _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n"); return FALSE; } /* because we swap the message into compiler order when you init an iter */ @@ -1495,13 +1746,13 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) } else { - _dbus_warn ("dbus message iterator looks uninitialized or corrupted\n"); + _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted\n"); return FALSE; } if (iter->changed_stamp != iter->message->changed_stamp) { - _dbus_warn ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n"); + _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)\n"); return FALSE; } @@ -1513,8 +1764,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) * Checks if an iterator has any more fields. * * @param iter the message iter - * @returns #TRUE if there are more fields - * following + * @returns #TRUE if there are more fields following */ dbus_bool_t dbus_message_iter_has_next (DBusMessageIter *iter) @@ -1626,6 +1876,8 @@ dbus_message_iter_recurse (DBusMessageIter *iter, * recurse into a variant and determine the signature of * the variant's value. * + * The returned string must be freed with dbus_free(). + * * @param iter the message iterator * @returns the contained signature, or NULL if out of memory */ @@ -1677,10 +1929,12 @@ dbus_message_iter_get_signature (DBusMessageIter *iter) * #endif * @endcode * - * To avoid the #DBUS_HAVE_INT64 conditional, create a struct or - * something that occupies at least 8 bytes, e.g. you could use a - * struct with two int32 values in it. dbus_uint64_t is just one - * example of a type that's large enough to hold any possible value. + * You can skip the #DBUS_HAVE_INT64 conditional unless you care about + * some sort of really obscure platform. If you do know about such a + * platform and want your code to work on it, create a struct + * that occupies at least 8 bytes. dbus_uint64_t is just + * one example of a type that's large enough to hold any possible + * value. * * Be sure you have somehow checked that * dbus_message_iter_get_arg_type() matches the type you are @@ -1704,10 +1958,22 @@ dbus_message_iter_get_basic (DBusMessageIter *iter, } /** - * Returns the number of elements in the array; + * Returns the number of bytes in the array as marshaled in the wire + * protocol. The iterator must currently be inside an array-typed + * value. + * + * This function is deprecated on the grounds that it is stupid. Why + * would you want to know how many bytes are in the array as marshaled + * in the wire protocol? For now, use the n_elements returned from + * dbus_message_iter_get_fixed_array() instead, or iterate over the + * array values and count them. * + * @todo introduce a variant of this get_n_elements that returns + * the number of elements, though with a non-fixed array it will not + * be very efficient, so maybe it's not good. + * * @param iter the iterator - * @returns the number of elements in the array + * @returns the number of bytes in the array */ int dbus_message_iter_get_array_len (DBusMessageIter *iter) @@ -1725,13 +1991,17 @@ dbus_message_iter_get_array_len (DBusMessageIter *iter) * such as integers, bool, double. The block read will be from the * current position in the array until the end of the array. * - * This function should only be used if #dbus_type_is_fixed returns + * This function should only be used if dbus_type_is_fixed() returns * #TRUE for the element type. * * The value argument should be the address of a location to store the * returned array. So for int32 it should be a "const dbus_int32_t**" * The returned value is by reference and should not be freed. * + * Because the array is not copied, this function runs in + * constant time and is fast; it's much preferred over walking the + * entire array with an iterator. + * * @param iter the iterator * @param value location to store the block * @param n_elements number of elements in the block @@ -1753,203 +2023,13 @@ dbus_message_iter_get_fixed_array (DBusMessageIter *iter, value, n_elements); } -/** - * This function takes a va_list for use by language bindings and is - * otherwise the same as dbus_message_iter_get_args(). - * dbus_message_get_args() is the place to go for complete - * documentation. - * - * @see dbus_message_get_args - * @param iter the message iter - * @param error error to be filled in - * @param first_arg_type type of the first argument - * @param var_args return location for first argument, followed by list of type/location pairs - * @returns #FALSE if error was set - */ -dbus_bool_t -_dbus_message_iter_get_args_valist (DBusMessageIter *iter, - DBusError *error, - int first_arg_type, - va_list var_args) -{ - DBusMessageRealIter *real = (DBusMessageRealIter *)iter; - int spec_type, msg_type, i; - dbus_bool_t retval; - - _dbus_assert (_dbus_message_iter_check (real)); - - retval = FALSE; - - spec_type = first_arg_type; - i = 0; - - while (spec_type != DBUS_TYPE_INVALID) - { - msg_type = dbus_message_iter_get_arg_type (iter); - - if (msg_type != spec_type) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Argument %d is specified to be of type \"%s\", but " - "is actually of type \"%s\"\n", i, - _dbus_type_to_string (spec_type), - _dbus_type_to_string (msg_type)); - - goto out; - } - - if (dbus_type_is_basic (spec_type)) - { - DBusBasicValue *ptr; - - ptr = va_arg (var_args, DBusBasicValue*); - - _dbus_assert (ptr != NULL); - - _dbus_type_reader_read_basic (&real->u.reader, - ptr); - } - else if (spec_type == DBUS_TYPE_ARRAY) - { - int element_type; - int spec_element_type; - const DBusBasicValue **ptr; - int *n_elements_p; - DBusTypeReader array; - - spec_element_type = va_arg (var_args, int); - element_type = _dbus_type_reader_get_element_type (&real->u.reader); - - if (spec_element_type != element_type) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Argument %d is specified to be an array of \"%s\", but " - "is actually an array of \"%s\"\n", - i, - _dbus_type_to_string (spec_element_type), - _dbus_type_to_string (element_type)); - - goto out; - } - - if (dbus_type_is_fixed (spec_element_type)) - { - ptr = va_arg (var_args, const DBusBasicValue**); - n_elements_p = va_arg (var_args, int*); - - _dbus_assert (ptr != NULL); - _dbus_assert (n_elements_p != NULL); - - _dbus_type_reader_recurse (&real->u.reader, &array); - - _dbus_type_reader_read_fixed_multi (&array, - ptr, n_elements_p); - } - else if (spec_element_type == DBUS_TYPE_STRING || - spec_element_type == DBUS_TYPE_SIGNATURE || - spec_element_type == DBUS_TYPE_OBJECT_PATH) - { - char ***str_array_p; - int n_elements; - char **str_array; - - str_array_p = va_arg (var_args, char***); - n_elements_p = va_arg (var_args, int*); - - _dbus_assert (str_array_p != NULL); - _dbus_assert (n_elements_p != NULL); - - /* Count elements in the array */ - _dbus_type_reader_recurse (&real->u.reader, &array); - - n_elements = 0; - while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID) - { - ++n_elements; - _dbus_type_reader_next (&array); - } - - str_array = dbus_new0 (char*, n_elements + 1); - if (str_array == NULL) - { - _DBUS_SET_OOM (error); - goto out; - } - - /* Now go through and dup each string */ - _dbus_type_reader_recurse (&real->u.reader, &array); - - i = 0; - while (i < n_elements) - { - const char *s; - _dbus_type_reader_read_basic (&array, - &s); - - str_array[i] = _dbus_strdup (s); - if (str_array[i] == NULL) - { - dbus_free_string_array (str_array); - _DBUS_SET_OOM (error); - goto out; - } - - ++i; - - if (!_dbus_type_reader_next (&array)) - _dbus_assert (i == n_elements); - } - - _dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID); - _dbus_assert (i == n_elements); - _dbus_assert (str_array[i] == NULL); - - *str_array_p = str_array; - *n_elements_p = n_elements; - } -#ifndef DBUS_DISABLE_CHECKS - else - { - _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now\n", - _DBUS_FUNCTION_NAME); - goto out; - } -#endif - } -#ifndef DBUS_DISABLE_CHECKS - else - { - _dbus_warn ("you can only read arrays and basic types with %s for now\n", - _DBUS_FUNCTION_NAME); - goto out; - } -#endif - - spec_type = va_arg (var_args, int); - if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID) - { - dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, - "Message has only %d arguments, but more were expected", i); - goto out; - } - - i++; - } - - retval = TRUE; - - out: - - return retval; -} - /** * Initializes a #DBusMessageIter for appending arguments to the end * of a message. * * @todo If appending any of the arguments fails due to lack of - * memory, generally the message is hosed and you have to start over - * building the whole message. + * memory, the message is hosed and you have to start over building + * the whole message. * * @param message the message * @param iter pointer to an iterator to initialize @@ -2099,7 +2179,7 @@ _dbus_message_iter_append_check (DBusMessageRealIter *iter) if (iter->message->locked) { - _dbus_warn ("dbus append iterator can't be used: message is locked (has already been sent)\n"); + _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)\n"); return FALSE; } @@ -2322,6 +2402,11 @@ dbus_message_iter_close_container (DBusMessageIter *iter, * message successfully arrived at the remote end. Normally you know a * message was received when you receive the reply to it. * + * The flag is #FALSE by default, that is by default the other end is + * required to reply. + * + * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_REPLY_EXPECTED + * * @param message the message * @param no_reply #TRUE if no reply is desired */ @@ -2360,6 +2445,10 @@ dbus_message_get_no_reply (DBusMessage *message) * starting up, or fails to start up. In case of failure, the reply * will be an error. * + * The flag is set to #TRUE by default, i.e. auto starting is the default. + * + * On the protocol level this toggles #DBUS_HEADER_FLAG_NO_AUTO_START + * * @param message the message * @param auto_start #TRUE if auto-starting is desired */ @@ -2397,6 +2486,9 @@ dbus_message_get_auto_start (DBusMessage *message) * DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a signal is being * emitted from (for DBUS_MESSAGE_TYPE_SIGNAL). * + * The path must contain only valid characters as defined + * in the D-Bus specification. + * * @param message the message * @param object_path the path or #NULL to unset * @returns #FALSE if not enough memory @@ -2422,6 +2514,11 @@ dbus_message_set_path (DBusMessage *message, * DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted from (for * DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none. * + * See also dbus_message_get_path_decomposed(). + * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the path (should not be freed) or #NULL */ @@ -2441,7 +2538,9 @@ dbus_message_get_path (DBusMessage *message) } /** - * Checks if the message has a path + * Checks if the message has a particular object path. The object + * path is the destination object for a method call or the emitting + * object for a signal. * * @param message the message * @param path the path name @@ -2482,6 +2581,8 @@ dbus_message_has_path (DBusMessage *message, * So the path "/foo/bar" becomes { "foo", "bar", NULL } * and the path "/" becomes { NULL }. * + * See also dbus_message_get_path(). + * * @todo this could be optimized by using the len from the message * instead of calling strlen() again * @@ -2516,6 +2617,9 @@ dbus_message_get_path_decomposed (DBusMessage *message, * the interface a signal is being emitted from * (for DBUS_MESSAGE_TYPE_SIGNAL). * + * The interface name must contain only valid characters as defined + * in the D-Bus specification. + * * @param message the message * @param interface the interface or #NULL to unset * @returns #FALSE if not enough memory @@ -2543,6 +2647,9 @@ dbus_message_set_interface (DBusMessage *message, * The interface name is fully-qualified (namespaced). * Returns #NULL if none. * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the message interface (should not be freed) or #NULL */ @@ -2566,7 +2673,7 @@ dbus_message_get_interface (DBusMessage *message) * * @param message the message * @param interface the interface name - * @returns #TRUE if there is a interface field in the header + * @returns #TRUE if the interface field in the header matches */ dbus_bool_t dbus_message_has_interface (DBusMessage *message, @@ -2597,7 +2704,9 @@ dbus_message_has_interface (DBusMessage *message, * Sets the interface member being invoked * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted * (DBUS_MESSAGE_TYPE_SIGNAL). - * The interface name is fully-qualified (namespaced). + * + * The member name must contain only valid characters as defined + * in the D-Bus specification. * * @param message the message * @param member the member or #NULL to unset @@ -2624,6 +2733,9 @@ dbus_message_set_member (DBusMessage *message, * (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted * (DBUS_MESSAGE_TYPE_SIGNAL). Returns #NULL if none. * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the member name (should not be freed) or #NULL */ @@ -2678,6 +2790,9 @@ dbus_message_has_member (DBusMessage *message, * Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR). * The name is fully-qualified (namespaced). * + * The error name must contain only valid characters as defined + * in the D-Bus specification. + * * @param message the message * @param error_name the name or #NULL to unset * @returns #FALSE if not enough memory @@ -2702,6 +2817,9 @@ dbus_message_set_error_name (DBusMessage *message, * Gets the error name (DBUS_MESSAGE_TYPE_ERROR only) * or #NULL if none. * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the error name (should not be freed) or #NULL */ @@ -2726,6 +2844,9 @@ dbus_message_get_error_name (DBusMessage *message) * assigned by the bus to each connection, or a well-known name * specified in advance. * + * The destination name must contain only valid characters as defined + * in the D-Bus specification. + * * @param message the message * @param destination the destination name or #NULL to unset * @returns #FALSE if not enough memory @@ -2749,6 +2870,9 @@ dbus_message_set_destination (DBusMessage *message, /** * Gets the destination of a message or #NULL if there is none set. * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the message destination (should not be freed) or #NULL */ @@ -2770,6 +2894,13 @@ dbus_message_get_destination (DBusMessage *message) /** * Sets the message sender. * + * The sender must be a valid bus name as defined in the D-Bus + * specification. + * + * Usually you don't want to call this. The message bus daemon will + * call it to set the origin of each message. If you aren't implementing + * a message bus daemon you shouldn't need to set the sender. + * * @param message the message * @param sender the sender or #NULL to unset * @returns #FALSE if not enough memory @@ -2795,6 +2926,13 @@ dbus_message_set_sender (DBusMessage *message, * message, or #NULL if unknown or inapplicable. The sender is filled * in by the message bus. * + * Note, the returned sender is always the unique bus name. + * Connections may own multiple other bus names, but those + * are not found in the sender field. + * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the unique name of the sender or #NULL */ @@ -2818,13 +2956,16 @@ dbus_message_get_sender (DBusMessage *message) * message payload. The signature includes only "in" arguments for * #DBUS_MESSAGE_TYPE_METHOD_CALL and only "out" arguments for * #DBUS_MESSAGE_TYPE_METHOD_RETURN, so is slightly different from - * what you might expect (it does not include the signature of the + * what you might expect (that is, it does not include the signature of the * entire C++-style method). * * The signature is a string made up of type codes such as * #DBUS_TYPE_INT32. The string is terminated with nul (nul is also * the value of #DBUS_TYPE_INVALID). * + * The returned string becomes invalid if the message is + * modified, since it points into the wire-marshaled message data. + * * @param message the message * @returns the type signature */ @@ -2907,9 +3048,7 @@ dbus_message_is_method_call (DBusMessage *message, /** * 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. If the - * interface field in the message is missing, it is assumed to match - * any interface you pass in to this function. + * has a different interface or member field, returns #FALSE. * * @param message the message * @param interface the name to check (must not be #NULL) @@ -3064,7 +3203,7 @@ dbus_message_has_signature (DBusMessage *message, /** * 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_TYPE_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. @@ -3081,7 +3220,7 @@ dbus_message_has_signature (DBusMessage *message, * * @param error the error to set * @param message the message to set it from - * @returns #TRUE if dbus_message_get_is_error() returns #TRUE for the message + * @returns #TRUE if the message had type #DBUS_MESSAGE_TYPE_ERROR */ dbus_bool_t dbus_set_error_from_message (DBusError *error, diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h index f0e80a67..b0351758 100644 --- a/dbus/dbus-message.h +++ b/dbus/dbus-message.h @@ -163,7 +163,12 @@ void dbus_message_iter_recurse (DBusMessageIter *iter, DBusMessageIter *sub); void dbus_message_iter_get_basic (DBusMessageIter *iter, void *value); +#ifndef DBUS_DISABLE_DEPRECATED +/* This function returns the wire protocol size of the array in bytes, + * you do not want to know that probably + */ int dbus_message_iter_get_array_len (DBusMessageIter *iter); +#endif void dbus_message_iter_get_fixed_array (DBusMessageIter *iter, void *value, int *n_elements); diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c index 72784660..e4b71e26 100644 --- a/dbus/dbus-timeout.c +++ b/dbus/dbus-timeout.c @@ -384,6 +384,9 @@ _dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list, * Types and functions related to DBusTimeout. A timeout * represents a timeout that the main loop needs to monitor, * as in Qt's QTimer or GLib's g_timeout_add(). + * + * Use dbus_connection_set_timeout_functions() or dbus_server_set_timeout_functions() + * to be notified when libdbus needs to add or remove timeouts. * * @{ */ diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c index a7a5adba..ebbb7ed2 100644 --- a/dbus/dbus-watch.c +++ b/dbus/dbus-watch.c @@ -465,6 +465,9 @@ _dbus_watch_set_handler (DBusWatch *watch, * Types and functions related to DBusWatch. A watch represents * a file descriptor that the main loop needs to monitor, * as in Qt's QSocketNotifier or GLib's g_io_add_watch(). + * + * Use dbus_connection_set_watch_functions() or dbus_server_set_watch_functions() + * to be notified when libdbus needs to add or remove watches. * * @{ */ diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 41d3fb9b..977734d7 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -1184,7 +1184,8 @@ A signal emission is simply a single message of type SIGNAL. It must have three header fields: PATH giving the object the signal was emitted from, plus INTERFACE and MEMBER giving - the fully-qualified name of the signal. + the fully-qualified name of the signal. The INTERFACE header is required + for signals, though it is optional for method calls. @@ -3014,7 +3015,9 @@ interface An interface name (see ) Match messages sent over or to a particular interface. An example of an - interface match is interface='org.freedesktop.Hal.Manager' + interface match is interface='org.freedesktop.Hal.Manager'. + If a message omits the interface header, it must not match any rule + that specifies this key. member @@ -3035,12 +3038,13 @@ example of a destination match is destination=':1.0' - arg[1, 2, 3, ...] + arg[0, 1, 2, 3, ...] Any string Arg matches are special and are used for further restricting the match based on the arguments in the body of a message. As of this time only string arguments can be matched. An example of an argument match - would be arg3='Foo'. + would be arg3='Foo'. Only argument indexes from 0 to 63 should be + accepted. -- cgit