diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | bus/dispatch.c | 12 | ||||
-rw-r--r-- | bus/driver.c | 2 | ||||
-rw-r--r-- | dbus/dbus-address.c | 1 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 103 | ||||
-rw-r--r-- | dbus/dbus-errors.c | 60 | ||||
-rw-r--r-- | dbus/dbus-errors.h | 2 | ||||
-rw-r--r-- | dbus/dbus-server-debug-pipe.c | 1 | ||||
-rw-r--r-- | dbus/dbus-server-unix.c | 1 | ||||
-rw-r--r-- | dbus/dbus-server.c | 1 | ||||
-rw-r--r-- | dbus/dbus-string.c | 55 | ||||
-rw-r--r-- | dbus/dbus-string.h | 11 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 3 |
13 files changed, 227 insertions, 43 deletions
@@ -1,3 +1,21 @@ +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 diff --git a/bus/dispatch.c b/bus/dispatch.c index 6902da65..e8f0c9ba 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -100,7 +100,7 @@ bus_dispatch_broadcast_message (BusTransaction *transaction, return TRUE; } -static void +static DBusHandlerResult bus_dispatch (DBusConnection *connection, DBusMessage *message) { @@ -108,6 +108,9 @@ bus_dispatch (DBusConnection *connection, DBusError error; BusTransaction *transaction; BusContext *context; + DBusHandlerResult result; + + result = DBUS_HANDLER_RESULT_HANDLED; transaction = NULL; dbus_error_init (&error); @@ -145,6 +148,7 @@ bus_dispatch (DBusConnection *connection, /* DBusConnection also handles some of these automatically, we leave * it to do so. */ + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; goto out; } @@ -295,6 +299,8 @@ bus_dispatch (DBusConnection *connection, } dbus_connection_unref (connection); + + return result; } static DBusHandlerResult @@ -303,9 +309,7 @@ bus_dispatch_message_handler (DBusMessageHandler *handler, DBusMessage *message, void *user_data) { - bus_dispatch (connection, message); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return bus_dispatch (connection, message); } static void diff --git a/bus/driver.c b/bus/driver.c index 6e0024b0..22e36e0a 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -662,7 +662,7 @@ bus_driver_handle_message (DBusConnection *connection, _dbus_verbose ("No driver handler for %s\n", name); - dbus_set_error (error, DBUS_ERROR_UNKNOWN_MESSAGE, + dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD, "%s does not understand message %s", DBUS_SERVICE_DBUS, name); diff --git a/dbus/dbus-address.c b/dbus/dbus-address.c index bf9dbc3b..89dac41e 100644 --- a/dbus/dbus-address.c +++ b/dbus/dbus-address.c @@ -25,6 +25,7 @@ #include "dbus-address.h" #include "dbus-internals.h" #include "dbus-list.h" +#include "dbus-string.h" /** * @defgroup DBusAddress Address parsing diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 17563f35..ba5601e3 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -36,6 +36,7 @@ #include "dbus-protocol.h" #include "dbus-dataslot.h" #include "dbus-object-registry.h" +#include "dbus-string.h" #if 0 #define CONNECTION_LOCK(connection) do { \ @@ -1942,6 +1943,8 @@ dbus_connection_borrow_message (DBusConnection *connection) 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 @@ -1977,6 +1980,8 @@ dbus_connection_return_message (DBusConnection *connection, { _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); @@ -2005,6 +2010,8 @@ dbus_connection_steal_borrowed_message (DBusConnection *connection, _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); @@ -2074,6 +2081,22 @@ _dbus_connection_pop_message_unlocked (DBusConnection *connection) 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_name (message_link->data), + connection, connection->n_incoming); +} /** * Returns the first-received message from the incoming message queue, @@ -2360,7 +2383,7 @@ dbus_connection_dispatch (DBusConnection *connection) CONNECTION_LOCK (connection); if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) - /* FIXME */ ; + goto out; /* Did a reply we were waiting on get filtered? */ if (reply_handler_data && result == DBUS_HANDLER_RESULT_HANDLED) @@ -2405,22 +2428,84 @@ dbus_connection_dispatch (DBusConnection *connection) message); CONNECTION_LOCK (connection); - if (result == DBUS_HANDLER_RESULT_HANDLED) + + if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) goto out; - if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) - /* FIXME */ ; + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) + { + DBusMessage *reply; + DBusString str; + DBusPreallocatedSend *preallocated; + + _dbus_verbose (" sending error %s\n", + DBUS_ERROR_UNKNOWN_METHOD); + + if (!_dbus_string_init (&str)) + { + result = DBUS_HANDLER_RESULT_NEED_MEMORY; + goto out; + } + + if (!_dbus_string_append_printf (&str, + "Method \"%s\" doesn't exist\n", + dbus_message_get_name (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); + + 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); 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 + { + _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); diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c index 3cf52363..82e48025 100644 --- a/dbus/dbus-errors.c +++ b/dbus/dbus-errors.c @@ -23,8 +23,8 @@ */ #include "dbus-errors.h" #include "dbus-internals.h" +#include "dbus-string.h" #include <stdarg.h> -#include <stdio.h> #include <string.h> /** @@ -292,9 +292,6 @@ dbus_error_is_set (const DBusError *error) * * @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 +303,9 @@ dbus_set_error (DBusError *error, ...) { DBusRealError *real; + DBusString str; va_list args; - int message_length; - char *message; - char c; - + if (error == NULL) return; @@ -321,31 +316,46 @@ dbus_set_error (DBusError *error, _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); + if (!_dbus_string_init (&str)) + goto nomem; - message = dbus_malloc (message_length); - - 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); } /** @} */ diff --git a/dbus/dbus-errors.h b/dbus/dbus-errors.h index 8d8e16ec..ca398a0b 100644 --- a/dbus/dbus-errors.h +++ b/dbus/dbus-errors.h @@ -72,7 +72,7 @@ struct DBusError #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" void dbus_error_init (DBusError *error); diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c index 15b78608..6a66391e 100644 --- a/dbus/dbus-server-debug-pipe.c +++ b/dbus/dbus-server-debug-pipe.c @@ -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 diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index 036446af..487d60ec 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -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> diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 1c9d53f0..29e20a55 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -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 diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 60c25461..f4f7a2ad 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -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" @@ -987,6 +989,59 @@ _dbus_string_append_8_aligned (DBusString *str, } /** + * 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) +{ + DBUS_STRING_PREAMBLE (str); + int len; + char c; + + /* 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 diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 8fa13805..732359a0 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -28,10 +28,11 @@ #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; struct DBusString { @@ -111,6 +112,12 @@ dbus_bool_t _dbus_string_append_4_aligned (DBusString *str, 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); diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index cfe0cd25..bfdcfb0a 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -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_BEGIN_DECLS; * 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))) |