2003-04-03 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Thu, 3 Apr 2003 21:56:22 +0000 (21:56 +0000)
committerHavoc Pennington <hp@redhat.com>
Thu, 3 Apr 2003 21:56:22 +0000 (21:56 +0000)
* bus/activation.c (load_directory): fix up memleaks
(bus_activation_entry_free): free the entry

* dbus/dbus-bus.c (dbus_bus_acquire_service): return an error if
we get one from the message bus; fix memleaks.

* dbus/dbus-message.c (dbus_set_error_from_message): new function

ChangeLog
bus/activation.c
configure.in
dbus/dbus-bus.c
dbus/dbus-message.c
dbus/dbus-message.h
doc/TODO
doc/dbus-specification.sgml
test/Makefile.am
test/test-service.c

index 3772119..a164df0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-04-03  Havoc Pennington  <hp@redhat.com>
+
+       * bus/activation.c (load_directory): fix up memleaks
+       (bus_activation_entry_free): free the entry
+
+       * dbus/dbus-bus.c (dbus_bus_acquire_service): return an error if
+       we get one from the message bus; fix memleaks.
+
+       * dbus/dbus-message.c (dbus_set_error_from_message): new function
+
 2003-04-03  Havoc Pennington  <hp@pobox.com>
 
        * bus/config-parser.c (bus_config_parser_unref): free 
index eb56a74..ef5c173 100644 (file)
@@ -110,6 +110,8 @@ bus_activation_entry_free (BusActivationEntry *entry)
   
   dbus_free (entry->name);
   dbus_free (entry->exec);
+
+  dbus_free (entry);
 }
 
 static dbus_bool_t
@@ -197,7 +199,8 @@ load_directory (BusActivation *activation,
   DBusString full_path;
   BusDesktopFile *desktop_file;
   DBusError tmp_error;
-
+  dbus_bool_t retval;
+  
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
   _dbus_string_init_const (&dir, directory);
@@ -218,14 +221,16 @@ load_directory (BusActivation *activation,
       return FALSE;
     }
 
-  /* from this point it's safe to "goto failed" */
+  retval = FALSE;
+  
+  /* from this point it's safe to "goto out" */
   
   iter = _dbus_directory_open (&dir, error);
   if (iter == NULL)
     {
       _dbus_verbose ("Failed to open directory %s: %s\n",
                      directory, error ? error->message : "unknown");
-      goto failed;
+      goto out;
     }
   
   /* Now read the files */
@@ -240,7 +245,7 @@ load_directory (BusActivation *activation,
           !_dbus_concat_dir_and_file (&full_path, &filename))
         {
           BUS_SET_OOM (error);
-          goto failed;
+          goto out;
         }
       
       if (!_dbus_string_ends_with_c_str (&filename, ".service"))
@@ -261,7 +266,7 @@ load_directory (BusActivation *activation,
           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
             {
               dbus_move_error (&tmp_error, error);
-              goto failed;
+              goto out;
             }
           
          dbus_error_free (&tmp_error);
@@ -279,7 +284,7 @@ load_directory (BusActivation *activation,
           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
             {
               dbus_move_error (&tmp_error, error);
-              goto failed;
+              goto out;
             }
 
           dbus_error_free (&tmp_error);
@@ -296,13 +301,16 @@ load_directory (BusActivation *activation,
   if (dbus_error_is_set (&tmp_error))
     {
       dbus_move_error (&tmp_error, error);
-      goto failed;
+      goto out;
     }
   
-  return TRUE;
+  retval = TRUE;
   
- failed:
-  _DBUS_ASSERT_ERROR_IS_SET (error);
+ out:
+  if (!retval)
+    _DBUS_ASSERT_ERROR_IS_SET (error);
+  else
+    _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
   if (iter != NULL)
     _dbus_directory_close (iter);
@@ -311,7 +319,7 @@ load_directory (BusActivation *activation,
   _dbus_string_free (&filename);
   _dbus_string_free (&full_path);
   
-  return FALSE;
+  return retval;
 }
 
 BusActivation*
index fbf60d7..076b74c 100644 (file)
@@ -403,6 +403,15 @@ fi
 
 AM_CONDITIONAL(DBUS_INIT_SCRIPTS_RED_HAT, test x$with_init_scripts = xredhat)
 
+#### Tell tests where to find certain stuff in builddir
+ABSOLUTE_TOP_BUILDDIR=`cd ${ac_top_builddir}. && pwd`
+
+TEST_SERVICE_BINARY=${ABSOLUTE_TOP_BUILDDIR}/test/test-service
+AC_SUBST(TEST_SERVICE_BINARY)
+
+TEST_SERVICE_DIR=${ABSOLUTE_TOP_BUILDDIR}/test/data/valid-service-files
+AC_SUBST(TEST_SERVICE_DIR)
+
 AC_OUTPUT([
 Doxyfile
 bus/system.conf
@@ -417,6 +426,8 @@ test/Makefile
 doc/Makefile
 dbus-1.0.pc
 dbus-glib-1.0.pc
+test/data/valid-config-files/debug-allow-all.conf
+test/data/valid-service-files/debug-echo.service
 ])
 
 dnl ==========================================================================
index dc1762e..df883f5 100644 (file)
@@ -534,7 +534,7 @@ dbus_bus_acquire_service (DBusConnection *connection,
                           DBusError      *error)
 {
   DBusMessage *message, *reply;
-  int service_result;
+  dbus_uint32_t service_result;
   
   message = dbus_message_new (DBUS_SERVICE_DBUS,
                               DBUS_MESSAGE_ACQUIRE_SERVICE);
@@ -564,16 +564,26 @@ dbus_bus_acquire_service (DBusConnection *connection,
     {
       _DBUS_ASSERT_ERROR_IS_SET (error);
       return -1;
-    }
+    }  
 
+  if (dbus_set_error_from_message (error, reply))
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      dbus_message_unref (reply);
+      return -1;
+    }
+  
   if (!dbus_message_get_args (reply, error,
                               DBUS_TYPE_UINT32, &service_result,
                               0))
     {
       _DBUS_ASSERT_ERROR_IS_SET (error);
+      dbus_message_unref (reply);
       return -1;
     }
 
+  dbus_message_unref (reply);
+  
   return service_result;
 }
 
index 39ed394..46c4c40 100644 (file)
@@ -2381,6 +2381,45 @@ dbus_message_sender_is (DBusMessage  *message,
     return FALSE;
 }
 
+/**
+ * Sets a #DBusError based on the contents of the given
+ * message. The error is only set if the message
+ * is an error message, as in dbus_message_get_is_error().
+ * 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.
+ *
+ * The return value indicates whether the error was set (the error is
+ * set if and only if the message is an error message).
+ * So you can check for an error reply and convert it to DBusError
+ * in one go.
+ *
+ * @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
+ */
+dbus_bool_t
+dbus_set_error_from_message (DBusError   *error,
+                             DBusMessage *message)
+{
+  char *str;
+  
+  if (!dbus_message_get_is_error (message))
+    return FALSE;
+
+  str = NULL;
+  dbus_message_get_args (message, NULL,
+                         DBUS_TYPE_STRING, &str,
+                         DBUS_TYPE_INVALID);
+
+  dbus_set_error (error, dbus_message_get_name (message),
+                  str ? "%s" : NULL, str);
+
+  dbus_free (str);
+  
+  return TRUE;
+}
+
 /** @} */
 
 /**
index be752c9..4733786 100644 (file)
@@ -148,6 +148,11 @@ dbus_bool_t   dbus_message_iter_get_string_array  (DBusMessageIter   *iter,
 dbus_bool_t   dbus_message_iter_get_dict          (DBusMessageIter   *iter,
                                                   DBusDict         **dict);
 
+
+
+dbus_bool_t  dbus_set_error_from_message  (DBusError    *error,
+                                           DBusMessage  *message);
+
 DBUS_END_DECLS;
 
 #endif /* DBUS_MESSAGE_H */
index ebbff3a..f6c539d 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
 
  - Abstract the user database, so you can use something other than the system password 
    database.
+
+ - The convenience functions in dbus-bus.h should perhaps have
+   the signatures that they would have if they were autogenerated
+   stubs. e.g. the acquire service function. We should also evaluate 
+   which of these functions to include, in light of the fact that 
+   GLib/Qt native stubs will probably also exist.
+
+ - The message handler interface needs rethinking, perhaps handlers should be able 
+   to return an error that automatically gets turned into a message; most likely 
+   some basic spec'ing out of the GLib/Qt level stubs/skels stuff will be 
+   needed to understand the right approach.
index 7e2fcb3..3c41068 100644 (file)
             <tbody>
               <row>
                 <entry>0x1</entry>
-                <entry>This message is an error reply.</entry>
+                <entry>This message is an error reply. If the first argument exists and is a string, it is an error message.</entry>
               </row>
             </tbody>
           </tgroup>
         number of the message being replied to.
       </para>
       <para>
-        If an error occurs, an error reply may be sent in place of the 
-        standard reply. Error replies can be identified by a special 
-        header flag, see <xref linkend="message-protocol-header-encoding">.
-          Error replies have a name which reflects the type of 
-          error that occurred. Error replies would generally 
-          be mapped to exceptions in a programming language.
+        If an error occurs, an error reply may be sent in place of the standard
+        reply. Error replies can be identified by a special header flag, see
+        <xref linkend="message-protocol-header-encoding">.  Error replies have a
+        name which reflects the type of error that occurred. Error replies would
+        generally be mapped to exceptions in a programming language.  If an
+        error reply has a first argument, and that argument has type STRING,
+        then the argument must be an error message.
       </para>
       <para>
         [FIXME discuss mapping of broadcast messages + matching rules 
             # Sample service description file
             [D-BUS Service]
             Name=org.gnome.ConfigurationDatabase
-            Exec=gconfd-2
+            Exec=/usr/libexec/gconfd-2
           </programlisting>
        </figure>
       </para>
index 46a66db..d0429aa 100644 (file)
@@ -61,9 +61,10 @@ TESTDIRS=                                    \
        data/auth                               \
        data/sha-1                              \
        data/valid-config-files                 \
-       data/valid-config-files/basic.d
+       data/valid-config-files/basic.d         \
+       data/valid-service-files
 
-FIND_TESTS=find -name "*.message" -o -name "*.message-raw" -o -name "*.auth-script" -o -name "*.sha1" -o -name "*.txt" -o -name "*.conf"
+FIND_TESTS=find -name "*.message" -o -name "*.message-raw" -o -name "*.auth-script" -o -name "*.sha1" -o -name "*.txt" -o -name "*.conf" -o -name "*.service"
 
 dist-hook:
        for D in $(TESTDIRS); do                                                \
index a4dff0b..49048f6 100644 (file)
@@ -1,15 +1,74 @@
 #include <dbus/dbus.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include "watch.h"
 
+static void
+die (const char *message)
+{
+  fprintf (stderr, "%s", message);
+  exit (1);
+}
+
+static DBusHandlerResult
+echo_handler (DBusMessageHandler *handler,
+              DBusConnection     *connection,
+              DBusMessage        *message,
+              void               *user_data)
+{
+  DBusError error;
+  DBusMessage *reply;
+  char *s;
+  
+  dbus_error_init (&error);
+  
+  if (!dbus_message_get_args (message,
+                              &error,
+                              DBUS_TYPE_STRING, &s,
+                              DBUS_TYPE_INVALID))
+    {
+      reply = dbus_message_new_error_reply (message,
+                                            error.name,
+                                            error.message);
+
+      if (reply == NULL)
+        die ("No memory\n");
+
+      if (!dbus_connection_send (connection, reply, NULL))
+        die ("No memory\n");
+
+      dbus_message_unref (reply);
+
+      return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+    }
+
+  reply = dbus_message_new_reply (message);
+  if (reply == NULL)
+    die ("No memory\n");
+
+  if (!dbus_message_append_string (reply, s))
+    die ("No memory");
+
+  if (!dbus_connection_send (connection, reply, NULL))
+    die ("No memory\n");
+  
+  dbus_free (s);
+  
+  dbus_message_unref (reply);
+    
+  return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
+}
+
 int
 main (int    argc,
       char **argv)
 {
   DBusConnection *connection;
   DBusError error;
-  DBusMessage *message;
-
+  DBusMessageHandler *handler;
+  const char *to_handle[] = { "org.freedesktop.DBus.TestSuiteEcho" };
+  int result;
+  
   dbus_error_init (&error);
   connection = dbus_bus_get (DBUS_BUS_ACTIVATION, &error);
   if (connection == NULL)
@@ -21,10 +80,31 @@ main (int    argc,
     }
 
   setup_connection (connection);
+
+  handler = dbus_message_handler_new (echo_handler, NULL, NULL);
+  if (handler == NULL)
+    die ("No memory");
+  
+  if (!dbus_connection_register_handler (connection, handler, to_handle, 1))
+    die ("No memory");
+
+  result = dbus_bus_acquire_service (connection, "org.freedesktop.DBus.TestSuiteEchoService",
+                                     0, &error);
+  if (dbus_error_is_set (&error))
+    {
+      fprintf (stderr, "Failed to acquire service: %s\n",
+               error.message);
+      dbus_error_free (&error);
+      return 1;
+    }
   
   do_mainloop ();
 
   dbus_connection_unref (connection);
+
+  dbus_message_handler_unref (handler);
+  
+  dbus_shutdown ();
   
   return 0;
 }