diff options
-rw-r--r-- | .gitignore | 9 | ||||
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | bus/.gitignore | 4 | ||||
-rw-r--r-- | dbus/dbus-connection.c | 125 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 13 | ||||
-rw-r--r-- | dbus/dbus-errors.c | 2 | ||||
-rw-r--r-- | dbus/dbus-object-tree.c | 53 | ||||
-rw-r--r-- | dbus/dbus-object-tree.h | 3 | ||||
-rw-r--r-- | dbus/dbus-protocol.h | 2 | ||||
-rw-r--r-- | test/data/invalid-service-files-system/.gitignore | 1 | ||||
-rw-r--r-- | test/data/valid-config-files-system/.gitignore | 1 | ||||
-rw-r--r-- | test/data/valid-service-files-system/.gitignore | 1 | ||||
-rw-r--r-- | test/data/valid-service-files/.gitignore | 7 | ||||
-rw-r--r-- | test/name-test/.gitignore | 2 |
14 files changed, 206 insertions, 30 deletions
@@ -1,10 +1,19 @@ +*.orig +*.rej +*.o +*~ +compile +config.cache config.log config.status config.sub configure +depcomp *.pc +install-sh libtool ltmain.sh +missing stamp-h1 stamp-h stamp-h.in @@ -1,3 +1,16 @@ +2007-10-10 Simon McVittie <simon.mcvittie@collabora.co.uk> + + * dbus/dbus-errors.c, dbus/dbus-protocol.h: Add new error + org.freedesktop.DBus.Error.ObjectPathInUse + * dbus/dbus-object-tree.h, dbus/dbus-object-tree.c, + dbus/dbus-connection.c, dbus/dbus-connection.h: add new functions + dbus_connection_try_register_object_path and + dbus_connection_try_register_fallback, which raise ObjectPathInUse + rather than asserting, to make object path registration less painful + for bindings + * .gitignore: add various things that weren't in .cvsignore because + CVS implicitly ignored them; generally bring up to date + 2007-10-09 Simon McVittie <simon.mcvittie@collabora.co.uk> * doc/dbus-specification.xml: Specifically forbid empty structs (#7969) diff --git a/bus/.gitignore b/bus/.gitignore index 21817b8e..0b67447d 100644 --- a/bus/.gitignore +++ b/bus/.gitignore @@ -7,6 +7,8 @@ Makefile.in dbus-daemon dbus-daemon-activation-helper dbus-daemon-activation-helper-test +dbus-daemon-launch-helper +dbus-daemon-launch-helper-test *.bb *.bbg *.da @@ -17,3 +19,5 @@ messagebus session.conf system.conf dbus-daemon.1 +bus-test-launch-helper +bus-test-system diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index cc26b75c..b6ecc36d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -5265,6 +5265,53 @@ dbus_connection_remove_filter (DBusConnection *connection, * Registers a handler for a given path in the object hierarchy. * The given vtable handles messages sent to exactly the given path. * + * @param connection the connection + * @param path a '/' delimited string of path elements + * @param vtable the virtual table + * @param user_data data to pass to functions in the vtable + * @param error address where an error can be returned + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_ADDRESS_IN_USE) is reported + */ +dbus_bool_t +dbus_connection_try_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error) +{ + char **decomposed_path; + dbus_bool_t retval; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (path != NULL, FALSE); + _dbus_return_val_if_fail (path[0] == '/', FALSE); + _dbus_return_val_if_fail (vtable != NULL, FALSE); + + if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) + return FALSE; + + CONNECTION_LOCK (connection); + + retval = _dbus_object_tree_register (connection->objects, + FALSE, + (const char **) decomposed_path, vtable, + user_data, error); + + CONNECTION_UNLOCK (connection); + + dbus_free_string_array (decomposed_path); + + return retval; +} + +/** + * Registers a handler for a given path in the object hierarchy. + * The given vtable handles messages sent to exactly the given path. + * + * It is a bug to call this function for object paths which already + * have a handler. Use dbus_connection_try_register_object_path() if this + * might be the case. * * @param connection the connection * @param path a '/' delimited string of path elements @@ -5280,12 +5327,15 @@ dbus_connection_register_object_path (DBusConnection *connection, { char **decomposed_path; dbus_bool_t retval; - + DBusError error; + _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (path != NULL, FALSE); _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); + dbus_error_init (&error); + if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) return FALSE; @@ -5294,12 +5344,19 @@ dbus_connection_register_object_path (DBusConnection *connection, retval = _dbus_object_tree_register (connection->objects, FALSE, (const char **) decomposed_path, vtable, - user_data); + user_data, &error); CONNECTION_UNLOCK (connection); dbus_free_string_array (decomposed_path); + if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE)) + { + _dbus_warn ("%s\n", error.message); + dbus_error_free (&error); + return FALSE; + } + return retval; } @@ -5313,6 +5370,56 @@ dbus_connection_register_object_path (DBusConnection *connection, * @param path a '/' delimited string of path elements * @param vtable the virtual table * @param user_data data to pass to functions in the vtable + * @param error address where an error can be returned + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_ADDRESS_IN_USE) is reported + */ +dbus_bool_t +dbus_connection_try_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error) +{ + char **decomposed_path; + dbus_bool_t retval; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (path != NULL, FALSE); + _dbus_return_val_if_fail (path[0] == '/', FALSE); + _dbus_return_val_if_fail (vtable != NULL, FALSE); + + if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) + return FALSE; + + CONNECTION_LOCK (connection); + + retval = _dbus_object_tree_register (connection->objects, + TRUE, + (const char **) decomposed_path, vtable, + user_data, error); + + CONNECTION_UNLOCK (connection); + + dbus_free_string_array (decomposed_path); + + return retval; +} + +/** + * Registers a fallback handler for a given subsection of the object + * hierarchy. The given vtable handles messages at or below the given + * path. You can use this to establish a default message handling + * policy for a whole "subdirectory." + * + * It is a bug to call this function for object paths which already + * have a handler. Use dbus_connection_try_register_fallback() if this + * might be the case. + * + * @param connection the connection + * @param path a '/' delimited string of path elements + * @param vtable the virtual table + * @param user_data data to pass to functions in the vtable * @returns #FALSE if not enough memory */ dbus_bool_t @@ -5323,12 +5430,15 @@ dbus_connection_register_fallback (DBusConnection *connection, { char **decomposed_path; dbus_bool_t retval; - + DBusError error; + _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (path != NULL, FALSE); _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); + dbus_error_init (&error); + if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) return FALSE; @@ -5337,12 +5447,19 @@ dbus_connection_register_fallback (DBusConnection *connection, retval = _dbus_object_tree_register (connection->objects, TRUE, (const char **) decomposed_path, vtable, - user_data); + user_data, &error); CONNECTION_UNLOCK (connection); dbus_free_string_array (decomposed_path); + if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE)) + { + _dbus_warn ("%s\n", error.message); + dbus_error_free (&error); + return FALSE; + } + return retval; } diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index 2efda44e..5d7e493b 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -321,10 +321,23 @@ struct DBusObjectPathVTable void (* dbus_internal_pad4) (void *); /**< Reserved for future expansion */ }; +dbus_bool_t dbus_connection_try_register_object_path (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + dbus_bool_t dbus_connection_register_object_path (DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, void *user_data); + +dbus_bool_t dbus_connection_try_register_fallback (DBusConnection *connection, + const char *path, + const DBusObjectPathVTable *vtable, + void *user_data, + DBusError *error); + dbus_bool_t dbus_connection_register_fallback (DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c index 7c1d68e5..d0a80b02 100644 --- a/dbus/dbus-errors.c +++ b/dbus/dbus-errors.c @@ -97,6 +97,8 @@ message_from_error (const char *error) return "Did not get a reply message."; else if (strcmp (error, DBUS_ERROR_FILE_NOT_FOUND) == 0) return "File doesn't exist."; + else if (strcmp (error, DBUS_ERROR_OBJECT_PATH_IN_USE) == 0) + return "Object path already in use"; else return error; } diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index 18db1ee2..953aa3bd 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -371,6 +371,8 @@ ensure_subtree (DBusObjectTree *tree, return find_subtree_recurse (tree->root, path, TRUE, NULL, NULL); } +static char *flatten_path (const char **path); + /** * Registers a new subtree in the global object tree. * @@ -379,14 +381,17 @@ ensure_subtree (DBusObjectTree *tree, * @param path NULL-terminated array of path elements giving path to subtree * @param vtable the vtable used to traverse this subtree * @param user_data user data to pass to methods in the vtable - * @returns #FALSE if not enough memory + * @param error address where an error can be returned + * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or + * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported */ dbus_bool_t _dbus_object_tree_register (DBusObjectTree *tree, dbus_bool_t fallback, const char **path, const DBusObjectPathVTable *vtable, - void *user_data) + void *user_data, + DBusError *error) { DBusObjectSubtree *subtree; @@ -396,24 +401,33 @@ _dbus_object_tree_register (DBusObjectTree *tree, subtree = ensure_subtree (tree, path); if (subtree == NULL) - return FALSE; + { + _DBUS_SET_OOM (error); + return FALSE; + } -#ifndef DBUS_DISABLE_CHECKS if (subtree->message_function != NULL) { - _dbus_warn ("A handler is already registered for the path starting with path[0] = \"%s\"\n", - path[0] ? path[0] : "null"); + if (error != NULL) + { + char *complete_path = flatten_path (path); + + dbus_set_error (error, DBUS_ERROR_OBJECT_PATH_IN_USE, + "A handler is already registered for %s", + complete_path ? complete_path + : "(cannot represent path: out of memory!)"); + + dbus_free (complete_path); + } + return FALSE; } -#else - _dbus_assert (subtree->message_function == NULL); -#endif subtree->message_function = vtable->message_function; subtree->unregister_function = vtable->unregister_function; subtree->user_data = user_data; subtree->invoke_as_fallback = fallback != FALSE; - + return TRUE; } @@ -1140,13 +1154,6 @@ _dbus_decompose_path (const char* data, /** @} */ -#ifdef DBUS_BUILD_TESTS - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#include "dbus-test.h" -#include <stdio.h> - static char* flatten_path (const char **path) { @@ -1191,6 +1198,13 @@ flatten_path (const char **path) } +#ifdef DBUS_BUILD_TESTS + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#include "dbus-test.h" +#include <stdio.h> + typedef enum { STR_EQUAL, @@ -1314,7 +1328,7 @@ do_register (DBusObjectTree *tree, { DBusObjectPathVTable vtable = { test_unregister_function, test_message_function, NULL }; - + tree_test_data[i].message_handled = FALSE; tree_test_data[i].handler_unregistered = FALSE; tree_test_data[i].handler_fallback = fallback; @@ -1322,7 +1336,8 @@ do_register (DBusObjectTree *tree, if (!_dbus_object_tree_register (tree, fallback, path, &vtable, - &tree_test_data[i])) + &tree_test_data[i], + NULL)) return FALSE; _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path) == diff --git a/dbus/dbus-object-tree.h b/dbus/dbus-object-tree.h index 4434097d..1166752c 100644 --- a/dbus/dbus-object-tree.h +++ b/dbus/dbus-object-tree.h @@ -37,7 +37,8 @@ dbus_bool_t _dbus_object_tree_register (DBusObjectTree dbus_bool_t fallback, const char **path, const DBusObjectPathVTable *vtable, - void *user_data); + void *user_data, + DBusError *error); void _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, const char **path); DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h index 240f9526..58677dcf 100644 --- a/dbus/dbus-protocol.h +++ b/dbus/dbus-protocol.h @@ -411,6 +411,8 @@ extern "C" { #define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent" /** Asked for SELinux security context and it wasn't available. */ #define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" +/** There's already an object with the requested object path. */ +#define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse" /* XML introspection format */ diff --git a/test/data/invalid-service-files-system/.gitignore b/test/data/invalid-service-files-system/.gitignore new file mode 100644 index 00000000..0e3ad1b0 --- /dev/null +++ b/test/data/invalid-service-files-system/.gitignore @@ -0,0 +1 @@ +*.service diff --git a/test/data/valid-config-files-system/.gitignore b/test/data/valid-config-files-system/.gitignore new file mode 100644 index 00000000..fee92170 --- /dev/null +++ b/test/data/valid-config-files-system/.gitignore @@ -0,0 +1 @@ +*.conf diff --git a/test/data/valid-service-files-system/.gitignore b/test/data/valid-service-files-system/.gitignore new file mode 100644 index 00000000..0e3ad1b0 --- /dev/null +++ b/test/data/valid-service-files-system/.gitignore @@ -0,0 +1 @@ +*.service diff --git a/test/data/valid-service-files/.gitignore b/test/data/valid-service-files/.gitignore index b6f2adcf..0e3ad1b0 100644 --- a/test/data/valid-service-files/.gitignore +++ b/test/data/valid-service-files/.gitignore @@ -1,6 +1 @@ -debug-echo.service -debug-glib.service -debug-python.service -debug-segfault.service -debug-shell-echo-fail.service -debug-shell-echo-success.service +*.service diff --git a/test/name-test/.gitignore b/test/name-test/.gitignore index 91eb1830..09930f11 100644 --- a/test/name-test/.gitignore +++ b/test/name-test/.gitignore @@ -5,3 +5,5 @@ Makefile.in test-names test-pending-call-dispatch test-threads-init +test-ids +run-with-tmp-session-bus.conf |