From 1d1b0f20a467cf1cbdcaf81fbad3a111bcff6c48 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Tue, 12 Aug 2003 04:15:49 +0000 Subject: 2003-08-12 Havoc Pennington * 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. --- dbus/dbus-address.c | 1 + dbus/dbus-connection.c | 103 ++++++++++++++++++++++++++++++++++++++---- dbus/dbus-errors.c | 60 ++++++++++++++---------- dbus/dbus-errors.h | 2 +- dbus/dbus-server-debug-pipe.c | 1 + dbus/dbus-server-unix.c | 1 + dbus/dbus-server.c | 1 + dbus/dbus-string.c | 55 ++++++++++++++++++++++ dbus/dbus-string.h | 11 ++++- dbus/dbus-sysdeps.h | 3 +- 10 files changed, 200 insertions(+), 38 deletions(-) (limited to 'dbus') 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 -#include #include /** @@ -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 #include 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 +/* for vsnprintf */ +#include #include "dbus-marshal.h" #define DBUS_CAN_USE_DBUS_STRING_PRIVATE 1 #include "dbus-string-private.h" @@ -986,6 +988,59 @@ _dbus_string_append_8_aligned (DBusString *str, return TRUE; } +/** + * 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. * 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 #include +#include -DBUS_BEGIN_DECLS; +#include -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 #include /* 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))) -- cgit