2003-08-12 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Tue, 12 Aug 2003 04:15:49 +0000 (04:15 +0000)
committerHavoc Pennington <hp@redhat.com>
Tue, 12 Aug 2003 04:15:49 +0000 (04:15 +0000)
* 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.

13 files changed:
ChangeLog
bus/dispatch.c
bus/driver.c
dbus/dbus-address.c
dbus/dbus-connection.c
dbus/dbus-errors.c
dbus/dbus-errors.h
dbus/dbus-server-debug-pipe.c
dbus/dbus-server-unix.c
dbus/dbus-server.c
dbus/dbus-string.c
dbus/dbus-string.h
dbus/dbus-sysdeps.h

index b786b4e..4396c9a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 6902da6..e8f0c9b 100644 (file)
@@ -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
index 6e0024b..22e36e0 100644 (file)
@@ -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);
   
index bf9dbc3..89dac41 100644 (file)
@@ -25,6 +25,7 @@
 #include "dbus-address.h"
 #include "dbus-internals.h"
 #include "dbus-list.h"
+#include "dbus-string.h"
 
 /**
  * @defgroup DBusAddress Address parsing
index 17563f3..ba5601e 100644 (file)
@@ -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);
 
index 3cf5236..82e4802 100644 (file)
@@ -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);      
 }
 
 /** @} */
index 8d8e16e..ca398a0 100644 (file)
@@ -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);
index 15b7860..6a66391 100644 (file)
@@ -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 036446a..487d60e 100644 (file)
@@ -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 1c9d53f..29e20a5 100644 (file)
@@ -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 60c2546..f4f7a2a 100644 (file)
@@ -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
index 8fa1380..732359a 100644 (file)
 
 #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);
index cfe0cd2..bfdcfb0 100644 (file)
@@ -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)))