diff options
117 files changed, 2608 insertions, 3307 deletions
@@ -13,7 +13,6 @@ Christian Ehrlicher <Ch.Ehrlicher@gmx.de> Christian Persch (GNOME) <chpe@gnome.org> Colin Walters <walters@verbum.org> Colin Watson <cjwatson@ubuntu.com> -Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> Cristian Rodríguez <cristian.rodriguez@opensuse.org> Cyril Brulebois <kibi@debian.org> Daniel P. Berrange <dan@berrange.com> @@ -154,10 +154,6 @@ To make a release of D-Bus, do the following: - update the file NEWS based on the git history - - verify that the version number of dbus-specification.xml is - changed if it needs to be; if changes have been made, update the - release date in that file - - update the AUTHORS file with "make update-authors" if necessary - the version number should have major.minor.micro, even @@ -179,8 +175,7 @@ To make a release of D-Bus, do the following: - bump the version number up in configure.ac (so the micro version is odd), and commit it. Make sure you do this *after* tagging the previous release! The idea is that git has a newer version number - than anything released. Similarly, bump the version number of - dbus-specification.xml and set the release date to "(not finalized)". + than anything released. - merge the branch you've released to the chronologically-later branch (usually "master"). You'll probably have to fix a merge @@ -1,18 +1,12 @@ -D-Bus 1.5.10 (UNRELEASED) +D-Bus 1.4.18 (UNRELEASED) == … -D-Bus 1.5.8 (2011-09-21) +D-Bus 1.4.16 (2011-09-21) == -The "cross-metering" release. - -In addition to dead code removal and refactoring, this release contains all -of the bugfixes from 1.4.16. - -• Clean up dead code, and make more warnings fatal in development builds - (fd.o #39231, fd.o #41012; Simon McVittie) +The "this answerphone fails to answer the phone" release. • If full test coverage is requested via --enable-tests, strictly require Python, pygobject and dbus-python, which are required by some tests; if not, @@ -57,37 +51,17 @@ of the bugfixes from 1.4.16. · Fix compilation on MSVC, which doesn't understand "inline" with its C99 meaning (fd.o #40000; Ralf Habacker, Simon McVittie) · Fix misuse of GPid in test/dbus-daemon.c (fd.o #40003, Simon McVittie) - · Fix cross-compilation to Windows with Automake (fd.o #40003, Simon McVittie) -D-Bus 1.5.6 (2011-07-29) +D-Bus 1.4.14 (2011-07-29) == -The "weird, gravy-like aftertaste" release. - -In addition to new features and refactoring, this release contains all of the -bugfixes from 1.4.14. - -Potentially incompatible (Bustle and similar debugging tools will need -changes to work as intended): - -• Do not allow match rules to "eavesdrop" (receive messages intended for a - different recipient) by mistake: eavesdroppers must now opt-in to this - behaviour by putting "eavesdrop='true'" in the match rule, which will - not have any practical effect on buses where eavesdropping is not allowed - (fd.o #37890, Cosimo Alfarano) +The "Puny receptacle!" release. -Other changes: - -• D-Bus Specification version 0.18 (fd.o #37890, fd.o #39450, fd.o #38252; - Cosimo Alfarano, Simon McVittie) - · add the "eavesdrop" keyword to match rules - · define eavesdropping, unicast messages and broadcast messages - · stop claiming that match rules are needed to match unicast messages to you - · promote the type system to be a top-level section +Changes: • Use DBUS_ERROR_OBJECT_PATH_IN_USE if dbus_connection_try_register_object_path - or dbus_connection_try_register_fallback fails, not ...ADDRESS_IN_USE, - and simplify object-path registration (fd.o #38874, Jiří Klimeš) + or dbus_connection_try_register_fallback fails, not ...ADDRESS_IN_USE + (fd.o #38874, Jiří Klimeš) • Consistently use atomic operations on everything that is ever manipulated via atomic ops, as was done for changes to DBusConnection's refcount in @@ -99,26 +73,6 @@ Other changes: • Make "make check" in a clean tree work, by not running tests until test data has been set up (fd.o #34405, Simon McVittie) -• The dbus-daemon no longer busy-loops if it has a very large number of file - descriptors (fd.o #23194, Simon McVittie) - -• Refactor message flow through dispatching to avoid locking violations if - the bus daemon's message limit is hit; remove the per-connection link cache, - which was meant to improve performance, but now reduces it (fd.o #34393, - Simon McVittie) - -• Some cmake fixes (Ralf Habacker) - -• Remove dead code, mainly from DBusString (fd.o #38570, fd.o #39610; - Simon McVittie, Lennart Poettering) - -• Stop storing two extra byte order indicators in each D-Bus message - (fd.o #38287, Simon McVittie) - -• Add an optional Stats interface which can be used to get statistics from - a running dbus-daemon if enabled at configure time with --enable-stats - (fd.o #34040, Simon McVittie) - • Fix various typos (fd.o #27227, fd.o #38284; Sascha Silbe, Simon McVittie) • Documentation (fd.o #36156, Simon McVittie): @@ -137,7 +91,7 @@ Other changes: · fix use of a mutex for autolaunch server detection · don't crash on malloc failure in _dbus_printf_string_upper_bound -D-Bus 1.5.4 (2011-06-10) +D-Bus 1.4.12 (2011-06-10) == Security (local denial of service): @@ -178,10 +132,10 @@ Changes: • Windows-specific changes: · don't try to build dbus-daemon-launch-helper (fd.o #37838, Mark Brand) -D-Bus 1.5.2 (2011-06-01) +D-Bus 1.4.10 (2011-06-01) == -The "Boar Hunter" release. +The "Ape Ale" release. Notes for distributors: @@ -195,10 +149,6 @@ Notes for distributors: Changes: - • D-Bus Specification v0.17 - · Reserve the extra characters used in signatures by GVariant - (fd.o #34529, Simon McVittie) - · Define the ObjectManager interface (fd.o #34869, David Zeuthen) • Don't force -fPIE: distributions and libtool know better than we do whether it's desirable (fd.o #16621, fd.o #27215; Simon McVittie) • Allow --disable-gc-sections, in case your toolchain offers the @@ -208,8 +158,6 @@ Changes: (fd.o #14512; Simon McVittie, loosely based on a patch from Luca Barbato) • Ensure that maintainers upload documentation with the right permissions (fd.o #36130, Simon McVittie) - • Don't force users of libdbus to be linked against -lpthread, -lrt - (fd.o #32827, Simon McVittie) • Log system-bus activation information to syslog (fd.o #35705, Colin Walters) • Log messages dropped due to quotas to syslog (fd.o #35358, @@ -229,28 +177,6 @@ Changes: • Windows: • Remove obsolete workaround for winioctl.h (fd.o #35083, Ralf Habacker) -D-Bus 1.5.0 (2011-04-11) -== - -The "you never know when you need to tow something from your giant -flying shark" release. - - • D-Bus Specification v0.16 - · Add support for path_namespace and arg0namespace in match rules - (fd.o #24317, #34870; Will Thompson, David Zeuthen, Simon McVittie) - · Make argNpath support object paths, not just object-path-like strings, - and document it better (fd.o #31818, Will Thompson) - • Let the bus daemon implement more than one interface (fd.o #33757, - Simon McVittie) - • Optimize _dbus_string_replace_len to reduce waste (fd.o #21261, - Roberto Guido) - • Require user intervention to compile with missing 64-bit support - (fd.o #35114, Simon McVittie) - • Add dbus_type_is_valid as public API (fd.o #20496, Simon McVittie) - • Raise UnknownObject instead of UnknownMethod for calls to methods on - paths that are not part of the object tree, and UnknownInterface for calls - to unknown interfaces in the bus daemon (fd.o #34527, Lennart Poettering) - D-Bus 1.4.8 (2011-04-08) == diff --git a/bus/Makefile.am b/bus/Makefile.am index 6cbc09a6..a3ddb6cf 100644 --- a/bus/Makefile.am +++ b/bus/Makefile.am @@ -1,30 +1,10 @@ configdir=$(sysconfdir)/dbus-1 dbus_daemon_execdir = $(DBUS_DAEMONDIR) -DBUS_BUS_LIBS = \ - $(XML_LIBS) \ - $(SELINUX_LIBS) \ - $(THREAD_LIBS) \ - $(ADT_LIBS) \ - $(NETWORK_libs) \ - $(NULL) - -DBUS_LAUNCHER_LIBS = \ - $(XML_LIBS) \ - $(THREAD_LIBS) \ - $(NETWORK_libs) \ - $(NULL) - -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(XML_CFLAGS) \ +INCLUDES = -I$(top_srcdir) \ + $(DBUS_BUS_CFLAGS) \ -DDBUS_SYSTEM_CONFIG_FILE=\""$(configdir)/system.conf"\" \ - -DDBUS_COMPILATION \ - -DDBUS_STATIC_BUILD \ - $(NULL) - -# if assertions are enabled, improve backtraces -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ + -DDBUS_COMPILATION EFENCE= @@ -93,8 +73,6 @@ BUS_SOURCES= \ services.h \ signals.c \ signals.h \ - stats.c \ - stats.h \ test.c \ test.h \ utils.c \ @@ -105,11 +83,14 @@ dbus_daemon_SOURCES= \ $(BUS_SOURCES) \ main.c +dbus_daemon_CPPFLAGS = -DDBUS_STATIC_BUILD dbus_daemon_LDADD= \ $(top_builddir)/dbus/libdbus-internal.la \ $(EFENCE) \ $(DBUS_BUS_LIBS) +dbus_daemon_LDFLAGS=@R_DYNAMIC_LDFLAG@ + LAUNCH_HELPER_SOURCES= \ $(XML_SOURCES) \ config-parser-common.c \ @@ -129,10 +110,13 @@ dbus_daemon_launch_helper_SOURCES= \ activation-helper-bin.c \ $(LAUNCH_HELPER_SOURCES) +dbus_daemon_launch_helper_CPPFLAGS = -DDBUS_STATIC_BUILD dbus_daemon_launch_helper_LDADD= \ $(top_builddir)/dbus/libdbus-internal.la \ $(DBUS_LAUNCHER_LIBS) +dbus_daemon_launch_helper_LDFLAGS=@R_DYNAMIC_LDFLAG@ + ## we build another binary so we can do the launch testing without root privs. ## DO NOT INSTALL THIS FILE dbus_daemon_launch_helper_test_SOURCES= \ @@ -143,8 +127,8 @@ dbus_daemon_launch_helper_test_LDADD= \ $(top_builddir)/dbus/libdbus-internal.la \ $(DBUS_LAUNCHER_LIBS) -dbus_daemon_launch_helper_test_CPPFLAGS = \ - $(AM_CPPFLAGS) \ +dbus_daemon_launch_helper_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ +dbus_daemon_launch_helper_test_CPPFLAGS= -DDBUS_STATIC_BUILD \ -DACTIVATION_LAUNCHER_TEST ## we build yet another binary so we can do the OOM tests @@ -157,8 +141,8 @@ bus_test_launch_helper_LDADD= \ $(top_builddir)/dbus/libdbus-internal.la \ $(DBUS_LAUNCHER_LIBS) -bus_test_launch_helper_CPPFLAGS = \ - $(AM_CPPFLAGS) \ +bus_test_launch_helper_LDFLAGS=@R_DYNAMIC_LDFLAG@ +bus_test_launch_helper_CPPFLAGS= -DDBUS_STATIC_BUILD \ -DACTIVATION_LAUNCHER_TEST \ -DACTIVATION_LAUNCHER_DO_OOM @@ -199,13 +183,17 @@ bus_test_system_SOURCES= \ utils.h \ test-system.c +bus_test_system_CPPFLAGS = -DDBUS_STATIC_BUILD bus_test_system_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_BUS_LIBS) +bus_test_system_LDFLAGS=@R_DYNAMIC_LDFLAG@ bus_test_SOURCES= \ $(BUS_SOURCES) \ test-main.c +bus_test_CPPFLAGS = -DDBUS_STATIC_BUILD bus_test_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_BUS_LIBS) +bus_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ ## mop up the gcov files clean-local: diff --git a/bus/activation-helper.c b/bus/activation-helper.c index ab9d6010..baba8f04 100644 --- a/bus/activation-helper.c +++ b/bus/activation-helper.c @@ -144,10 +144,10 @@ out_all: static dbus_bool_t clear_environment (DBusError *error) { - const char *starter_env = NULL; -#ifdef DBUS_ENABLE_VERBOSE_MODE const char *debug_env = NULL; + const char *starter_env = NULL; +#ifdef DBUS_ENABLE_VERBOSE_MODE /* are we debugging */ debug_env = _dbus_getenv ("DBUS_VERBOSE"); #endif @@ -184,7 +184,6 @@ clear_environment (DBusError *error) static dbus_bool_t check_permissions (const char *dbus_user, DBusError *error) { -#ifndef ACTIVATION_LAUNCHER_TEST uid_t uid, euid; struct passwd *pw; @@ -192,6 +191,7 @@ check_permissions (const char *dbus_user, DBusError *error) uid = 0; euid = 0; +#ifndef ACTIVATION_LAUNCHER_TEST /* bail out unless the dbus user is invoking the helper */ pw = getpwnam(dbus_user); if (!pw) @@ -403,15 +403,12 @@ get_correct_parser (BusConfigParser **parser, DBusError *error) { DBusString config_file; dbus_bool_t retval; -#ifdef ACTIVATION_LAUNCHER_TEST const char *test_config_file; -#endif retval = FALSE; - -#ifdef ACTIVATION_LAUNCHER_TEST test_config_file = NULL; +#ifdef ACTIVATION_LAUNCHER_TEST /* there is no _way_ we should be setuid if this define is set. * but we should be doubly paranoid and check... */ if (getuid() != geteuid()) diff --git a/bus/activation.c b/bus/activation.c index 2744e214..acb2aa89 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -143,6 +143,16 @@ bus_pending_activation_entry_free (BusPendingActivationEntry *entry) dbus_free (entry); } +static void +handle_timeout_callback (DBusTimeout *timeout, + void *data) +{ + BusPendingActivation *pending_activation = data; + + while (!dbus_timeout_handle (pending_activation->timeout)) + _dbus_wait_for_memory (); +} + static BusPendingActivation * bus_pending_activation_ref (BusPendingActivation *pending_activation) { @@ -169,7 +179,8 @@ bus_pending_activation_unref (BusPendingActivation *pending_activation) if (pending_activation->timeout_added) { _dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context), - pending_activation->timeout); + pending_activation->timeout, + handle_timeout_callback, pending_activation); pending_activation->timeout_added = FALSE; } @@ -884,6 +895,8 @@ bus_activation_new (BusContext *context, DBusError *error) { BusActivation *activation; + DBusList *link; + char *dir; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1324,16 +1337,22 @@ handle_servicehelper_exit_error (int exit_code, } } -static void -pending_activation_finished_cb (DBusBabysitter *babysitter, - void *data) +static dbus_bool_t +babysitter_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) { BusPendingActivation *pending_activation = data; + dbus_bool_t retval; + DBusBabysitter *babysitter; dbus_bool_t uses_servicehelper; - _dbus_assert (babysitter == pending_activation->babysitter); + babysitter = pending_activation->babysitter; + _dbus_babysitter_ref (babysitter); + retval = dbus_watch_handle (watch, condition); + /* There are two major cases here; are we the system bus or the session? Here this * is distinguished by whether or not we use a setuid helper launcher. With the launch helper, * some process exit codes are meaningful, processed by handle_servicehelper_exit_error. @@ -1344,7 +1363,15 @@ pending_activation_finished_cb (DBusBabysitter *babysitter, */ uses_servicehelper = bus_context_get_servicehelper (pending_activation->activation->context) != NULL; - /* strictly speaking this is redundant with the check in dbus-spawn now */ + /* FIXME this is broken in the same way that + * connection watches used to be; there should be + * a separate callback for status change, instead + * of doing "if we handled a watch status might + * have changed" + * + * Fixing this lets us move dbus_watch_handle + * calls into dbus-mainloop.c + */ if (_dbus_babysitter_get_child_exited (babysitter)) { DBusError error; @@ -1404,6 +1431,8 @@ pending_activation_finished_cb (DBusBabysitter *babysitter, } _dbus_babysitter_unref (babysitter); + + return retval; } static dbus_bool_t @@ -1412,9 +1441,9 @@ add_babysitter_watch (DBusWatch *watch, { BusPendingActivation *pending_activation = data; - return _dbus_loop_add_watch ( - bus_context_get_loop (pending_activation->activation->context), - watch); + return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context), + watch, babysitter_watch_callback, pending_activation, + NULL); } static void @@ -1424,7 +1453,7 @@ remove_babysitter_watch (DBusWatch *watch, BusPendingActivation *pending_activation = data; _dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context), - watch); + watch, babysitter_watch_callback, pending_activation); } static dbus_bool_t @@ -1672,6 +1701,7 @@ bus_activation_activate_service (BusActivation *activation, char **envp = NULL; int argc; dbus_bool_t retval; + DBusHashIter iter; dbus_bool_t was_pending_activation; DBusString command; @@ -1833,7 +1863,10 @@ bus_activation_activate_service (BusActivation *activation, } if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context), - pending_activation->timeout)) + pending_activation->timeout, + handle_timeout_callback, + pending_activation, + NULL)) { _dbus_verbose ("Failed to add timeout for pending activation\n"); @@ -2103,10 +2136,6 @@ bus_activation_activate_service (BusActivation *activation, _dbus_assert (pending_activation->babysitter != NULL); - _dbus_babysitter_set_result_function (pending_activation->babysitter, - pending_activation_finished_cb, - pending_activation); - if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter, add_babysitter_watch, remove_babysitter_watch, @@ -2538,18 +2567,14 @@ bus_activation_service_reload_test (const DBusString *test_data_dir) _dbus_assert_not_reached ("could not initiate service reload test"); if (!do_service_reload_test (&directory, FALSE)) - { - /* Do nothing? */ - } + ; /* Do nothing? */ /* Do OOM tests */ if (!init_service_reload_test (&directory)) _dbus_assert_not_reached ("could not initiate service reload test"); if (!do_service_reload_test (&directory, TRUE)) - { - /* Do nothing? */ - } + ; /* Do nothing? */ /* Cleanup test directory */ if (!cleanup_service_reload_test (&directory)) @@ -103,6 +103,19 @@ server_get_context (DBusServer *server) } static dbus_bool_t +server_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + /* FIXME this can be done in dbus-mainloop.c + * if the code in activation.c for the babysitter + * watch handler is fixed. + */ + + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t add_server_watch (DBusWatch *watch, void *data) { @@ -111,7 +124,9 @@ add_server_watch (DBusWatch *watch, context = server_get_context (server); - return _dbus_loop_add_watch (context->loop, watch); + return _dbus_loop_add_watch (context->loop, + watch, server_watch_callback, server, + NULL); } static void @@ -123,7 +138,17 @@ remove_server_watch (DBusWatch *watch, context = server_get_context (server); - _dbus_loop_remove_watch (context->loop, watch); + _dbus_loop_remove_watch (context->loop, + watch, server_watch_callback, server); +} + + +static void +server_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); } static dbus_bool_t @@ -135,7 +160,8 @@ add_server_timeout (DBusTimeout *timeout, context = server_get_context (server); - return _dbus_loop_add_timeout (context->loop, timeout); + return _dbus_loop_add_timeout (context->loop, + timeout, server_timeout_callback, server, NULL); } static void @@ -147,7 +173,8 @@ remove_server_timeout (DBusTimeout *timeout, context = server_get_context (server); - _dbus_loop_remove_timeout (context->loop, timeout); + _dbus_loop_remove_timeout (context->loop, + timeout, server_timeout_callback, server); } static void @@ -481,6 +508,7 @@ process_config_every_time (BusContext *context, DBusString full_address; DBusList *link; DBusList **dirs; + BusActivation *new_activation; char *addr; const char *servicehelper; char *s; @@ -687,6 +715,7 @@ bus_context_new (const DBusString *config_file, dbus_bool_t systemd_activation, DBusError *error) { + DBusString log_prefix; BusContext *context; BusConfigParser *parser; @@ -1391,6 +1420,9 @@ bus_context_check_security_policy (BusContext *context, dbus_bool_t log; int type; dbus_bool_t requested_reply; + const char *sender_name; + const char *sender_loginfo; + const char *proposed_recipient_loginfo; type = dbus_message_get_type (message); dest = dbus_message_get_destination (message); @@ -1556,6 +1588,9 @@ bus_context_check_security_policy (BusContext *context, proposed_recipient, message, &toggles, &log)) { + const char *msg = "Rejected send message, %d matched rules; " + "type=\"%s\", sender=\"%s\" (%s) interface=\"%s\" member=\"%s\" error name=\"%s\" requested_reply=%d destination=\"%s\" (%s))"; + complain_about_message (context, DBUS_ERROR_ACCESS_DENIED, "Rejected send message", toggles, message, sender, proposed_recipient, requested_reply, diff --git a/bus/config-parser.c b/bus/config-parser.c index c636707f..f9432555 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -3271,12 +3271,11 @@ test_default_session_servicedirs (void) DBusList *dirs; DBusList *link; DBusString progs; + const char *common_progs; int i; #ifdef DBUS_WIN - const char *common_progs; char buffer[1024]; - if (_dbus_get_install_root(buffer, sizeof(buffer))) { strcat(buffer,DBUS_DATADIR); @@ -3290,9 +3289,8 @@ test_default_session_servicedirs (void) if (!_dbus_string_init (&progs)) _dbus_assert_not_reached ("OOM allocating progs"); -#ifndef DBUS_UNIX common_progs = _dbus_getenv ("CommonProgramFiles"); - +#ifndef DBUS_UNIX if (common_progs) { if (!_dbus_string_append (&progs, common_progs)) @@ -3413,9 +3411,7 @@ test_default_system_servicedirs (void) DBusList *dirs; DBusList *link; DBusString progs; -#ifndef DBUS_UNIX const char *common_progs; -#endif int i; /* On Unix we don't actually use this variable, but it's easier to handle the @@ -3423,9 +3419,8 @@ test_default_system_servicedirs (void) if (!_dbus_string_init (&progs)) _dbus_assert_not_reached ("OOM allocating progs"); -#ifndef DBUS_UNIX common_progs = _dbus_getenv ("CommonProgramFiles"); - +#ifndef DBUS_UNIX if (common_progs) { if (!_dbus_string_append (&progs, common_progs)) diff --git a/bus/connection.c b/bus/connection.c index 26839529..8e7d222a 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -62,16 +62,6 @@ struct BusConnections DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */ int stamp; /**< Incrementing number */ BusExpireList *pending_replies; /**< List of pending replies */ - -#ifdef DBUS_ENABLE_STATS - int total_match_rules; - int peak_match_rules; - int peak_match_rules_per_conn; - - int total_bus_names; - int peak_bus_names; - int peak_bus_names_per_conn; -#endif }; static dbus_int32_t connection_data_slot = -1; @@ -97,11 +87,6 @@ typedef struct long connection_tv_sec; /**< Time when we connected (seconds component) */ long connection_tv_usec; /**< Time when we connected (microsec component) */ int stamp; /**< connections->stamp last time we were traversed */ - -#ifdef DBUS_ENABLE_STATS - int peak_match_rules; - int peak_bus_names; -#endif } BusConnectionData; static dbus_bool_t bus_pending_reply_expired (BusExpireList *list, @@ -310,12 +295,30 @@ bus_connection_disconnected (DBusConnection *connection) } static dbus_bool_t +connection_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + /* FIXME this can be done in dbus-mainloop.c + * if the code in activation.c for the babysitter + * watch handler is fixed. + */ + +#if 0 + _dbus_verbose ("Calling handle_watch\n"); +#endif + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t add_connection_watch (DBusWatch *watch, void *data) { DBusConnection *connection = data; - return _dbus_loop_add_watch (connection_get_loop (connection), watch); + return _dbus_loop_add_watch (connection_get_loop (connection), + watch, connection_watch_callback, connection, + NULL); } static void @@ -324,7 +327,18 @@ remove_connection_watch (DBusWatch *watch, { DBusConnection *connection = data; - _dbus_loop_remove_watch (connection_get_loop (connection), watch); + _dbus_loop_remove_watch (connection_get_loop (connection), + watch, connection_watch_callback, connection); +} + +static void +connection_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* DBusConnection *connection = data; */ + + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); } static dbus_bool_t @@ -333,7 +347,8 @@ add_connection_timeout (DBusTimeout *timeout, { DBusConnection *connection = data; - return _dbus_loop_add_timeout (connection_get_loop (connection), timeout); + return _dbus_loop_add_timeout (connection_get_loop (connection), + timeout, connection_timeout_callback, connection, NULL); } static void @@ -342,7 +357,8 @@ remove_connection_timeout (DBusTimeout *timeout, { DBusConnection *connection = data; - _dbus_loop_remove_timeout (connection_get_loop (connection), timeout); + _dbus_loop_remove_timeout (connection_get_loop (connection), + timeout, connection_timeout_callback, connection); } static void @@ -403,6 +419,14 @@ free_connection_data (void *data) dbus_free (d); } +static void +call_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); +} + BusConnections* bus_connections_new (BusContext *context) { @@ -436,7 +460,8 @@ bus_connections_new (BusContext *context) goto failed_4; if (!_dbus_loop_add_timeout (bus_context_get_loop (context), - connections->expire_timeout)) + connections->expire_timeout, + call_timeout_callback, NULL, NULL)) goto failed_5; connections->refcount = 1; @@ -507,7 +532,8 @@ bus_connections_unref (BusConnections *connections) bus_expire_list_free (connections->pending_replies); _dbus_loop_remove_timeout (bus_context_get_loop (connections->context), - connections->expire_timeout); + connections->expire_timeout, + call_timeout_callback, NULL); _dbus_timeout_unref (connections->expire_timeout); @@ -830,7 +856,12 @@ bus_connection_get_unix_groups (DBusConnection *connection, int *n_groups, DBusError *error) { + BusConnectionData *d; unsigned long uid; + + d = BUS_CONNECTION_DATA (connection); + + _dbus_assert (d != NULL); *groups = NULL; *n_groups = 0; @@ -1193,16 +1224,6 @@ bus_connection_send_oom_error (DBusConnection *connection, d->oom_preallocated = NULL; } -#ifdef DBUS_ENABLE_STATS -static void -update_peak (int *peak, - int n) -{ - if (*peak < n) - *peak = n; -} -#endif - void bus_connection_add_match_rule_link (DBusConnection *connection, DBusList *link) @@ -1215,15 +1236,6 @@ bus_connection_add_match_rule_link (DBusConnection *connection, _dbus_list_append_link (&d->match_rules, link); d->n_match_rules += 1; - -#ifdef DBUS_ENABLE_STATS - update_peak (&d->peak_match_rules, d->n_match_rules); - update_peak (&d->connections->peak_match_rules_per_conn, d->n_match_rules); - - d->connections->total_match_rules += 1; - update_peak (&d->connections->peak_match_rules, - d->connections->total_match_rules); -#endif } dbus_bool_t @@ -1255,10 +1267,6 @@ bus_connection_remove_match_rule (DBusConnection *connection, d->n_match_rules -= 1; _dbus_assert (d->n_match_rules >= 0); - -#ifdef DBUS_ENABLE_STATS - d->connections->total_match_rules -= 1; -#endif } int @@ -1284,16 +1292,6 @@ bus_connection_add_owned_service_link (DBusConnection *connection, _dbus_list_append_link (&d->services_owned, link); d->n_services_owned += 1; - -#ifdef DBUS_ENABLE_STATS - update_peak (&d->peak_bus_names, d->n_services_owned); - update_peak (&d->connections->peak_bus_names_per_conn, - d->n_services_owned); - - d->connections->total_bus_names += 1; - update_peak (&d->connections->peak_bus_names, - d->connections->total_bus_names); -#endif } dbus_bool_t @@ -1325,10 +1323,6 @@ bus_connection_remove_owned_service (DBusConnection *connection, d->n_services_owned -= 1; _dbus_assert (d->n_services_owned >= 0); - -#ifdef DBUS_ENABLE_STATS - d->connections->total_bus_names -= 1; -#endif } int @@ -1446,7 +1440,13 @@ bus_connections_check_limits (BusConnections *connections, DBusConnection *requesting_completion, DBusError *error) { + BusConnectionData *d; unsigned long uid; + + d = BUS_CONNECTION_DATA (requesting_completion); + _dbus_assert (d != NULL); + + _dbus_assert (d->name == NULL); if (connections->n_completed >= bus_context_get_max_completed_connections (connections->context)) @@ -2306,71 +2306,3 @@ bus_transaction_add_cancel_hook (BusTransaction *transaction, return TRUE; } - -#ifdef DBUS_ENABLE_STATS -int -bus_connections_get_n_active (BusConnections *connections) -{ - return connections->n_completed; -} - -int -bus_connections_get_n_incomplete (BusConnections *connections) -{ - return connections->n_incomplete; -} - -int -bus_connections_get_total_match_rules (BusConnections *connections) -{ - return connections->total_match_rules; -} - -int -bus_connections_get_peak_match_rules (BusConnections *connections) -{ - return connections->peak_match_rules; -} - -int -bus_connections_get_peak_match_rules_per_conn (BusConnections *connections) -{ - return connections->peak_match_rules_per_conn; -} - -int -bus_connections_get_total_bus_names (BusConnections *connections) -{ - return connections->total_bus_names; -} - -int -bus_connections_get_peak_bus_names (BusConnections *connections) -{ - return connections->peak_bus_names; -} - -int -bus_connections_get_peak_bus_names_per_conn (BusConnections *connections) -{ - return connections->peak_bus_names_per_conn; -} - -int -bus_connection_get_peak_match_rules (DBusConnection *connection) -{ - BusConnectionData *d; - - d = BUS_CONNECTION_DATA (connection); - return d->peak_match_rules; -} - -int -bus_connection_get_peak_bus_names (DBusConnection *connection) -{ - BusConnectionData *d; - - d = BUS_CONNECTION_DATA (connection); - return d->peak_bus_names; -} -#endif /* DBUS_ENABLE_STATS */ diff --git a/bus/connection.h b/bus/connection.h index c9360212..4b9a754b 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -138,17 +138,4 @@ dbus_bool_t bus_transaction_add_cancel_hook (BusTransaction * void *data, DBusFreeFunction free_data_function); -/* called by stats.c, only present if DBUS_ENABLE_STATS */ -int bus_connections_get_n_active (BusConnections *connections); -int bus_connections_get_n_incomplete (BusConnections *connections); -int bus_connections_get_total_match_rules (BusConnections *connections); -int bus_connections_get_peak_match_rules (BusConnections *connections); -int bus_connections_get_peak_match_rules_per_conn (BusConnections *connections); -int bus_connections_get_total_bus_names (BusConnections *connections); -int bus_connections_get_peak_bus_names (BusConnections *connections); -int bus_connections_get_peak_bus_names_per_conn (BusConnections *connections); - -int bus_connection_get_peak_match_rules (DBusConnection *connection); -int bus_connection_get_peak_bus_names (DBusConnection *connection); - #endif /* BUS_CONNECTION_H */ diff --git a/bus/dir-watch-inotify.c b/bus/dir-watch-inotify.c index 2e9be988..461b8ee3 100644 --- a/bus/dir-watch-inotify.c +++ b/bus/dir-watch-inotify.c @@ -50,6 +50,12 @@ static DBusWatch *watch = NULL; static DBusLoop *loop = NULL; static dbus_bool_t +_inotify_watch_callback (DBusWatch *watch, unsigned int condition, void *data) +{ + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t _handle_inotify_watch (DBusWatch *passed_watch, unsigned int flags, void *data) { char buffer[INOTIFY_BUF_LEN]; @@ -198,18 +204,16 @@ _shutdown_inotify (void *data) _set_watched_dirs_internal (&empty); + close (inotify_fd); + inotify_fd = -1; if (watch != NULL) { - _dbus_loop_remove_watch (loop, watch); - _dbus_watch_invalidate (watch); + _dbus_loop_remove_watch (loop, watch, _inotify_watch_callback, NULL); _dbus_watch_unref (watch); _dbus_loop_unref (loop); } watch = NULL; loop = NULL; - - close (inotify_fd); - inotify_fd = -1; } static int @@ -246,7 +250,8 @@ _init_inotify (BusContext *context) goto out; } - if (!_dbus_loop_add_watch (loop, watch)) + if (!_dbus_loop_add_watch (loop, watch, _inotify_watch_callback, + NULL, NULL)) { _dbus_warn ("Unable to add reload watch to main loop"); _dbus_watch_unref (watch); diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c index ac6290cc..4e436eb1 100644 --- a/bus/dir-watch-kqueue.c +++ b/bus/dir-watch-kqueue.c @@ -50,6 +50,12 @@ static DBusWatch *watch = NULL; static DBusLoop *loop = NULL; static dbus_bool_t +_kqueue_watch_callback (DBusWatch *watch, unsigned int condition, void *data) +{ + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t _handle_kqueue_watch (DBusWatch *watch, unsigned int flags, void *data) { struct kevent ev; @@ -74,8 +80,7 @@ _handle_kqueue_watch (DBusWatch *watch, unsigned int flags, void *data) kq = -1; if (watch != NULL) { - _dbus_loop_remove_watch (loop, watch); - _dbus_watch_invalidate (watch); + _dbus_loop_remove_watch (loop, watch, _kqueue_watch_callback, NULL); _dbus_watch_unref (watch); watch = NULL; } @@ -115,14 +120,14 @@ _init_kqueue (BusContext *context) goto out; } - if (!_dbus_loop_add_watch (loop, watch)) + if (!_dbus_loop_add_watch (loop, watch, _kqueue_watch_callback, + NULL, NULL)) { _dbus_warn ("Unable to add reload watch to main loop"); - _dbus_watch_invalidate (watch); - _dbus_watch_unref (watch); - watch = NULL; close (kq); kq = -1; + _dbus_watch_unref (watch); + watch = NULL; goto out; } } diff --git a/bus/dispatch.c b/bus/dispatch.c index dfe6f746..a80476cd 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -4773,6 +4773,7 @@ bus_unix_fds_passing_test(const DBusString *test_data_dir) DBusConnection *foo, *bar; DBusError error; DBusMessage *m; + dbus_bool_t b; int one[2], two[2], x, y, z; char r; diff --git a/bus/driver.c b/bus/driver.c index 574e0f3d..cc8d1f26 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -30,7 +30,6 @@ #include "services.h" #include "selinux.h" #include "signals.h" -#include "stats.h" #include "utils.h" #include <dbus/dbus-string.h> #include <dbus/dbus-internals.h> @@ -827,6 +826,7 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection, DBusMessageIter iter; DBusMessageIter dict_iter; DBusMessageIter dict_entry_iter; + int msg_type; int array_type; int key_type; DBusList *keys, *key_link; @@ -841,13 +841,9 @@ bus_driver_handle_update_activation_environment (DBusConnection *connection, /* The message signature has already been checked for us, * so let's just assert it's right. */ -#ifndef DBUS_DISABLE_ASSERT - { - int msg_type = dbus_message_iter_get_arg_type (&iter); + msg_type = dbus_message_iter_get_arg_type (&iter); - _dbus_assert (msg_type == DBUS_TYPE_ARRAY); - } -#endif + _dbus_assert (msg_type == DBUS_TYPE_ARRAY); dbus_message_iter_recurse (&iter, &dict_iter); @@ -1648,7 +1644,11 @@ bus_driver_handle_get_id (DBusConnection *connection, return FALSE; } -typedef struct +/* For speed it might be useful to sort this in order of + * frequency of use (but doesn't matter with only a few items + * anyhow) + */ +static struct { const char *name; const char *in_args; @@ -1657,13 +1657,7 @@ typedef struct BusTransaction *transaction, DBusMessage *message, DBusError *error); -} MessageHandler; - -/* For speed it might be useful to sort this in order of - * frequency of use (but doesn't matter with only a few items - * anyhow) - */ -static const MessageHandler dbus_message_handlers[] = { +} message_handlers[] = { { "Hello", "", DBUS_TYPE_STRING_AS_STRING, @@ -1735,52 +1729,7 @@ static const MessageHandler dbus_message_handlers[] = { { "GetId", "", DBUS_TYPE_STRING_AS_STRING, - bus_driver_handle_get_id }, - { NULL, NULL, NULL, NULL } -}; - -static dbus_bool_t bus_driver_handle_introspect (DBusConnection *, - BusTransaction *, DBusMessage *, DBusError *); - -static const MessageHandler introspectable_message_handlers[] = { - { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect }, - { NULL, NULL, NULL, NULL } -}; - -#ifdef DBUS_ENABLE_STATS -static const MessageHandler stats_message_handlers[] = { - { "GetStats", "", "a{sv}", bus_stats_handle_get_stats }, - { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats }, - { NULL, NULL, NULL, NULL } -}; -#endif - -typedef struct { - const char *name; - const MessageHandler *message_handlers; - const char *extra_introspection; -} InterfaceHandler; - -/* These should ideally be sorted by frequency of use, although it - * probably doesn't matter with this few items */ -static InterfaceHandler interface_handlers[] = { - { DBUS_INTERFACE_DBUS, dbus_message_handlers, - " <signal name=\"NameOwnerChanged\">\n" - " <arg type=\"s\"/>\n" - " <arg type=\"s\"/>\n" - " <arg type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"NameLost\">\n" - " <arg type=\"s\"/>\n" - " </signal>\n" - " <signal name=\"NameAcquired\">\n" - " <arg type=\"s\"/>\n" - " </signal>\n" }, - { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL }, -#ifdef DBUS_ENABLE_STATS - { BUS_INTERFACE_STATS, stats_message_handlers, NULL }, -#endif - { NULL, NULL, NULL } + bus_driver_handle_get_id } }; static dbus_bool_t @@ -1821,43 +1770,86 @@ write_args_for_direction (DBusString *xml, dbus_bool_t bus_driver_generate_introspect_string (DBusString *xml) { - const InterfaceHandler *ih; - const MessageHandler *mh; + int i; if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) return FALSE; if (!_dbus_string_append (xml, "<node>\n")) return FALSE; + if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", DBUS_INTERFACE_INTROSPECTABLE)) + return FALSE; + if (!_dbus_string_append (xml, " <method name=\"Introspect\">\n")) + return FALSE; + if (!_dbus_string_append_printf (xml, " <arg name=\"data\" direction=\"out\" type=\"%s\"/>\n", DBUS_TYPE_STRING_AS_STRING)) + return FALSE; + if (!_dbus_string_append (xml, " </method>\n")) + return FALSE; + if (!_dbus_string_append (xml, " </interface>\n")) + return FALSE; - for (ih = interface_handlers; ih->name != NULL; ih++) + if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", + DBUS_INTERFACE_DBUS)) + return FALSE; + + i = 0; + while (i < _DBUS_N_ELEMENTS (message_handlers)) { - if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", - ih->name)) + + if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", + message_handlers[i].name)) return FALSE; - for (mh = ih->message_handlers; mh->name != NULL; mh++) - { - if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", - mh->name)) - return FALSE; + if (!write_args_for_direction (xml, message_handlers[i].in_args, TRUE)) + return FALSE; - if (!write_args_for_direction (xml, mh->in_args, TRUE)) - return FALSE; + if (!write_args_for_direction (xml, message_handlers[i].out_args, FALSE)) + return FALSE; - if (!write_args_for_direction (xml, mh->out_args, FALSE)) - return FALSE; + if (!_dbus_string_append (xml, " </method>\n")) + return FALSE; - if (!_dbus_string_append (xml, " </method>\n")) - return FALSE; - } + ++i; + } - if (ih->extra_introspection != NULL && - !_dbus_string_append (xml, ih->extra_introspection)) - return FALSE; + if (!_dbus_string_append_printf (xml, " <signal name=\"NameOwnerChanged\">\n")) + return FALSE; - if (!_dbus_string_append (xml, " </interface>\n")) - return FALSE; - } + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; + + + + if (!_dbus_string_append_printf (xml, " <signal name=\"NameLost\">\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; + + + + if (!_dbus_string_append_printf (xml, " <signal name=\"NameAcquired\">\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " <arg type=\"s\"/>\n")) + return FALSE; + + if (!_dbus_string_append_printf (xml, " </signal>\n")) + return FALSE; + + if (!_dbus_string_append (xml, " </interface>\n")) + return FALSE; if (!_dbus_string_append (xml, "</node>\n")) return FALSE; @@ -1933,10 +1925,8 @@ bus_driver_handle_message (DBusConnection *connection, DBusMessage *message, DBusError *error) { - const char *name, *interface; - const InterfaceHandler *ih; - const MessageHandler *mh; - dbus_bool_t found_interface = FALSE; + const char *name, *sender, *interface; + int i; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -1954,54 +1944,57 @@ bus_driver_handle_message (DBusConnection *connection, return TRUE; /* we just ignore this */ } - /* may be NULL, which means "any interface will do" */ + if (dbus_message_is_method_call (message, + DBUS_INTERFACE_INTROSPECTABLE, + "Introspect")) + return bus_driver_handle_introspect (connection, transaction, message, error); + interface = dbus_message_get_interface (message); + if (interface == NULL) + interface = DBUS_INTERFACE_DBUS; _dbus_assert (dbus_message_get_member (message) != NULL); name = dbus_message_get_member (message); + sender = dbus_message_get_sender (message); - _dbus_verbose ("Driver got a method call: %s\n", name); - - /* security checks should have kept this from getting here */ -#ifndef DBUS_DISABLE_ASSERT + if (strcmp (interface, + DBUS_INTERFACE_DBUS) != 0) { - const char *sender = dbus_message_get_sender (message); - - _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); + _dbus_verbose ("Driver got message to unknown interface \"%s\"\n", + interface); + goto unknown; } -#endif - for (ih = interface_handlers; ih->name != NULL; ih++) - { - if (interface != NULL && strcmp (interface, ih->name) != 0) - continue; + _dbus_verbose ("Driver got a method call: %s\n", + dbus_message_get_member (message)); - found_interface = TRUE; + /* security checks should have kept this from getting here */ + _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); - for (mh = ih->message_handlers; mh->name != NULL; mh++) + i = 0; + while (i < _DBUS_N_ELEMENTS (message_handlers)) + { + if (strcmp (message_handlers[i].name, name) == 0) { - if (strcmp (mh->name, name) != 0) - continue; - _dbus_verbose ("Found driver handler for %s\n", name); - if (!dbus_message_has_signature (message, mh->in_args)) + if (!dbus_message_has_signature (message, message_handlers[i].in_args)) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n", name, dbus_message_get_signature (message), - mh->in_args); + message_handlers[i].in_args); dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Call to %s has wrong args (%s, expected %s)\n", name, dbus_message_get_signature (message), - mh->in_args); + message_handlers[i].in_args); _DBUS_ASSERT_ERROR_IS_SET (error); return FALSE; } - if ((* mh->handler) (connection, transaction, message, error)) + if ((* message_handlers[i].handler) (connection, transaction, message, error)) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("Driver handler succeeded\n"); @@ -2014,12 +2007,15 @@ bus_driver_handle_message (DBusConnection *connection, return FALSE; } } + + ++i; } + unknown: _dbus_verbose ("No driver handler for message \"%s\"\n", name); - dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE, + dbus_set_error (error, DBUS_ERROR_UNKNOWN_METHOD, "%s does not understand message %s", DBUS_SERVICE_DBUS, name); diff --git a/bus/expirelist.c b/bus/expirelist.c index 3c87c119..946a615c 100644 --- a/bus/expirelist.c +++ b/bus/expirelist.c @@ -40,6 +40,14 @@ struct BusExpireList static dbus_bool_t expire_timeout_handler (void *data); +static void +call_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); +} + BusExpireList* bus_expire_list_new (DBusLoop *loop, int expire_after, @@ -65,7 +73,9 @@ bus_expire_list_new (DBusLoop *loop, _dbus_timeout_set_enabled (list->timeout, FALSE); - if (!_dbus_loop_add_timeout (list->loop, list->timeout)) + if (!_dbus_loop_add_timeout (list->loop, + list->timeout, + call_timeout_callback, NULL, NULL)) goto failed; return list; @@ -84,7 +94,8 @@ bus_expire_list_free (BusExpireList *list) { _dbus_assert (list->items == NULL); - _dbus_loop_remove_timeout (list->loop, list->timeout); + _dbus_loop_remove_timeout (list->loop, list->timeout, + call_timeout_callback, NULL); _dbus_timeout_unref (list->timeout); @@ -32,12 +32,12 @@ #ifdef HAVE_SIGNAL_H #include <signal.h> #endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #ifdef HAVE_ERRNO_H #include <errno.h> #endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* for write() and STDERR_FILENO */ -#endif #include "selinux.h" static BusContext *context; @@ -48,7 +48,7 @@ static int reload_pipe[2]; #define RELOAD_READ_END 0 #define RELOAD_WRITE_END 1 -static void close_reload_pipe (DBusWatch **); +static void close_reload_pipe (void); typedef enum { @@ -231,7 +231,7 @@ handle_reload_watch (DBusWatch *watch, _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); - close_reload_pipe (&watch); + close_reload_pipe (); return TRUE; } @@ -286,6 +286,14 @@ handle_reload_watch (DBusWatch *watch, return TRUE; } +static dbus_bool_t +reload_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + return dbus_watch_handle (watch, condition); +} + static void setup_reload_pipe (DBusLoop *loop) { @@ -315,7 +323,8 @@ setup_reload_pipe (DBusLoop *loop) exit (1); } - if (!_dbus_loop_add_watch (loop, watch)) + if (!_dbus_loop_add_watch (loop, watch, reload_watch_callback, + NULL, NULL)) { _dbus_warn ("Unable to add reload watch to main loop: %s\n", error.message); @@ -326,13 +335,8 @@ setup_reload_pipe (DBusLoop *loop) } static void -close_reload_pipe (DBusWatch **watch) +close_reload_pipe (void) { - _dbus_loop_remove_watch (bus_context_get_loop (context), *watch); - _dbus_watch_invalidate (*watch); - _dbus_watch_unref (*watch); - *watch = NULL; - _dbus_close_socket (reload_pipe[RELOAD_READ_END], NULL); reload_pipe[RELOAD_READ_END] = -1; @@ -355,6 +359,7 @@ main (int argc, char **argv) int i; dbus_bool_t print_address; dbus_bool_t print_pid; + dbus_bool_t is_session_bus; int force_fork; dbus_bool_t systemd_activation; @@ -372,6 +377,7 @@ main (int argc, char **argv) print_address = FALSE; print_pid = FALSE; + is_session_bus = FALSE; force_fork = FORK_FOLLOW_CONFIG_FILE; systemd_activation = FALSE; diff --git a/bus/policy.c b/bus/policy.c index 34e84469..4841f47c 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -1280,3 +1280,18 @@ bus_client_policy_check_can_own (BusClientPolicy *policy, return allowed; } + +#ifdef DBUS_BUILD_TESTS + +dbus_bool_t +bus_policy_test (const DBusString *test_data_dir) +{ + /* This doesn't do anything for now because I decided to do it in + * dispatch.c instead by having some of the clients in dispatch.c + * have particular policies applied to them. + */ + + return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/bus/services.c b/bus/services.c index 68a7022a..0a049257 100644 --- a/bus/services.c +++ b/bus/services.c @@ -385,6 +385,7 @@ bus_registry_acquire_service (BusRegistry *registry, { dbus_bool_t retval; DBusConnection *old_owner_conn; + DBusConnection *current_owner_conn; BusClientPolicy *policy; BusService *service; BusActivation *activation; @@ -509,10 +510,12 @@ bus_registry_acquire_service (BusRegistry *registry, primary_owner = bus_service_get_primary_owner (service); if (primary_owner == NULL) goto out; - + + current_owner_conn = primary_owner->conn; + if (old_owner_conn == NULL) { - _dbus_assert (primary_owner->conn == connection); + _dbus_assert (current_owner_conn == connection); *result = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; } diff --git a/bus/signals.c b/bus/signals.c index 28506d3f..c85a88df 100644 --- a/bus/signals.c +++ b/bus/signals.c @@ -47,11 +47,8 @@ struct BusMatchRule int args_len; }; -#define BUS_MATCH_ARG_NAMESPACE 0x4000000u #define BUS_MATCH_ARG_IS_PATH 0x8000000u -#define BUS_MATCH_ARG_FLAGS (BUS_MATCH_ARG_NAMESPACE | BUS_MATCH_ARG_IS_PATH) - BusMatchRule* bus_match_rule_new (DBusConnection *matches_go_to) { @@ -138,9 +135,36 @@ match_rule_to_string (BusMatchRule *rule) if (rule->flags & BUS_MATCH_MESSAGE_TYPE) { - if (!_dbus_string_append_printf (&str, "type='%s'", - dbus_message_type_to_string (rule->message_type))) - goto nomem; + if (rule->message_type == DBUS_MESSAGE_TYPE_INVALID) + { + if (!_dbus_string_append_printf (&str, "type='INVALID'")) + goto nomem; + } + else if (rule->message_type == DBUS_MESSAGE_TYPE_METHOD_CALL) + { + if (!_dbus_string_append_printf (&str, "type='method_call'")) + goto nomem; + } + else if (rule->message_type == DBUS_MESSAGE_TYPE_METHOD_RETURN) + { + if (!_dbus_string_append_printf (&str, "type='method_return'")) + goto nomem; + } + else if (rule->message_type == DBUS_MESSAGE_TYPE_ERROR) + { + if (!_dbus_string_append_printf (&str, "type='error'")) + goto nomem; + } + else if (rule->message_type == DBUS_MESSAGE_TYPE_SIGNAL) + { + if (!_dbus_string_append_printf (&str, "type='signal'")) + goto nomem; + } + else + { + if (!_dbus_string_append_printf (&str, "type='%d'", rule->message_type)) + goto nomem; + } } if (rule->flags & BUS_MATCH_INTERFACE) @@ -179,18 +203,6 @@ match_rule_to_string (BusMatchRule *rule) goto nomem; } - if (rule->flags & BUS_MATCH_PATH_NAMESPACE) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "path_namespace='%s'", rule->path)) - goto nomem; - } - if (rule->flags & BUS_MATCH_SENDER) { if (_dbus_string_get_length (&str) > 0) @@ -215,20 +227,6 @@ match_rule_to_string (BusMatchRule *rule) goto nomem; } - if (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) - { - if (_dbus_string_get_length (&str) > 0) - { - if (!_dbus_string_append (&str, ",")) - goto nomem; - } - - if (!_dbus_string_append_printf (&str, "eavesdrop='%s'", - (rule->flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) ? - "true" : "false")) - goto nomem; - } - if (rule->flags & BUS_MATCH_ARGS) { int i; @@ -240,7 +238,7 @@ match_rule_to_string (BusMatchRule *rule) { if (rule->args[i] != NULL) { - dbus_bool_t is_path, is_namespace; + dbus_bool_t is_path; if (_dbus_string_get_length (&str) > 0) { @@ -249,13 +247,10 @@ match_rule_to_string (BusMatchRule *rule) } is_path = (rule->arg_lens[i] & BUS_MATCH_ARG_IS_PATH) != 0; - is_namespace = (rule->arg_lens[i] & BUS_MATCH_ARG_NAMESPACE) != 0; if (!_dbus_string_append_printf (&str, "arg%d%s='%s'", - i, - is_path ? "path" : - is_namespace ? "namespace" : "", + i, is_path ? "path" : "", rule->args[i])) goto nomem; } @@ -368,20 +363,9 @@ bus_match_rule_set_destination (BusMatchRule *rule, return TRUE; } -void -bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule, - dbus_bool_t is_eavesdropping) -{ - if (is_eavesdropping) - rule->flags |= BUS_MATCH_CLIENT_IS_EAVESDROPPING; - else - rule->flags &= ~(BUS_MATCH_CLIENT_IS_EAVESDROPPING); -} - dbus_bool_t bus_match_rule_set_path (BusMatchRule *rule, - const char *path, - dbus_bool_t is_namespace) + const char *path) { char *new; @@ -391,13 +375,7 @@ bus_match_rule_set_path (BusMatchRule *rule, if (new == NULL) return FALSE; - rule->flags &= ~(BUS_MATCH_PATH|BUS_MATCH_PATH_NAMESPACE); - - if (is_namespace) - rule->flags |= BUS_MATCH_PATH_NAMESPACE; - else - rule->flags |= BUS_MATCH_PATH; - + rule->flags |= BUS_MATCH_PATH; dbus_free (rule->path); rule->path = new; @@ -408,8 +386,7 @@ dbus_bool_t bus_match_rule_set_arg (BusMatchRule *rule, int arg, const DBusString *value, - dbus_bool_t is_path, - dbus_bool_t is_namespace) + dbus_bool_t is_path) { int length; char *new; @@ -476,9 +453,6 @@ bus_match_rule_set_arg (BusMatchRule *rule, if (is_path) rule->arg_lens[arg] |= BUS_MATCH_ARG_IS_PATH; - if (is_namespace) - rule->arg_lens[arg] |= BUS_MATCH_ARG_NAMESPACE; - /* NULL termination didn't get busted */ _dbus_assert (rule->args[rule->args_len] == NULL); _dbus_assert (rule->arg_lens[rule->args_len] == 0); @@ -773,8 +747,7 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule, const DBusString *value, DBusError *error) { - dbus_bool_t is_path = FALSE; - dbus_bool_t is_namespace = FALSE; + dbus_bool_t is_path; DBusString key_str; unsigned long arg; int length; @@ -805,35 +778,17 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule, goto failed; } - if (end != length) + if (end != length && + ((end + 4) != length || + !_dbus_string_ends_with_c_str (&key_str, "path"))) { - if ((end + strlen ("path")) == length && - _dbus_string_ends_with_c_str (&key_str, "path")) - { - is_path = TRUE; - } - else if (_dbus_string_equal_c_str (&key_str, "arg0namespace")) - { - int value_len = _dbus_string_get_length (value); - - is_namespace = TRUE; - - if (!_dbus_validate_bus_namespace (value, 0, value_len)) - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "arg0namespace='%s' is not a valid prefix of a bus name", - _dbus_string_get_const_data (value)); - goto failed; - } - } - else - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "Key '%s' in match rule contains junk after argument number (%u). Only 'arg%upath' (for example) or 'arg0namespace' are valid", key, arg, arg); - goto failed; - } + dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, + "Key '%s' in match rule contains junk after argument number. Only 'path' is optionally valid ('arg0path' for example).\n", key); + goto failed; } + is_path = end != length; + /* If we didn't check this we could allocate a huge amount of RAM */ if (arg > DBUS_MAXIMUM_MATCH_RULE_ARG_NUMBER) { @@ -851,7 +806,7 @@ bus_match_rule_parse_arg_match (BusMatchRule *rule, goto failed; } - if (!bus_match_rule_set_arg (rule, arg, value, is_path, is_namespace)) + if (!bus_match_rule_set_arg (rule, arg, value, is_path)) { BUS_SET_OOM (error); goto failed; @@ -1007,15 +962,12 @@ bus_match_rule_parse (DBusConnection *matches_go_to, goto failed; } } - else if (strcmp (key, "path") == 0 || - strcmp (key, "path_namespace") == 0) + else if (strcmp (key, "path") == 0) { - dbus_bool_t is_namespace = (strcmp (key, "path_namespace") == 0); - - if (rule->flags & (BUS_MATCH_PATH | BUS_MATCH_PATH_NAMESPACE)) + if (rule->flags & BUS_MATCH_PATH) { dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "path or path_namespace specified twice in match rule\n"); + "Key %s specified twice in match rule\n", key); goto failed; } @@ -1026,7 +978,7 @@ bus_match_rule_parse (DBusConnection *matches_go_to, goto failed; } - if (!bus_match_rule_set_path (rule, value, is_namespace)) + if (!bus_match_rule_set_path (rule, value)) { BUS_SET_OOM (error); goto failed; @@ -1054,31 +1006,6 @@ bus_match_rule_parse (DBusConnection *matches_go_to, goto failed; } } - else if (strcmp (key, "eavesdrop") == 0) - { - /* do not detect "eavesdrop" being used more than once in rule: - * 1) it's not possible, it's only in the flags - * 2) it might be used twice to disable eavesdropping when it's - * automatically added (eg dbus-monitor/bustle) */ - - /* we accept only "true|false" as possible values */ - if ((strcmp (value, "true") == 0)) - { - bus_match_rule_set_client_is_eavesdropping (rule, TRUE); - } - else if (strcmp (value, "false") == 0) - { - bus_match_rule_set_client_is_eavesdropping (rule, FALSE); - } - else - { - dbus_set_error (error, DBUS_ERROR_MATCH_RULE_INVALID, - "eavesdrop='%s' is invalid, " - "it should be 'true' or 'false'\n", - value); - goto failed; - } - } else if (strncmp (key, "arg", 3) == 0) { if (!bus_match_rule_parse_arg_match (rule, key, &tmp_str, error)) @@ -1388,7 +1315,7 @@ match_rule_equal (BusMatchRule *a, if ((a->flags & BUS_MATCH_PATH) && strcmp (a->path, b->path) != 0) return FALSE; - + if ((a->flags & BUS_MATCH_INTERFACE) && strcmp (a->interface, b->interface) != 0) return FALSE; @@ -1401,9 +1328,6 @@ match_rule_equal (BusMatchRule *a, strcmp (a->destination, b->destination) != 0) return FALSE; - /* we already compared the value of flags, and - * BUS_MATCH_CLIENT_IS_EAVESDROPPING does not have another struct member */ - if (a->flags & BUS_MATCH_ARGS) { int i; @@ -1422,7 +1346,7 @@ match_rule_equal (BusMatchRule *a, if (a->arg_lens[i] != b->arg_lens[i]) return FALSE; - length = a->arg_lens[i] & ~BUS_MATCH_ARG_FLAGS; + length = a->arg_lens[i] & ~BUS_MATCH_ARG_IS_PATH; if (a->args[i] != NULL) { @@ -1654,24 +1578,12 @@ connection_is_primary_owner (DBusConnection *connection, } static dbus_bool_t -str_has_prefix (const char *str, const char *prefix) -{ - size_t prefix_len; - prefix_len = strlen (prefix); - if (strncmp (str, prefix, prefix_len) == 0) - return TRUE; - else - return FALSE; -} - -static dbus_bool_t match_rule_matches (BusMatchRule *rule, DBusConnection *sender, DBusConnection *addressed_recipient, DBusMessage *message, BusMatchFlags already_matched) { - dbus_bool_t wants_to_eavesdrop = FALSE; int flags; /* All features of the match rule are AND'd together, @@ -1686,9 +1598,6 @@ match_rule_matches (BusMatchRule *rule, /* Don't bother re-matching features we've already checked implicitly. */ flags = rule->flags & (~already_matched); - if (flags & BUS_MATCH_CLIENT_IS_EAVESDROPPING) - wants_to_eavesdrop = TRUE; - if (flags & BUS_MATCH_MESSAGE_TYPE) { _dbus_assert (rule->message_type != DBUS_MESSAGE_TYPE_INVALID); @@ -1742,24 +1651,6 @@ match_rule_matches (BusMatchRule *rule, } } - /* Note: this part is relevant for eavesdropper rules: - * Two cases: - * 1) rule has a destination to be matched - * (flag BUS_MATCH_DESTINATION present). Rule will match if: - * - rule->destination matches the addressed_recipient - * AND - * - wants_to_eavesdrop=TRUE - * - * Note: (the case in which addressed_recipient is the actual rule owner - * is handled elsewere in dispatch.c:bus_dispatch_matches(). - * - * 2) rule has no destination. Rule will match if: - * - message has no specified destination (ie broadcasts) - * (Note: this will rule out unicast method calls and unicast signals, - * fixing FDO#269748) - * OR - * - wants_to_eavesdrop=TRUE (destination-catch-all situation) - */ if (flags & BUS_MATCH_DESTINATION) { const char *destination; @@ -1768,12 +1659,6 @@ match_rule_matches (BusMatchRule *rule, destination = dbus_message_get_destination (message); if (destination == NULL) - /* broadcast, but this rule specified a destination: no match */ - return FALSE; - - /* rule owner does not intend to eavesdrop: we'll deliver only msgs - * directed to it, NOT MATCHING */ - if (!wants_to_eavesdrop) return FALSE; if (addressed_recipient == NULL) @@ -1787,19 +1672,6 @@ match_rule_matches (BusMatchRule *rule, if (!connection_is_primary_owner (addressed_recipient, rule->destination)) return FALSE; } - } else { /* no destination in rule */ - dbus_bool_t msg_is_broadcast; - - _dbus_assert (rule->destination == NULL); - - msg_is_broadcast = (dbus_message_get_destination (message) == NULL); - - if (!wants_to_eavesdrop && !msg_is_broadcast) - return FALSE; - - /* if we are here rule owner intends to eavesdrop - * OR - * message is being broadcasted */ } if (flags & BUS_MATCH_PATH) @@ -1816,31 +1688,6 @@ match_rule_matches (BusMatchRule *rule, return FALSE; } - if (flags & BUS_MATCH_PATH_NAMESPACE) - { - const char *path; - int len; - - _dbus_assert (rule->path != NULL); - - path = dbus_message_get_path (message); - if (path == NULL) - return FALSE; - - if (!str_has_prefix (path, rule->path)) - return FALSE; - - len = strlen (rule->path); - - /* Check that the actual argument is within the expected - * namespace, rather than just starting with that string, - * by checking that the matched prefix is followed by a '/' - * or the end of the path. - */ - if (path[len] != '\0' && path[len] != '/') - return FALSE; - } - if (flags & BUS_MATCH_ARGS) { int i; @@ -1856,12 +1703,11 @@ match_rule_matches (BusMatchRule *rule, int current_type; const char *expected_arg; int expected_length; - dbus_bool_t is_path, is_namespace; + dbus_bool_t is_path; expected_arg = rule->args[i]; - expected_length = rule->arg_lens[i] & ~BUS_MATCH_ARG_FLAGS; + expected_length = rule->arg_lens[i] & ~BUS_MATCH_ARG_IS_PATH; is_path = (rule->arg_lens[i] & BUS_MATCH_ARG_IS_PATH) != 0; - is_namespace = (rule->arg_lens[i] & BUS_MATCH_ARG_NAMESPACE) != 0; current_type = dbus_message_iter_get_arg_type (&iter); @@ -1869,9 +1715,8 @@ match_rule_matches (BusMatchRule *rule, { const char *actual_arg; int actual_length; - - if (current_type != DBUS_TYPE_STRING && - (!is_path || current_type != DBUS_TYPE_OBJECT_PATH)) + + if (current_type != DBUS_TYPE_STRING) return FALSE; actual_arg = NULL; @@ -1894,32 +1739,6 @@ match_rule_matches (BusMatchRule *rule, MIN (actual_length, expected_length)) != 0) return FALSE; } - else if (is_namespace) - { - if (expected_length > actual_length) - return FALSE; - - /* If the actual argument doesn't start with the expected - * namespace, then we don't match. - */ - if (memcmp (expected_arg, actual_arg, expected_length) != 0) - return FALSE; - - if (expected_length < actual_length) - { - /* Check that the actual argument is within the expected - * namespace, rather than just starting with that string, - * by checking that the matched prefix ends in a '.'. - * - * This doesn't stop "foo.bar." matching "foo.bar..baz" - * which is an invalid namespace, but at some point the - * daemon can't cover up for broken services. - */ - if (actual_arg[expected_length] != '.') - return FALSE; - } - /* otherwise we had an exact match. */ - } else { if (expected_length != actual_length || @@ -2234,73 +2053,7 @@ test_parsing (void *data) bus_match_rule_unref (rule); } - - rule = check_parse (TRUE, "arg7path='/foo'"); - if (rule != NULL) - { - _dbus_assert (rule->flags = BUS_MATCH_ARGS); - _dbus_assert (rule->args != NULL); - _dbus_assert (rule->args_len == 8); - _dbus_assert (rule->args[7] != NULL); - _dbus_assert (rule->args[8] == NULL); - _dbus_assert (strcmp (rule->args[7], "/foo") == 0); - _dbus_assert ((rule->arg_lens[7] & BUS_MATCH_ARG_IS_PATH) - == BUS_MATCH_ARG_IS_PATH); - - bus_match_rule_unref (rule); - } - - /* Arg 0 namespace matches */ - rule = check_parse (TRUE, "arg0namespace='foo'"); - if (rule != NULL) - { - _dbus_assert (rule->flags == BUS_MATCH_ARGS); - _dbus_assert (rule->args != NULL); - _dbus_assert (rule->args_len == 1); - _dbus_assert (strcmp (rule->args[0], "foo") == 0); - _dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE) - == BUS_MATCH_ARG_NAMESPACE); - - bus_match_rule_unref (rule); - } - - rule = check_parse (TRUE, "arg0namespace='foo.bar'"); - if (rule != NULL) - { - _dbus_assert (rule->flags == BUS_MATCH_ARGS); - _dbus_assert (rule->args != NULL); - _dbus_assert (rule->args_len == 1); - _dbus_assert (strcmp (rule->args[0], "foo.bar") == 0); - _dbus_assert ((rule->arg_lens[0] & BUS_MATCH_ARG_NAMESPACE) - == BUS_MATCH_ARG_NAMESPACE); - - bus_match_rule_unref (rule); - } - - /* Only arg0namespace is supported. */ - rule = check_parse (FALSE, "arg1namespace='foo'"); - _dbus_assert (rule == NULL); - - /* An empty string isn't a valid namespace prefix (you should just not - * specify this key at all). - */ - rule = check_parse (FALSE, "arg0namespace=''"); - _dbus_assert (rule == NULL); - - /* Trailing periods aren't allowed (earlier versions of the arg0namespace - * spec allowed a single trailing period, which altered the semantics) */ - rule = check_parse (FALSE, "arg0namespace='foo.'"); - _dbus_assert (rule == NULL); - - rule = check_parse (FALSE, "arg0namespace='foo.bar.'"); - _dbus_assert (rule == NULL); - - rule = check_parse (FALSE, "arg0namespace='foo..'"); - _dbus_assert (rule == NULL); - - rule = check_parse (FALSE, "arg0namespace='foo.bar..'"); - _dbus_assert (rule == NULL); - + /* Too-large argN */ rule = check_parse (FALSE, "arg300='foo'"); _dbus_assert (rule == NULL); @@ -2321,24 +2074,6 @@ test_parsing (void *data) rule = check_parse (FALSE, "type='signal',type='method_call'"); _dbus_assert (rule == NULL); - rule = check_parse (TRUE, "path_namespace='/foo/bar'"); - if (rule != NULL) - { - _dbus_assert (rule->flags == BUS_MATCH_PATH_NAMESPACE); - _dbus_assert (rule->path != NULL); - _dbus_assert (strcmp (rule->path, "/foo/bar") == 0); - - bus_match_rule_unref (rule); - } - - /* Almost a duplicate */ - rule = check_parse (FALSE, "path='/foo',path_namespace='/foo'"); - _dbus_assert (rule == NULL); - - /* Trailing / was supported in the initial proposal, but now isn't */ - rule = check_parse (FALSE, "path_namespace='/foo/'"); - _dbus_assert (rule == NULL); - /* Duplicates with the argN code */ rule = check_parse (FALSE, "arg0='foo',arg0='bar'"); _dbus_assert (rule == NULL); @@ -2399,7 +2134,6 @@ static struct { { "type='method_call',arg0='blah',arg1='baz'", "arg0='blah',arg1='baz',type='method_call'" }, { "type='method_call',arg3='foosh'", "arg3='foosh',type='method_call'" }, { "arg3='fool'", "arg3='fool'" }, - { "arg0namespace='fool'", "arg0namespace='fool'" }, { "member='food'", "member='food'" } }; @@ -2469,13 +2203,6 @@ should_match_message_1[] = { "type='signal',member='Frobated',arg0='foobar'", "member='Frobated',arg0='foobar'", "type='signal',arg0='foobar'", - /* The definition of argXpath matches says: "As with normal argument matches, - * if the argument is exactly equal to the string given in the match rule - * then the rule is satisfied." So this should match (even though the - * argument is not a valid path)! - */ - "arg0path='foobar'", - "arg0namespace='foobar'", NULL }; @@ -2494,44 +2221,6 @@ should_not_match_message_1[] = { "arg0='foobar',arg1='abcdef'", "arg0='foobar',arg1='abcdef',arg2='abcdefghi',arg3='abcdefghi',arg4='abcdefghi'", "arg0='foobar',arg1='abcdef',arg4='abcdefghi',arg3='abcdefghi',arg2='abcdefghi'", - "arg0path='foo'", - "arg0path='foobar/'", - "arg1path='3'", - "arg0namespace='foo'", - "arg0namespace='foo',arg1='abcdef'", - "arg0namespace='moo'", - NULL -}; - -#define EXAMPLE_NAME "com.example.backend.foo" - -static const char * -should_match_message_2[] = { - /* EXAMPLE_NAME is in all of these namespaces */ - "arg0namespace='com.example.backend'", - "arg0namespace='com.example'", - "arg0namespace='com'", - - /* If the client specifies the name exactly, with no trailing period, then - * it should match. - */ - "arg0namespace='com.example.backend.foo'", - - NULL -}; - -static const char * -should_not_match_message_2[] = { - /* These are not even prefixes */ - "arg0namespace='com.example.backend.foo.bar'", - "arg0namespace='com.example.backend.foobar'", - - /* These are prefixes, but they're not parent namespaces. */ - "arg0namespace='com.example.backend.fo'", - "arg0namespace='com.example.backen'", - "arg0namespace='com.exampl'", - "arg0namespace='co'", - NULL }; @@ -2587,7 +2276,7 @@ check_matching (DBusMessage *message, static void test_matching (void) { - DBusMessage *message1, *message2; + DBusMessage *message1; const char *v_STRING; dbus_int32_t v_INT32; @@ -2609,185 +2298,6 @@ test_matching (void) should_not_match_message_1); dbus_message_unref (message1); - - message2 = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); - _dbus_assert (message2 != NULL); - if (!dbus_message_set_member (message2, "NameOwnerChanged")) - _dbus_assert_not_reached ("oom"); - - /* Obviously this isn't really a NameOwnerChanged signal. */ - v_STRING = EXAMPLE_NAME; - if (!dbus_message_append_args (message2, - DBUS_TYPE_STRING, &v_STRING, - NULL)) - _dbus_assert_not_reached ("oom"); - - check_matching (message2, 2, - should_match_message_2, - should_not_match_message_2); - - dbus_message_unref (message2); -} - -#define PATH_MATCH_RULE "arg0path='/aa/bb/'" - -/* This is a list of paths that should be matched by PATH_MATCH_RULE, taken - * from the specification. Notice that not all of them are actually legal D-Bus - * paths. - * - * The author of this test takes no responsibility for the semantics of - * this match rule key. - */ -static const char *paths_that_should_be_matched[] = { - "/aa/", - "/aa/bb/", - "/aa/bb/cc/", -#define FIRST_VALID_PATH_WHICH_SHOULD_MATCH 3 - "/", - "/aa/bb/cc", - NULL -}; - -/* These paths should not be matched by PATH_MATCH_RULE. */ -static const char *paths_that_should_not_be_matched[] = { - "/aa/b", - "/aa", - /* or even... */ - "/aa/bb", - NULL -}; - -static void -test_path_match (int type, - const char *path, - const char *rule_text, - BusMatchRule *rule, - dbus_bool_t should_match) -{ - DBusMessage *message = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); - dbus_bool_t matched; - - _dbus_assert (message != NULL); - if (!dbus_message_set_member (message, "Foo")) - _dbus_assert_not_reached ("oom"); - - if (!dbus_message_append_args (message, - type, &path, - NULL)) - _dbus_assert_not_reached ("oom"); - - matched = match_rule_matches (rule, NULL, NULL, message, 0); - - if (matched != should_match) - { - _dbus_warn ("Expected rule %s to %s message " - "with first arg %s of type '%c', failed\n", - rule_text, - should_match ? "match" : "not match", - path, - (char) type); - exit (1); - } - - dbus_message_unref (message); -} - -static void -test_path_matching (void) -{ - BusMatchRule *rule; - const char **s; - - rule = check_parse (TRUE, PATH_MATCH_RULE); - _dbus_assert (rule != NULL); - - for (s = paths_that_should_be_matched; *s != NULL; s++) - test_path_match (DBUS_TYPE_STRING, *s, PATH_MATCH_RULE, rule, TRUE); - - for (s = paths_that_should_be_matched + FIRST_VALID_PATH_WHICH_SHOULD_MATCH; - *s != NULL; s++) - test_path_match (DBUS_TYPE_OBJECT_PATH, *s, PATH_MATCH_RULE, rule, TRUE); - - for (s = paths_that_should_not_be_matched; *s != NULL; s++) - { - test_path_match (DBUS_TYPE_STRING, *s, PATH_MATCH_RULE, rule, FALSE); - test_path_match (DBUS_TYPE_OBJECT_PATH, *s, PATH_MATCH_RULE, rule, FALSE); - } - - bus_match_rule_unref (rule); -} - -static const char* -path_namespace_should_match_message_1[] = { - "type='signal',path_namespace='/foo'", - "type='signal',path_namespace='/foo/TheObjectManager'", - NULL -}; - -static const char* -path_namespace_should_not_match_message_1[] = { - "type='signal',path_namespace='/bar'", - "type='signal',path_namespace='/bar/TheObjectManager'", - NULL -}; - -static const char* -path_namespace_should_match_message_2[] = { - "type='signal',path_namespace='/foo/TheObjectManager'", - NULL -}; - -static const char* -path_namespace_should_not_match_message_2[] = { - NULL -}; - -static const char* -path_namespace_should_match_message_3[] = { - NULL -}; - -static const char* -path_namespace_should_not_match_message_3[] = { - "type='signal',path_namespace='/foo/TheObjectManager'", - NULL -}; - -static void -test_matching_path_namespace (void) -{ - DBusMessage *message1; - DBusMessage *message2; - DBusMessage *message3; - - message1 = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); - _dbus_assert (message1 != NULL); - if (!dbus_message_set_path (message1, "/foo/TheObjectManager")) - _dbus_assert_not_reached ("oom"); - - message2 = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); - _dbus_assert (message2 != NULL); - if (!dbus_message_set_path (message2, "/foo/TheObjectManager/child_object")) - _dbus_assert_not_reached ("oom"); - - message3 = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); - _dbus_assert (message3 != NULL); - if (!dbus_message_set_path (message3, "/foo/TheObjectManagerOther")) - _dbus_assert_not_reached ("oom"); - - check_matching (message1, 1, - path_namespace_should_match_message_1, - path_namespace_should_not_match_message_1); - check_matching (message2, 2, - path_namespace_should_match_message_2, - path_namespace_should_not_match_message_2); - check_matching (message3, 3, - path_namespace_should_match_message_3, - path_namespace_should_not_match_message_3); - - dbus_message_unref (message3); - dbus_message_unref (message2); - dbus_message_unref (message1); } dbus_bool_t @@ -2804,10 +2314,9 @@ bus_signals_test (const DBusString *test_data_dir) _dbus_assert_not_reached ("Parsing match rules test failed"); test_equality (); - test_matching (); - test_path_matching (); - test_matching_path_namespace (); + test_matching (); + return TRUE; } diff --git a/bus/signals.h b/bus/signals.h index a71d2e45..eeb1d2d0 100644 --- a/bus/signals.h +++ b/bus/signals.h @@ -31,15 +31,13 @@ typedef enum { - BUS_MATCH_MESSAGE_TYPE = 1 << 0, - BUS_MATCH_INTERFACE = 1 << 1, - BUS_MATCH_MEMBER = 1 << 2, - BUS_MATCH_SENDER = 1 << 3, - BUS_MATCH_DESTINATION = 1 << 4, - BUS_MATCH_PATH = 1 << 5, - BUS_MATCH_ARGS = 1 << 6, - BUS_MATCH_PATH_NAMESPACE = 1 << 7, - BUS_MATCH_CLIENT_IS_EAVESDROPPING = 1 << 8 + BUS_MATCH_MESSAGE_TYPE = 1 << 0, + BUS_MATCH_INTERFACE = 1 << 1, + BUS_MATCH_MEMBER = 1 << 2, + BUS_MATCH_SENDER = 1 << 3, + BUS_MATCH_DESTINATION = 1 << 4, + BUS_MATCH_PATH = 1 << 5, + BUS_MATCH_ARGS = 1 << 6 } BusMatchFlags; BusMatchRule* bus_match_rule_new (DBusConnection *matches_go_to); @@ -57,21 +55,11 @@ dbus_bool_t bus_match_rule_set_sender (BusMatchRule *rule, dbus_bool_t bus_match_rule_set_destination (BusMatchRule *rule, const char *destination); dbus_bool_t bus_match_rule_set_path (BusMatchRule *rule, - const char *path, - dbus_bool_t is_namespace); + const char *path); dbus_bool_t bus_match_rule_set_arg (BusMatchRule *rule, int arg, const DBusString *value, - dbus_bool_t is_path, - dbus_bool_t is_namespace); - -/* Calling this methods a client declares that it is creating a rule which - * needs to eavesdrop (e.g., dbus-monitor), any other created rules not - * setting themselves as eavesdropping won't receive any message not addressed - * to them, when eavedrop is enabled in the policy. On the other hand, when - * eavedrop is not enabled in policy, this method won't have any effect */ -void bus_match_rule_set_client_is_eavesdropping (BusMatchRule *rule, - dbus_bool_t is_eavesdropping); + dbus_bool_t is_path); BusMatchRule* bus_match_rule_parse (DBusConnection *matches_go_to, const DBusString *rule_text, diff --git a/bus/test-main.c b/bus/test-main.c index 1b7c5bea..a8039d51 100644 --- a/bus/test-main.c +++ b/bus/test-main.c @@ -130,6 +130,15 @@ main (int argc, char **argv) test_post_hook (); } + if (only == NULL || strcmp (only, "policy") == 0) + { + test_pre_hook (); + printf ("%s: Running policy test\n", argv[0]); + if (!bus_policy_test (&test_data_dir)) + die ("policy"); + test_post_hook (); + } + if (only == NULL || strcmp (only, "signals") == 0) { test_pre_hook (); @@ -37,31 +37,69 @@ static DBusList *clients = NULL; static DBusLoop *client_loop = NULL; static dbus_bool_t +client_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + /* FIXME this can be done in dbus-mainloop.c + * if the code in activation.c for the babysitter + * watch handler is fixed. + */ + + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t add_client_watch (DBusWatch *watch, void *data) { - return _dbus_loop_add_watch (client_loop, watch); + DBusConnection *connection = data; + + return _dbus_loop_add_watch (client_loop, + watch, client_watch_callback, connection, + NULL); } static void remove_client_watch (DBusWatch *watch, void *data) { - _dbus_loop_remove_watch (client_loop, watch); + DBusConnection *connection = data; + + _dbus_loop_remove_watch (client_loop, + watch, client_watch_callback, connection); +} + +static void +client_timeout_callback (DBusTimeout *timeout, + void *data) +{ + DBusConnection *connection = data; + + dbus_connection_ref (connection); + + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); + + dbus_connection_unref (connection); } static dbus_bool_t add_client_timeout (DBusTimeout *timeout, void *data) { - return _dbus_loop_add_timeout (client_loop, timeout); + DBusConnection *connection = data; + + return _dbus_loop_add_timeout (client_loop, timeout, client_timeout_callback, connection, NULL); } static void remove_client_timeout (DBusTimeout *timeout, void *data) { - _dbus_loop_remove_timeout (client_loop, timeout); + DBusConnection *connection = data; + + _dbus_loop_remove_timeout (client_loop, timeout, client_timeout_callback, connection); } static DBusHandlerResult @@ -32,6 +32,7 @@ dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir); dbus_bool_t bus_dispatch_sha1_test (const DBusString *test_data_dir); +dbus_bool_t bus_policy_test (const DBusString *test_data_dir); dbus_bool_t bus_config_parser_test (const DBusString *test_data_dir); dbus_bool_t bus_config_parser_trivial_test (const DBusString *test_data_dir); dbus_bool_t bus_signals_test (const DBusString *test_data_dir); diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index bcbd772f..51d27cd1 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,5 +1,18 @@ project(dbus) +######################################################################### +# detect version +######################################################################### +file (READ ../configure.ac configure_ac) +string (REGEX REPLACE ".*dbus_major_version], .([0-9]+).*" "\\1" DBUS_MAJOR_VERSION ${configure_ac}) +string (REGEX REPLACE ".*dbus_minor_version], .([0-9]+).*" "\\1" DBUS_MINOR_VERSION ${configure_ac}) +string (REGEX REPLACE ".*dbus_micro_version], .([0-9]+).*" "\\1" DBUS_MICRO_VERSION ${configure_ac}) +# used by file version info +set (DBUS_PATCH_VERSION "0") +set (DBUS_VERSION ${DBUS_MAJOR_VERSION}.${DBUS_MINOR_VERSION}.${DBUS_MICRO_VERSION}) + +set (DBUS_VERSION_STRING "${DBUS_VERSION}") + # we need to be up to date CMAKE_MINIMUM_REQUIRED(VERSION 2.4.4 FATAL_ERROR) if(COMMAND cmake_policy) @@ -9,12 +22,6 @@ endif(COMMAND cmake_policy) # where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/modules") -# detect version -include(MacrosAutotools) -autoversion(../configure.ac dbus) -# used by file version info -set (DBUS_PATCH_VERSION "0") - include(Macros) TIMESTAMP(DBUS_BUILD_TIMESTAMP) @@ -82,13 +89,11 @@ endif (WIN32) option (DBUS_USE_EXPAT "Use expat (== ON) or libxml2 (==OFF)" ON) if(NOT WIN32) - option (DBUS_ENABLE_ABSTRACT_SOCKETS "enable support for abstract sockets" ON) + OPTION(DBUS_ENABLE_ABSTRACT_SOCKETS "enable support for abstract sockets" ON) endif(NOT WIN32) #AC_ARG_ENABLE(asserts, AS_HELP_STRING([--enable-asserts],[include assertion checks]),enable_asserts=$enableval,enable_asserts=$USE_MAINTAINER_MODE) -option (DBUS_DISABLE_ASSERTS "Disable assertion checking" OFF) - -option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) +OPTION(DBUS_DISABLE_ASSERTS "Disable assertion checking" OFF) option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) @@ -226,24 +231,24 @@ ENABLE_TESTING() # TODO: take check from configure.in #AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests],[enable unit test code]),enable_tests=$enableval,enable_tests=$USE_MAINTAINER_MODE) -option (DBUS_BUILD_TESTS "enable unit test code" ON) +OPTION(DBUS_BUILD_TESTS "enable unit test code" ON) if(DBUS_BUILD_TESTS) add_definitions(-DDBUS_BUILD_TESTS -DDBUS_ENABLE_EMBEDDED_TESTS) endif(DBUS_BUILD_TESTS) -option (DBUS_USE_OUTPUT_DEBUG_STRING "enable win32 debug port for message output" OFF) +OPTION(DBUS_USE_OUTPUT_DEBUG_STRING "enable win32 debug port for message output" OFF) if(DBUS_USE_OUTPUT_DEBUG_STRING) add_definitions(-DDBUS_USE_OUTPUT_DEBUG_STRING) endif(DBUS_USE_OUTPUT_DEBUG_STRING) if(WIN32) # win32 dbus service support - this support is not complete - option (DBUS_SERVICE "enable dbus service installer" OFF) + OPTION(DBUS_SERVICE "enable dbus service installer" OFF) endif(WIN32) #AC_ARG_ENABLE(ansi, AS_HELP_STRING([--enable-ansi],[enable -ansi -pedantic gcc flags]),enable_ansi=$enableval,enable_ansi=no) -option (DBUS_ENABLE_ANSI "enable -ansi -pedantic gcc flags" OFF) +OPTION(DBUS_ENABLE_ANSI "enable -ansi -pedantic gcc flags" OFF) if(DBUS_ENABLE_ANSI) if(NOT MSVC) add_definitions(-ansi -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE -pedantic) @@ -253,14 +258,14 @@ if(DBUS_ENABLE_ANSI) endif(DBUS_ENABLE_ANSI) #AC_ARG_ENABLE(verbose-mode, AS_HELP_STRING([--enable-verbose-mode],[support verbose debug mode]),enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE) -option (DBUS_ENABLE_VERBOSE_MODE "support verbose debug mode" ON) +OPTION(DBUS_ENABLE_VERBOSE_MODE "support verbose debug mode" ON) #AC_ARG_ENABLE(checks, AS_HELP_STRING([--enable-checks],[include sanity checks on public API]),enable_checks=$enableval,enable_checks=yes) -option (DBUS_DISABLE_CHECKS "Disable public API sanity checking" OFF) +OPTION(DBUS_DISABLE_CHECKS "Disable public API sanity checking" OFF) if(NOT MSVC) #AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov],[compile with coverage profiling instrumentation (gcc only)]),enable_gcov=$enableval,enable_gcov=no) - option (DBUS_GCOV_ENABLED "compile with coverage profiling instrumentation (gcc only)" OFF) + OPTION(DBUS_GCOV_ENABLED "compile with coverage profiling instrumentation (gcc only)" OFF) if(DBUS_GCOV_ENABLED) add_definitions(-fprofile-arcs -ftest-coverage) # FIXME!!!! @@ -277,7 +282,7 @@ endif(NOT MSVC) #AC_ARG_ENABLE(dnotify, AS_HELP_STRING([--enable-dnotify],[build with dnotify support (linux only)]),enable_dnotify=$enableval,enable_dnotify=auto) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") - option (DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX "build with dnotify support (linux only)" ON) # add a check ! + OPTION(DBUS_BUS_ENABLE_DNOTIFY_ON_LINUX "build with dnotify support (linux only)" ON) # add a check ! endif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") #AC_ARG_ENABLE(kqueue, AS_HELP_STRING([--enable-kqueue],[build with kqueue support (FreeBSD only)]),enable_kqueue=$enableval,enable_kqueue=auto) @@ -286,7 +291,7 @@ endif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") #AC_ARG_ENABLE(console-owner-file, AS_HELP_STRING([--enable-console-owner-file],[enable console owner file]),enable_console_owner_file=$enableval,enable_console_owner_file=auto) STRING(TOUPPER ${CMAKE_SYSTEM_NAME} sysname) if("${sysname}" MATCHES ".*SOLARIS.*") - option (HAVE_CONSOLE_OWNER_FILE "enable console owner file (solaris only)" ON) + OPTION(HAVE_CONSOLE_OWNER_FILE "enable console owner file (solaris only)" ON) if(HAVE_CONSOLE_OWNER_FILE) set (DBUS_CONSOLE_OWNER_FILE "/dev/console" CACHE STRING "Directory to check for console ownerhip") endif(HAVE_CONSOLE_OWNER_FILE) @@ -346,26 +351,24 @@ set (DBUS_HAVE_ATOMIC_INT ${atomic_int} CACHE STRING "Some atomic integer implem set (DBUS_USE_ATOMIC_INT_486 ${atomic_int_486} CACHE STRING "Use atomic integer implementation for 486") if(X11_FOUND) - option (DBUS_BUILD_X11 "Build with X11 autolaunch support " ON) + OPTION(DBUS_BUILD_X11 "Build with X11 autolaunch support " ON) endif(X11_FOUND) # test binary names if (WIN32) set (EXT ".exe") - # compatible with Automake .in files - set (EXEEXT ".exe") endif(WIN32) if (MSVC_IDE) if(CMAKE_BUILD_TYPE MATCHES Debug) - set(IDE_BIN /Debug ) + set(IDE_BIN Debug/ ) message(STATUS) message(STATUS "Visual Studio: test programs will only work with 'Debug' configuration!") message(STATUS "To run tests with 'Release' configuration use -DCMAKE_BUILD_TYPE=Release") message(STATUS "Add '..\\..\\test\\data' to the command line option of the test programs") message(STATUS) else(CMAKE_BUILD_TYPE MATCHES Debug) - set(IDE_BIN /Release) + set(IDE_BIN Release/) message(STATUS) message(STATUS "Visual Studio: test programs will only work with 'Release' configuration!") message(STATUS "To run tests with 'Debug' configuration use -DCMAKE_BUILD_TYPE=Debug") @@ -377,6 +380,11 @@ if (MSVC_IDE) endif (MSVC_IDE) set(TEST_SERVICE_DIR ${CMAKE_BINARY_DIR}/test/data/valid-service-files CACHE STRING "Full path to test file test/data/valid-service-files in builddir" ) +set(TEST_SERVICE_BINARY ${CMAKE_BINARY_DIR}/bin/${IDE_BIN}test-service${EXT} CACHE STRING "Full path to test file test/test-service in builddir" ${TEST_PATH_FORCE}) +set(TEST_SHELL_SERVICE_BINARY ${CMAKE_BINARY_DIR}/bin/${IDE_BIN}test-shell-service${EXT} CACHE STRING "Full path to test file test/test-shell-service in builddir" ${TEST_PATH_FORCE}) +set(TEST_EXIT_BINARY ${CMAKE_BINARY_DIR}/bin/${IDE_BIN}test-exit${EXT} CACHE STRING "Full path to test file test/test-exit in builddir" ${TEST_PATH_FORCE}) +set(TEST_SEGFAULT_BINARY ${CMAKE_BINARY_DIR}/bin/${IDE_BIN}test-segfault${EXT} CACHE STRING "Full path to test file test/test-segfault in builddir" ${TEST_PATH_FORCE}) +set(TEST_SLEEP_FOREVER_BINARY ${CMAKE_BINARY_DIR}/bin/${IDE_BIN}test-sleep-forever${EXT} CACHE STRING "Full path to test file test/test-sleep-forever in builddir" ${TEST_PATH_FORCE}) #### Find socket directories if (NOT $ENV{TMPDIR} STREQUAL "") @@ -433,16 +441,16 @@ set (DBUS_USER ) if (WIN32) - set (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "autolaunch:" CACHE STRING "system bus default address") - set (DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:" CACHE STRING "session bus default address") + set (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "nonce-tcp:" CACHE STRING "system bus default address" ) + set (DBUS_SESSION_BUS_DEFAULT_ADDRESS "nonce-tcp:" CACHE STRING "session bus default address" ) set (DBUS_SYSTEM_CONFIG_FILE "etc/dbus-1/system.conf") set (DBUS_SESSION_CONFIG_FILE "etc/dbus-1/session.conf") # bus-test expects a non empty string set (DBUS_USER "Administrator") else (WIN32) - set (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:tmpdir=" CACHE STRING "system bus default address") - set (DBUS_SESSION_BUS_DEFAULT_ADDRESS "unix:path=${DBUS_SESSION_SOCKET_DIR}" CACHE STRING "session bus default address") + set (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:tmpdir=" CACHE STRING "system bus default address" ) + set (DBUS_SESSION_BUS_DEFAULT_ADDRESS "unix:path=${DBUS_SESSION_SOCKET_DIR}" CACHE STRING "session bus default address" ) set (sysconfdir "") set (configdir ${sysconfdir}/dbus-1 ) set (DBUS_SYSTEM_CONFIG_FILE ${configdir}/system.conf) @@ -450,7 +458,7 @@ else (WIN32) set (DBUS_USER "root") endif (WIN32) -set (DBUS_DAEMON_NAME "dbus-daemon" CACHE STRING "The name of the dbus daemon executable") +set(DBUS_DAEMON_NAME dbus-daemon CACHE STRING "The name of the dbus daemon executable") ########### create config.h ############### @@ -463,15 +471,17 @@ endif(MINGW) # compiler definitions add_definitions(-DHAVE_CONFIG_H=1) -add_definitions(${DBUS_BUS_CFLAGS}) +add_definitions(${DBUS_BUS_CFLAGS} -DDBUS_API_SUBJECT_TO_CHANGE) if (DBUS_BUILD_TESTS) # set variables used for the .in files (substituted by configure_file) in test/data: - set(DBUS_TEST_EXEC ${EXECUTABLE_OUTPUT_PATH}${IDE_BIN}) - set(DBUS_TEST_DATA ${CMAKE_BINARY_DIR}/test/data) + set(TEST_VALID_SERVICE_DIR ${CMAKE_BINARY_DIR}/test/data/valid-service-files) + set(TEST_VALID_SERVICE_SYSTEM_DIR ${CMAKE_BINARY_DIR}/test/data/valid-service-files-system) + set(TEST_INVALID_SERVICE_SYSTEM_DIR ${CMAKE_BINARY_DIR}/test/data/invalid-service-files-system) set(TEST_SOCKET_DIR ${DBUS_SESSION_SOCKET_DIR} ) set(TEST_LAUNCH_HELPER_BINARY ${EXECUTABLE_OUTPUT_PATH}/dbus-daemon-launch-helper-test) + set(TEST_PRIVSERVER_BINARY ${EXECUTABLE_OUTPUT_PATH}/test-privserver) if (UNIX) set (TEST_LISTEN "debug-pipe:name=test-server</listen><listen>unix:tmpdir=${TEST_SOCKET_DIR}") set (TEST_CONNECTION "debug-pipe:name=test-server") diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake index 768bf2db..b4bfc802 100644 --- a/cmake/config.h.cmake +++ b/cmake/config.h.cmake @@ -33,11 +33,18 @@ #define TEST_CONNECTION "@TEST_CONNECTION@" // test binaries -#define DBUS_TEST_EXEC "@DBUS_TEST_EXEC@" -#define DBUS_EXEEXT "@EXEEXT@" - /* Full path to test file test/test-exit in builddir */ #define TEST_BUS_BINARY "@TEST_BUS_BINARY@" +/* Full path to test file test/test-exit in builddir */ +#define TEST_EXIT_BINARY "@TEST_EXIT_BINARY@" +/* Full path to test file test/test-segfault in builddir */ +#define TEST_SEGFAULT_BINARY "@TEST_SEGFAULT_BINARY@" +/* Full path to test file test/test-service in builddir */ +#define TEST_SERVICE_BINARY "@TEST_SERVICE_BINARY@" +/* Full path to test file test/test-shell-service in builddir */ +#define TEST_SHELL_SERVICE_BINARY "@TEST_SHELL_SERVICE_BINARY@" +/* Full path to test file test/test-sleep-forever in builddir */ +#define TEST_SLEEP_FOREVER_BINARY "@TEST_SLEEP_FOREVER_BINARY@" /* Some dbus features */ #cmakedefine DBUS_BUILD_TESTS 1 diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt index 4ec702d7..9a259d22 100644 --- a/cmake/test/CMakeLists.txt +++ b/cmake/test/CMakeLists.txt @@ -2,20 +2,24 @@ project(test) add_definitions(${DBUS_INTERNAL_CLIENT_DEFINITIONS}) -add_library(dbus-testutils STATIC +add_library(dbus_testutils STATIC ${CMAKE_SOURCE_DIR}/../test/test-utils.h ${CMAKE_SOURCE_DIR}/../test/test-utils.c ) -target_link_libraries(dbus-testutils ${DBUS_INTERNAL_LIBRARIES}) +target_link_libraries(dbus_testutils ${DBUS_INTERNAL_LIBRARIES}) add_subdirectory( name-test ) set (test-service_SOURCES ${CMAKE_SOURCE_DIR}/../test/test-service.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.h ) set (test-names_SOURCES ${CMAKE_SOURCE_DIR}/../test/test-names.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.h ) set (break_loader_SOURCES @@ -24,6 +28,8 @@ set (break_loader_SOURCES set (test-shell-service_SOURCES ${CMAKE_SOURCE_DIR}/../test/test-shell-service.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.c + ${CMAKE_SOURCE_DIR}/../test/test-utils.h ) set (shell-test_SOURCES @@ -47,17 +53,17 @@ set (test-sleep-forever_SOURCES ) add_executable(test-service ${test-service_SOURCES}) -target_link_libraries(test-service dbus-testutils) +target_link_libraries(test-service ${DBUS_INTERNAL_LIBRARIES}) add_executable(test-names ${test-names_SOURCES}) -target_link_libraries(test-names dbus-testutils) +target_link_libraries(test-names ${DBUS_INTERNAL_LIBRARIES}) add_executable(shell-test ${shell-test_SOURCES}) target_link_libraries(shell-test ${DBUS_INTERNAL_LIBRARIES}) ADD_TEST(shell-test ${EXECUTABLE_OUTPUT_PATH}/shell-test${EXT}) add_executable(test-shell-service ${test-shell-service_SOURCES}) -target_link_libraries(test-shell-service dbus-testutils) +target_link_libraries(test-shell-service ${DBUS_INTERNAL_LIBRARIES}) add_executable(spawn-test ${spawn-test_SOURCES}) target_link_libraries(spawn-test ${DBUS_INTERNAL_LIBRARIES}) diff --git a/cmake/test/name-test/CMakeLists.txt b/cmake/test/name-test/CMakeLists.txt index 80b9908b..25ec7f65 100644 --- a/cmake/test/name-test/CMakeLists.txt +++ b/cmake/test/name-test/CMakeLists.txt @@ -21,19 +21,19 @@ target_link_libraries(test-ids ${DBUS_INTERNAL_LIBRARIES}) ADD_TEST(test-ids ${EXECUTABLE_OUTPUT_PATH}/test-ids) add_executable(test-shutdown ${NAMEtest-DIR}/test-shutdown.c) -target_link_libraries(test-shutdown dbus-testutils) +target_link_libraries(test-shutdown ${DBUS_INTERNAL_LIBRARIES} dbus_testutils) ADD_TEST(test-shutdown ${EXECUTABLE_OUTPUT_PATH}/test-shutdown) add_executable(test-privserver ${NAMEtest-DIR}/test-privserver.c) -target_link_libraries(test-privserver dbus-testutils) +target_link_libraries(test-privserver ${DBUS_INTERNAL_LIBRARIES} dbus_testutils) ADD_TEST(test-privserver ${EXECUTABLE_OUTPUT_PATH}/test-privserver) add_executable(test-privserver-client ${NAMEtest-DIR}/test-privserver-client.c) -target_link_libraries(test-privserver-client dbus-testutils) +target_link_libraries(test-privserver-client ${DBUS_INTERNAL_LIBRARIES} dbus_testutils) ADD_TEST(test-privserver-client ${EXECUTABLE_OUTPUT_PATH}/test-privserver-client) add_executable(test-autolaunch ${NAMEtest-DIR}/test-autolaunch.c) -target_link_libraries(test-autolaunch dbus-testutils) +target_link_libraries(test-autolaunch ${DBUS_INTERNAL_LIBRARIES} dbus_testutils) ADD_TEST(test-autolaunch ${EXECUTABLE_OUTPUT_PATH}/test-autolaunch) endif (DBUS_BUILD_TESTS) diff --git a/cmake/tools/CMakeLists.txt b/cmake/tools/CMakeLists.txt index 101c7e60..e91a5094 100644 --- a/cmake/tools/CMakeLists.txt +++ b/cmake/tools/CMakeLists.txt @@ -33,6 +33,14 @@ set (dbus_cleanup_sockets_SOURCES ../../tools/dbus-cleanup-sockets.c ) +set (dbus_viewer_SOURCES + ../../tools/dbus-names-model.c + ../../tools/dbus-names-model.h + ../../tools/dbus-tree-view.c + ../../tools/dbus-tree-view.h + ../../tools/dbus-viewer.c +) + add_executable(dbus-send ${dbus_send_SOURCES}) target_link_libraries(dbus-send ${DBUS_LIBRARIES}) install_targets(/bin dbus-send ) diff --git a/configure.ac b/configure.ac index ee3412f4..23e886f9 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl -*- mode: m4 -*- AC_PREREQ([2.63]) m4_define([dbus_major_version], [1]) -m4_define([dbus_minor_version], [5]) -m4_define([dbus_micro_version], [9]) +m4_define([dbus_minor_version], [4]) +m4_define([dbus_micro_version], [17]) m4_define([dbus_version], [dbus_major_version.dbus_minor_version.dbus_micro_version]) AC_INIT([dbus],[dbus_version],[https://bugs.freedesktop.org/enter_bug.cgi?product=dbus],[dbus]) @@ -32,16 +32,16 @@ AC_DEFINE_UNQUOTED(DBUS_DAEMON_NAME,"dbus-daemon",[Name of executable]) # ## increment if the interface has additions, changes, removals. -LT_CURRENT=9 +LT_CURRENT=8 ## increment any time the source changes; set to ## 0 if you increment CURRENT -LT_REVISION=4 +LT_REVISION=8 ## increment if any interfaces have been added; set to 0 ## if any interfaces have been changed or removed. removal has ## precedence over adding, so set to 0 if both happened. -LT_AGE=6 +LT_AGE=5 AC_SUBST(LT_CURRENT) AC_SUBST(LT_REVISION) @@ -149,7 +149,6 @@ AC_ARG_WITH(console-owner-file, AS_HELP_STRING([--with-console-owner-file=[filen AC_ARG_WITH(launchd-agent-dir, AS_HELP_STRING([--with-launchd-agent-dir=[dirname]],[directory to put the launchd agent (default: /Library/LaunchAgents)])) AC_ARG_WITH(dbus_user, AS_HELP_STRING([--with-dbus-user=<user>],[User for running the DBUS daemon (messagebus)])) AC_ARG_WITH(dbus_daemondir, AS_HELP_STRING([--with-dbus-daemondir=[dirname]],[Directory for installing the DBUS daemon])) -AC_ARG_WITH(dbus_session_bus_default_address, AS_HELP_STRING([--with-dbus-session-bus-default-address=[nonce-tcp:/autolaunch:/tcp:host:port]],[Transport Type to be used (default: nonce-tcp:)]),with_dbus_session_bus_default_address=$withval,with_dbus_session_bus_default_address=nonce-tcp:) AC_ARG_ENABLE([embedded-tests], AS_HELP_STRING([--enable-embedded-tests], @@ -250,7 +249,6 @@ fi if test x$enable_asserts = xno; then AC_DEFINE(DBUS_DISABLE_ASSERT,1,[Disable assertion checking]) - DISABLE_UNUSED_WARNINGS="unused-label" R_DYNAMIC_LDFLAG="" else # -rdynamic is needed for glibc's backtrace_symbols to work. @@ -268,7 +266,6 @@ AC_SUBST(R_DYNAMIC_LDFLAG) if test x$enable_checks = xno; then AC_DEFINE(DBUS_DISABLE_CHECKS,1,[Disable public API sanity checking]) AC_DEFINE(G_DISABLE_CHECKS,1,[Disable GLib public API sanity checking]) - DISABLE_UNUSED_WARNINGS="unused-label" fi if test x$enable_userdb_cache = xyes; then @@ -315,12 +312,6 @@ AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(__int64) -AC_ARG_WITH([64-bit], - [AS_HELP_STRING([--without-64-bit], - [If you have to use this option, please report it as a bug])], - [], - [with_64_bit=yes]) - ### See what our 64 bit type is called AC_MSG_CHECKING([64-bit integer type]) @@ -358,32 +349,13 @@ $ac_cv_sizeof___int64) ;; esac -AS_IF( - [test "x$with_64_bit" = xno], - [ +if test -z "$dbusint64" ; then DBUS_INT64_TYPE="no_int64_type_detected" DBUS_HAVE_INT64=0 DBUS_INT64_CONSTANT= DBUS_UINT64_CONSTANT= - AC_MSG_RESULT([disabled via --without-64-bit]) - ], - dnl else if - [test -z "$dbusint64"], - [AC_MSG_RESULT([not found]) - AC_MSG_ERROR([Could not find a 64-bit integer type. - -Please report a bug here with details of your platform and compiler: - - http://bugs.freedesktop.org/enter_bug.cgi?product=DBus&component=core - -To compile D-Bus with all 64-bit integer types removed (not recommended), use -the option "--without-64-bit". - -This option is likely to be removed in future, unless you report that your -platform needs it.]) - ], - dnl else - [ + AC_MSG_RESULT([none found]) +else DBUS_INT64_TYPE="$dbusint64" DBUS_HAVE_INT64=1 DBUS_INT64_CONSTANT="$dbusint64_constant" @@ -392,7 +364,7 @@ platform needs it.]) AC_DEFINE_UNQUOTED(DBUS_INT64_PRINTF_MODIFIER, [$dbusint64_printf_modifier], [Define to printf modifier for 64 bit integer type]) fi AC_MSG_RESULT($DBUS_INT64_TYPE) - ]) +fi AC_SUBST(DBUS_INT64_TYPE) AC_SUBST(DBUS_INT64_CONSTANT) @@ -923,8 +895,6 @@ if $dbus_use_libxml; then XML_LIBS=$LIBXML_LIBS XML_CFLAGS=$LIBXML_CFLAGS fi -AC_SUBST([XML_CFLAGS]) -AC_SUBST([XML_LIBS]) # Thread lib detection AC_CHECK_FUNC(pthread_cond_timedwait,[AC_CHECK_LIB(pthread,pthread_cond_timedwait, @@ -955,8 +925,6 @@ fi fi LIBS="$save_libs" -AC_SUBST([THREAD_LIBS]) - # SELinux detection if test x$enable_selinux = xno ; then have_selinux=no; @@ -1124,9 +1092,7 @@ if test x$have_libaudit = xyes ; then AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support]) fi -AC_SUBST([SELINUX_LIBS]) - -# Check for ADT API (Solaris Basic Security Mode auditing) +# Check for ADT API AC_MSG_CHECKING(for ADT API) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <bsm/adt.h> @@ -1142,7 +1108,6 @@ then else AC_MSG_RESULT(no) fi -AC_SUBST([ADT_LIBS]) # Check for SCM_RIGHTS AC_MSG_CHECKING([for SCM_RIGHTS]) @@ -1164,11 +1129,26 @@ if test x$dbus_win = xyes ; then fi fi -AC_SUBST([NETWORK_libs]) - #### Set up final flags -LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs" -AC_SUBST([LIBDBUS_LIBS]) +DBUS_CLIENT_CFLAGS= +DBUS_CLIENT_LIBS="$THREAD_LIBS $NETWORK_libs" +AC_SUBST(DBUS_CLIENT_CFLAGS) +AC_SUBST(DBUS_CLIENT_LIBS) + +DBUS_BUS_CFLAGS="$XML_CFLAGS" +DBUS_BUS_LIBS="$XML_LIBS $SELINUX_LIBS $THREAD_LIBS $ADT_LIBS $NETWORK_libs" +AC_SUBST(DBUS_BUS_CFLAGS) +AC_SUBST(DBUS_BUS_LIBS) + +DBUS_LAUNCHER_CFLAGS="$XML_CFLAGS" +DBUS_LAUNCHER_LIBS="$XML_LIBS $THREAD_LIBS $NETWORK_libs" +AC_SUBST(DBUS_LAUNCHER_CFLAGS) +AC_SUBST(DBUS_LAUNCHER_LIBS) + +DBUS_TEST_CFLAGS= +DBUS_TEST_LIBS="$THREAD_LIBS $NETWORK_libs" +AC_SUBST(DBUS_TEST_CFLAGS) +AC_SUBST(DBUS_TEST_LIBS) ### X11 detection DBUS_X_LIBS= @@ -1236,9 +1216,8 @@ TP_COMPILER_WARNINGS([WARNING_CFLAGS], dnl Override with --enable-Werror or --disable-Werror [test x$dbus_win != xyes -a x$dbus_cygwin != xyes -a x$USE_MAINTAINER_MODE = xyes], - dnl Enable these warnings if possible: + dnl enable these warnings if possible: [all \ - extra \ char-subscripts \ missing-declarations \ missing-prototypes \ @@ -1250,25 +1229,12 @@ TP_COMPILER_WARNINGS([WARNING_CFLAGS], declaration-after-statement \ ], - dnl Disable these warnings if possible, make them non-fatal if possible, - dnl and don't enable -Werror unless we succeeded. - dnl - dnl Intentional: - dnl - $DISABLE_UNUSED_WARNINGS disables unused-label warnings if not - dnl checking or not asserting - dnl - missing field initializers being 0 is a C feature, not a bug - dnl - unused-parameter is to make writing callbacks less annoying - dnl - dnl To be fixed one day: - dnl - sign-compare and pointer-sign are workarounds for fd.o #17433 - dnl - type-limits is probably a bug too, but having the rest of -Wextra - dnl is better than nothing - [$DISABLE_UNUSED_WARNINGS \ - missing-field-initializers \ - unused-parameter \ + dnl disable these warnings if possible, make them non-fatal if possible, + dnl and don't enable -Werror unless we succeeded: + dnl (unused is by design, sign-compare and pointer-sign are fd.o #17433) + [unused \ sign-compare \ pointer-sign \ - type-limits \ ]) if test "x$GCC" = "xyes"; then @@ -1520,19 +1486,31 @@ DBUS_PWD=`pwd` # Useful in a cross-compilation environment, where the tests are run on the host system. AC_ARG_WITH(dbus-test-dir, AS_HELP_STRING([--with-dbus-test-dir=[dirname]],[path where the tests tools are available]), DBUS_PWD=$withval) +AC_DEFUN([TEST_PATH], [ +TEST_$1=${DBUS_PWD}/test/$2 +AC_DEFINE_UNQUOTED(TEST_$1, "$TEST_$1", + [Full path to test file test/$2 in builddir]) +AC_SUBST(TEST_$1) +]) +AC_DEFUN([TEST_PROG], [ +TEST_$1=${DBUS_PWD}/test/$2 +AC_DEFINE_UNQUOTED(TEST_$1, "$TEST_$1$EXEEXT", + [Full path to test file test/$2 in builddir]) +AC_SUBST(TEST_$1) +]) -DBUS_TEST_EXEC="$DBUS_PWD/test" -DBUS_TEST_DATA="$DBUS_PWD/test/data" - -AC_SUBST([DBUS_TEST_DATA]) -AC_SUBST([DBUS_TEST_EXEC]) - -AC_DEFINE_UNQUOTED([DBUS_TEST_EXEC], ["$DBUS_TEST_EXEC"], - [Full path to the daemon in the builddir]) -AC_DEFINE_UNQUOTED([DBUS_EXEEXT], ["$EXEEXT"], - [Extension for executables, typically empty or .exe]) - -AC_DEFINE_UNQUOTED(TEST_BUS_BINARY, ["$DBUS_PWD/bus/dbus-daemon$EXEEXT"], +TEST_PATH(VALID_SERVICE_DIR, data/valid-service-files) +TEST_PATH(INVALID_SERVICE_DIR, data/invalid-service-files) +TEST_PATH(VALID_SERVICE_SYSTEM_DIR, data/valid-service-files-system) +TEST_PATH(INVALID_SERVICE_SYSTEM_DIR, data/invalid-service-files-system) +TEST_PROG(SERVICE_BINARY, test-service) +TEST_PROG(SHELL_SERVICE_BINARY, test-shell-service) +TEST_PROG(EXIT_BINARY, test-exit) +TEST_PROG(SEGFAULT_BINARY, test-segfault) +TEST_PROG(SLEEP_FOREVER_BINARY, test-sleep-forever) +TEST_PROG(PRIVSERVER_BINARY, name-test/test-privserver) + +AC_DEFINE_UNQUOTED(TEST_BUS_BINARY, "$DBUS_PWD/bus/dbus-daemon$EXEEXT", [Full path to the daemon in the builddir]) AC_SUBST(TEST_BUS_BINARY) @@ -1572,7 +1550,7 @@ AC_DEFINE_UNQUOTED(DBUS_SESSION_SOCKET_DIR, "$DBUS_SESSION_SOCKET_DIR", [Where p AC_SUBST(DBUS_SESSION_SOCKET_DIR) if test x$dbus_win = xyes; then - DBUS_SESSION_BUS_DEFAULT_ADDRESS="$with_dbus_session_bus_default_address" + DBUS_SESSION_BUS_DEFAULT_ADDRESS="nonce-tcp:" elif test x$have_launchd = xyes; then DBUS_SESSION_BUS_DEFAULT_ADDRESS="launchd:env=DBUS_LAUNCHD_SESSION_BUS_SOCKET" else @@ -1592,15 +1570,6 @@ AH_VERBATIM(_DARWIN_ENVIRON, #endif ]) -AC_ARG_ENABLE([stats], - [AS_HELP_STRING([--enable-stats], - [enable bus daemon usage statistics])], - [], [enable_stats=no]) -if test "x$enable_stats" = xyes; then - AC_DEFINE([DBUS_ENABLE_STATS], [1], - [Define to enable bus daemon usage statistics]) -fi - AC_CONFIG_FILES([ Doxyfile dbus/versioninfo.rc @@ -1676,7 +1645,6 @@ echo " Building verbose mode: ${enable_verbose_mode} Building assertions: ${enable_asserts} Building checks: ${enable_checks} - Building bus stats API: ${enable_stats} Building SELinux support: ${have_selinux} Building inotify support: ${have_inotify} Building dnotify support: ${have_dnotify} @@ -1727,16 +1695,3 @@ if test x$dbus_use_libxml = xtrue; then echo echo "WARNING: You have chosen to use libxml as your xml parser however this code path is not maintained by the D-Bus developers and if it breaks you get to keep the pieces. If you have selected this option in err please reconfigure with expat (e.g. --with-xml=expat)." fi - -if test "x$DBUS_HAVE_INT64" = x0; then - AC_MSG_WARN([You have disabled 64-bit integers via --without-64-bit. - - This removes parts of the standard D-Bus API and ABI (the 't' and 'x' - typecodes, the dbus_int64_t and dbus_uint64_t types, etc.) and should only be - used if your compiler lacks support for 64-bit integers. Please report a bug - with details of your platform and compiler. - - This option is likely to be removed in future, unless the D-Bus developers - receive reports that it is still needed. - ]) -fi diff --git a/dbus-1-uninstalled.pc.in b/dbus-1-uninstalled.pc.in index f0072325..082222d6 100644 --- a/dbus-1-uninstalled.pc.in +++ b/dbus-1-uninstalled.pc.in @@ -13,5 +13,5 @@ Name: dbus Description: Free desktop message bus (uninstalled copy) Version: @VERSION@ Libs: ${abs_top_builddir}/dbus/libdbus-1.la -Libs.private: @LIBDBUS_LIBS@ +Libs.private: @DBUS_CLIENT_LIBS@ Cflags: -I${abs_top_srcdir} diff --git a/dbus-1.pc.in b/dbus-1.pc.in index 7201e07f..e3e63c4f 100644 --- a/dbus-1.pc.in +++ b/dbus-1.pc.in @@ -12,6 +12,5 @@ daemondir=@DBUS_DAEMONDIR@ Name: dbus Description: Free desktop message bus Version: @VERSION@ -Libs: -L${libdir} -ldbus-1 -Libs.private: @LIBDBUS_LIBS@ +Libs: -L${libdir} -ldbus-1 @DBUS_CLIENT_LIBS@ Cflags: -I${includedir}/dbus-1.0 -I${libdir}/dbus-1.0/include diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 3c44ae49..094773c9 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -1,17 +1,12 @@ configdir=$(sysconfdir)/dbus-1 -AM_CPPFLAGS = \ - -I$(top_builddir) \ - -I$(top_srcdir) \ +INCLUDES = -I$(top_builddir) -I$(top_srcdir) \ + $(DBUS_CLIENT_CFLAGS) \ -DDBUS_COMPILATION \ -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" \ -DDBUS_SYSTEM_CONFIG_FILE=\""$(configdir)/system.conf"\" \ - -DDBUS_SESSION_CONFIG_FILE=\""$(configdir)/session.conf"\" \ - $(NULL) - -# if assertions are enabled, improve backtraces -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ + -DDBUS_SESSION_CONFIG_FILE=\""$(configdir)/session.conf"\" dbusincludedir=$(includedir)/dbus-1.0/dbus dbusarchincludedir=$(libdir)/dbus-1.0/include/dbus @@ -32,6 +27,7 @@ dbus_res = versioninfo.o dbus_res_ldflag = -Wl,$(dbus_res) no_undefined = -no-undefined export_symbols = +export_symvols_internal = libdbus_1_la_DEPENDENCIES = $(dbus_res) intllibs = @@ -43,6 +39,7 @@ no_undefined = ## don't export symbols that start with "_" (we use this ## convention for internal symbols) export_symbols = -export-symbols-regex "^[^_].*" +export_symbols_internal = intllibs = @LTLIBINTL@ @@ -191,6 +188,9 @@ DBUS_LIB_SOURCES= \ dbus-watch.c \ dbus-watch.h +## dbus-md5.c \ +## dbus-md5.h \ + ### source code that goes in the installed client library ### AND is generic utility functionality used by the ### daemon or test programs (all symbols in here should @@ -261,23 +261,13 @@ EXTRA_DIST=dbus-arch-deps.h.in ## and is only used for static linking within the dbus package. noinst_LTLIBRARIES=libdbus-internal.la -libdbus_1_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -Ddbus_1_EXPORTS \ - $(NULL) -libdbus_1_la_LIBADD= $(LIBDBUS_LIBS) -libdbus_1_la_LDFLAGS = \ - $(AM_LDFLAGS) \ - $(export_symbols) \ - -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ - -no-undefined \ - $(NULL) - -libdbus_internal_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DDBUS_STATIC_BUILD \ - $(NULL) -libdbus_internal_la_LIBADD=$(LIBDBUS_LIBS) +libdbus_1_la_CPPFLAGS= -Ddbus_1_EXPORTS +libdbus_1_la_LIBADD= $(DBUS_CLIENT_LIBS) +libdbus_1_la_LDFLAGS= $(export_symbols) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -no-undefined @R_DYNAMIC_LDFLAG@ + +libdbus_internal_la_CPPFLAGS = -DDBUS_STATIC_BUILD +libdbus_internal_la_LIBADD=$(DBUS_CLIENT_LIBS) +libdbus_internal_la_LDFLAGS=$(export_symbols_internal) @R_DYNAMIC_LDFLAG@ noinst_PROGRAMS = @@ -289,7 +279,8 @@ endif dbus_test_SOURCES= \ dbus-test-main.c -dbus_test_LDADD = libdbus-internal.la +dbus_test_LDADD=libdbus-internal.la $(DBUS_TEST_LIBS) +dbus_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ ## mop up the gcov files clean-local: diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index f05ddea4..8cb82eb8 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -661,8 +661,6 @@ dbus_bus_register (DBusConnection *connection, _dbus_return_val_if_error_is_set (error, FALSE); retval = FALSE; - message = NULL; - reply = NULL; _DBUS_LOCK (bus_datas); @@ -670,16 +668,18 @@ dbus_bus_register (DBusConnection *connection, if (bd == NULL) { _DBUS_SET_OOM (error); - goto out; + _DBUS_UNLOCK (bus_datas); + return FALSE; } if (bd->unique_name != NULL) { _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n", bd->unique_name); + _DBUS_UNLOCK (bus_datas); + /* Success! */ - retval = TRUE; - goto out; + return TRUE; } message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, @@ -690,11 +690,15 @@ dbus_bus_register (DBusConnection *connection, if (!message) { _DBUS_SET_OOM (error); - goto out; + + _DBUS_UNLOCK (bus_datas); + return FALSE; } reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error); + dbus_message_unref (message); + if (reply == NULL) goto out; else if (dbus_set_error_from_message (error, reply)) @@ -714,17 +718,14 @@ dbus_bus_register (DBusConnection *connection, retval = TRUE; out: - _DBUS_UNLOCK (bus_datas); - - if (message) - dbus_message_unref (message); - if (reply) dbus_message_unref (reply); if (!retval) _DBUS_ASSERT_ERROR_IS_SET (error); + _DBUS_UNLOCK (bus_datas); + return retval; } @@ -1433,17 +1434,11 @@ send_no_return_values (DBusConnection *connection, * If you pass #NULL for the error, this function will not * block; the match thus won't be added until you flush the * connection, and if there's an error adding the match - * you won't find out about it. This is generally acceptable, since the - * possible errors (including a lack of resources in the bus, the connection - * having exceeded its quota of active match rules, or the match rule being - * unparseable) are generally unrecoverable. + * (only possible error is lack of resources in the bus), + * you won't find out about it. * * If you pass non-#NULL for the error this function will - * block until it gets a reply. This may be useful when using match rule keys - * introduced in recent versions of D-Bus, like 'arg0namespace', to allow the - * application to fall back to less efficient match rules supported by older - * versions of the daemon if the running version is not new enough; or when - * using user-supplied rules rather than rules hard-coded at compile time. + * block until it gets a reply. * * Normal API conventions would have the function return * a boolean value indicating whether the error was set, diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h index 4cc27610..cdf3f59d 100644 --- a/dbus/dbus-connection-internal.h +++ b/dbus/dbus-connection-internal.h @@ -54,7 +54,7 @@ void _dbus_connection_queue_received_message_link (DBusConnection DBusList *link); dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection); DBusMessage* _dbus_connection_get_message_to_send (DBusConnection *connection); -void _dbus_connection_message_sent_unlocked (DBusConnection *connection, +void _dbus_connection_message_sent (DBusConnection *connection, DBusMessage *message); dbus_bool_t _dbus_connection_add_watch_unlocked (DBusConnection *connection, DBusWatch *watch); @@ -103,19 +103,6 @@ void _dbus_connection_test_get_locks (DBusConnectio DBusCondVar **dispatch_cond_loc, DBusCondVar **io_path_cond_loc); -/* if DBUS_ENABLE_STATS */ -void _dbus_connection_get_stats (DBusConnection *connection, - dbus_uint32_t *in_messages, - dbus_uint32_t *in_bytes, - dbus_uint32_t *in_fds, - dbus_uint32_t *in_peak_bytes, - dbus_uint32_t *in_peak_fds, - dbus_uint32_t *out_messages, - dbus_uint32_t *out_bytes, - dbus_uint32_t *out_fds, - dbus_uint32_t *out_peak_bytes, - dbus_uint32_t *out_peak_fds); - /* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems * silly for one function */ diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 9128ffc7..8b8310dd 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -38,7 +38,6 @@ #include "dbus-protocol.h" #include "dbus-dataslot.h" #include "dbus-string.h" -#include "dbus-signature.h" #include "dbus-pending-call.h" #include "dbus-object-tree.h" #include "dbus-threads-internal.h" @@ -70,7 +69,11 @@ TOOK_LOCK_CHECK (connection); \ } while (0) -#define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection) +#define CONNECTION_UNLOCK(connection) do { \ + if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \ + RELEASING_LOCK_CHECK (connection); \ + _dbus_mutex_unlock ((connection)->mutex); \ + } while (0) #define SLOTS_LOCK(connection) do { \ _dbus_mutex_lock ((connection)->slot_mutex); \ @@ -252,7 +255,6 @@ struct DBusConnection DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */ DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */ - DBusList *expired_messages; /**< Messages that will be released when we next unlock. */ DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed; * dispatch_acquired will be set by the borrower @@ -287,6 +289,9 @@ struct DBusConnection DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */ + DBusList *link_cache; /**< A cache of linked list links to prevent contention + * for the global linked list mempool lock + */ DBusObjectTree *objects; /**< Object path handlers registered with this connection */ char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */ @@ -384,31 +389,7 @@ _dbus_connection_lock (DBusConnection *connection) void _dbus_connection_unlock (DBusConnection *connection) { - DBusList *expired_messages; - DBusList *iter; - - if (TRACE_LOCKS) - { - _dbus_verbose ("UNLOCK\n"); - } - - /* If we had messages that expired (fell off the incoming or outgoing - * queues) while we were locked, actually release them now */ - expired_messages = connection->expired_messages; - connection->expired_messages = NULL; - - RELEASING_LOCK_CHECK (connection); - _dbus_mutex_unlock (connection->mutex); - - for (iter = _dbus_list_pop_first_link (&expired_messages); - iter != NULL; - iter = _dbus_list_pop_first_link (&expired_messages)) - { - DBusMessage *message = iter->data; - - dbus_message_unref (message); - _dbus_list_free_link (iter); - } + CONNECTION_UNLOCK (connection); } /** @@ -627,8 +608,8 @@ _dbus_connection_get_message_to_send (DBusConnection *connection) * @param message the message that was sent. */ void -_dbus_connection_message_sent_unlocked (DBusConnection *connection, - DBusMessage *message) +_dbus_connection_message_sent (DBusConnection *connection, + DBusMessage *message) { DBusList *link; @@ -643,10 +624,11 @@ _dbus_connection_message_sent_unlocked (DBusConnection *connection, _dbus_assert (link != NULL); _dbus_assert (link->data == message); + /* Save this link in the link cache */ _dbus_list_unlink (&connection->outgoing_messages, link); - _dbus_list_prepend_link (&connection->expired_messages, link); - + _dbus_list_prepend_link (&connection->link_cache, link); + connection->n_outgoing -= 1; _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", @@ -664,11 +646,12 @@ _dbus_connection_message_sent_unlocked (DBusConnection *connection, dbus_message_get_signature (message), connection, connection->n_outgoing); - /* It's OK that in principle we call the notify function, because for the - * outgoing limit, there isn't one */ - _dbus_message_remove_counter (message, connection->outgoing_counter); - - /* The message will actually be unreffed when we unlock */ + /* Save this link in the link cache also */ + _dbus_message_remove_counter (message, connection->outgoing_counter, + &link); + _dbus_list_prepend_link (&connection->link_cache, link); + + dbus_message_unref (message); } /** Function to be called in protected_change_watch() with refcount held */ @@ -1940,13 +1923,31 @@ _dbus_connection_preallocate_send_unlocked (DBusConnection *connection) if (preallocated == NULL) return NULL; - preallocated->queue_link = _dbus_list_alloc_link (NULL); - if (preallocated->queue_link == NULL) - goto failed_0; - - preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); - if (preallocated->counter_link == NULL) - goto failed_1; + if (connection->link_cache != NULL) + { + preallocated->queue_link = + _dbus_list_pop_first_link (&connection->link_cache); + preallocated->queue_link->data = NULL; + } + else + { + preallocated->queue_link = _dbus_list_alloc_link (NULL); + if (preallocated->queue_link == NULL) + goto failed_0; + } + + if (connection->link_cache != NULL) + { + preallocated->counter_link = + _dbus_list_pop_first_link (&connection->link_cache); + preallocated->counter_link->data = connection->outgoing_counter; + } + else + { + preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); + if (preallocated->counter_link == NULL) + goto failed_1; + } _dbus_counter_ref (preallocated->counter_link->data); @@ -1975,8 +1976,6 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con _dbus_list_prepend_link (&connection->outgoing_messages, preallocated->queue_link); - /* It's OK that we'll never call the notify function, because for the - * outgoing limit, there isn't one */ _dbus_message_add_counter_link (message, preallocated->counter_link); @@ -2641,7 +2640,9 @@ free_outgoing_message (void *element, DBusMessage *message = element; DBusConnection *connection = data; - _dbus_message_remove_counter (message, connection->outgoing_counter); + _dbus_message_remove_counter (message, + connection->outgoing_counter, + NULL); dbus_message_unref (message); } @@ -2723,6 +2724,8 @@ _dbus_connection_last_unref (DBusConnection *connection) _dbus_list_free_link (connection->disconnect_message_link); } + _dbus_list_clear (&connection->link_cache); + _dbus_condvar_free_at_location (&connection->dispatch_cond); _dbus_condvar_free_at_location (&connection->io_path_cond); @@ -3046,7 +3049,7 @@ dbus_connection_can_send_type(DBusConnection *connection, { _dbus_return_val_if_fail (connection != NULL, FALSE); - if (!dbus_type_is_valid (type)) + if (!_dbus_type_is_valid(type)) return FALSE; if (type != DBUS_TYPE_UNIX_FD) @@ -3274,7 +3277,6 @@ reply_handler_timeout (void *data) DBusPendingCall *pending = data; connection = _dbus_pending_call_get_connection_and_lock (pending); - _dbus_connection_ref_unlocked (connection); _dbus_pending_call_queue_timeout_error_unlocked (pending, connection); @@ -3287,7 +3289,6 @@ reply_handler_timeout (void *data) /* Unlocks, and calls out to user code */ _dbus_connection_update_dispatch_status_and_unlock (connection, status); - dbus_connection_unref (connection); return TRUE; } @@ -3884,8 +3885,7 @@ dbus_connection_steal_borrowed_message (DBusConnection *connection, pop_message = _dbus_list_pop_first (&connection->incoming_messages); _dbus_assert (message == pop_message); - (void) pop_message; /* unused unless asserting */ - + connection->n_incoming -= 1; _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", @@ -4140,7 +4140,7 @@ notify_disconnected_unlocked (DBusConnection *connection) while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) { - _dbus_connection_message_sent_unlocked (connection, link->data); + _dbus_connection_message_sent (connection, link->data); } } } @@ -4325,48 +4325,44 @@ static DBusHandlerResult _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, DBusMessage *message) { - dbus_bool_t sent = FALSE; - DBusMessage *ret = NULL; - DBusList *expire_link; - if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL) { /* This means we're letting the bus route this message */ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - - if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER)) - { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - /* Preallocate a linked-list link, so that if we need to dispose of a - * message, we can attach it to the expired list */ - expire_link = _dbus_list_alloc_link (NULL); - - if (!expire_link) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - if (dbus_message_is_method_call (message, - DBUS_INTERFACE_PEER, - "Ping")) + else if (dbus_message_is_method_call (message, + DBUS_INTERFACE_PEER, + "Ping")) { + DBusMessage *ret; + dbus_bool_t sent; + ret = dbus_message_new_method_return (message); if (ret == NULL) - goto out; - + return DBUS_HANDLER_RESULT_NEED_MEMORY; + sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); + + dbus_message_unref (ret); + + if (!sent) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return DBUS_HANDLER_RESULT_HANDLED; } else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PEER, "GetMachineId")) { + DBusMessage *ret; + dbus_bool_t sent; DBusString uuid; ret = dbus_message_new_method_return (message); if (ret == NULL) - goto out; + return DBUS_HANDLER_RESULT_NEED_MEMORY; + sent = FALSE; _dbus_string_init (&uuid); if (_dbus_get_local_machine_uuid_encoded (&uuid)) { @@ -4379,38 +4375,43 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, } } _dbus_string_free (&uuid); + + dbus_message_unref (ret); + + if (!sent) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return DBUS_HANDLER_RESULT_HANDLED; } - else + else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER)) { /* We need to bounce anything else with this interface, otherwise apps * could start extending the interface and when we added extensions * here to DBusConnection we'd break those apps. */ + + DBusMessage *ret; + dbus_bool_t sent; + ret = dbus_message_new_error (message, DBUS_ERROR_UNKNOWN_METHOD, "Unknown method invoked on org.freedesktop.DBus.Peer interface"); if (ret == NULL) - goto out; - + return DBUS_HANDLER_RESULT_NEED_MEMORY; + sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); - } - -out: - if (ret == NULL) - { - _dbus_list_free_link (expire_link); + + dbus_message_unref (ret); + + if (!sent) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return DBUS_HANDLER_RESULT_HANDLED; } else { - /* It'll be safe to unref the reply when we unlock */ - expire_link->data = ret; - _dbus_list_prepend_link (&connection->expired_messages, expire_link); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - - if (!sent) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return DBUS_HANDLER_RESULT_HANDLED; } /** @@ -4480,7 +4481,6 @@ dbus_connection_dispatch (DBusConnection *connection) DBusPendingCall *pending; dbus_int32_t reply_serial; DBusDispatchStatus status; - dbus_bool_t found_object; _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); @@ -4642,8 +4642,7 @@ dbus_connection_dispatch (DBusConnection *connection) HAVE_LOCK_CHECK (connection); result = _dbus_object_tree_dispatch_and_unlock (connection->objects, - message, - &found_object); + message); CONNECTION_LOCK (connection); @@ -4658,11 +4657,10 @@ dbus_connection_dispatch (DBusConnection *connection) DBusMessage *reply; DBusString str; DBusPreallocatedSend *preallocated; - DBusList *expire_link; _dbus_verbose (" sending error %s\n", DBUS_ERROR_UNKNOWN_METHOD); - + if (!_dbus_string_init (&str)) { result = DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -4683,7 +4681,7 @@ dbus_connection_dispatch (DBusConnection *connection) } reply = dbus_message_new_error (message, - found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT, + DBUS_ERROR_UNKNOWN_METHOD, _dbus_string_get_const_data (&str)); _dbus_string_free (&str); @@ -4693,24 +4691,11 @@ dbus_connection_dispatch (DBusConnection *connection) _dbus_verbose ("no memory for error reply in dispatch\n"); goto out; } - - expire_link = _dbus_list_alloc_link (reply); - - if (expire_link == NULL) - { - dbus_message_unref (reply); - result = DBUS_HANDLER_RESULT_NEED_MEMORY; - _dbus_verbose ("no memory for error send in dispatch\n"); - goto out; - } - + preallocated = _dbus_connection_preallocate_send_unlocked (connection); if (preallocated == NULL) { - _dbus_list_free_link (expire_link); - /* It's OK that this is finalized, because it hasn't been seen by - * anything that could attach user callbacks */ dbus_message_unref (reply); result = DBUS_HANDLER_RESULT_NEED_MEMORY; _dbus_verbose ("no memory for error send in dispatch\n"); @@ -4719,9 +4704,9 @@ dbus_connection_dispatch (DBusConnection *connection) _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, reply, NULL); - /* reply will be freed when we release the lock */ - _dbus_list_prepend_link (&connection->expired_messages, expire_link); + dbus_message_unref (reply); + result = DBUS_HANDLER_RESULT_HANDLED; } @@ -4747,35 +4732,20 @@ dbus_connection_dispatch (DBusConnection *connection) */ _dbus_connection_putback_message_link_unlocked (connection, message_link); - /* now we don't want to free them */ - message_link = NULL; - message = NULL; } else { _dbus_verbose (" ... done dispatching\n"); + + _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); HAVE_LOCK_CHECK (connection); - if (message != NULL) - { - /* We don't want this message to count in maximum message limits when - * computing the dispatch status, below. We have to drop the lock - * temporarily, because finalizing a message can trigger callbacks. - * - * We have a reference to the connection, and we don't use any cached - * pointers to the connection's internals below this point, so it should - * be safe to drop the lock and take it back. */ - CONNECTION_UNLOCK (connection); - dbus_message_unref (message); - CONNECTION_LOCK (connection); - } - - if (message_link != NULL) - _dbus_list_free_link (message_link); - _dbus_verbose ("before final status update\n"); status = _dbus_connection_get_dispatch_status_unlocked (connection); @@ -5539,13 +5509,10 @@ dbus_connection_remove_filter (DBusConnection *connection, } /** - * Registers a handler for a given path or subsection in the object - * hierarchy. The given vtable handles messages sent to exactly the - * given path or also for paths bellow that, depending on fallback - * parameter. + * 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 fallback whether to handle messages also for "subdirectory" * @param path a '/' delimited string of path elements * @param vtable the virtual table * @param user_data data to pass to functions in the vtable @@ -5553,16 +5520,20 @@ dbus_connection_remove_filter (DBusConnection *connection, * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported */ -static dbus_bool_t -_dbus_connection_register_object_path (DBusConnection *connection, - dbus_bool_t fallback, - const char *path, - const DBusObjectPathVTable *vtable, - void *user_data, - DBusError *error) +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; @@ -5570,7 +5541,7 @@ _dbus_connection_register_object_path (DBusConnection *connection, CONNECTION_LOCK (connection); retval = _dbus_object_tree_register (connection->objects, - fallback, + FALSE, (const char **) decomposed_path, vtable, user_data, error); @@ -5585,33 +5556,6 @@ _dbus_connection_register_object_path (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_OBJECT_PATH_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) -{ - _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); - - return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error); -} - -/** - * 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. @@ -5629,6 +5573,7 @@ dbus_connection_register_object_path (DBusConnection *connection, const DBusObjectPathVTable *vtable, void *user_data) { + char **decomposed_path; dbus_bool_t retval; DBusError error = DBUS_ERROR_INIT; @@ -5637,7 +5582,19 @@ dbus_connection_register_object_path (DBusConnection *connection, _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); - retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error); + 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); if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { @@ -5670,12 +5627,29 @@ dbus_connection_try_register_fallback (DBusConnection *connection, 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); - return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error); + 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; } /** @@ -5701,6 +5675,7 @@ dbus_connection_register_fallback (DBusConnection *connection, const DBusObjectPathVTable *vtable, void *user_data) { + char **decomposed_path; dbus_bool_t retval; DBusError error = DBUS_ERROR_INIT; @@ -5709,7 +5684,19 @@ dbus_connection_register_fallback (DBusConnection *connection, _dbus_return_val_if_fail (path[0] == '/', FALSE); _dbus_return_val_if_fail (vtable != NULL, FALSE); - retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error); + 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); if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) { @@ -6169,47 +6156,6 @@ dbus_connection_get_outgoing_size (DBusConnection *connection) return res; } -#ifdef DBUS_ENABLE_STATS -void -_dbus_connection_get_stats (DBusConnection *connection, - dbus_uint32_t *in_messages, - dbus_uint32_t *in_bytes, - dbus_uint32_t *in_fds, - dbus_uint32_t *in_peak_bytes, - dbus_uint32_t *in_peak_fds, - dbus_uint32_t *out_messages, - dbus_uint32_t *out_bytes, - dbus_uint32_t *out_fds, - dbus_uint32_t *out_peak_bytes, - dbus_uint32_t *out_peak_fds) -{ - CONNECTION_LOCK (connection); - - if (in_messages != NULL) - *in_messages = connection->n_incoming; - - _dbus_transport_get_stats (connection->transport, - in_bytes, in_fds, in_peak_bytes, in_peak_fds); - - if (out_messages != NULL) - *out_messages = connection->n_outgoing; - - if (out_bytes != NULL) - *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter); - - if (out_fds != NULL) - *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter); - - if (out_peak_bytes != NULL) - *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter); - - if (out_peak_fds != NULL) - *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter); - - CONNECTION_UNLOCK (connection); -} -#endif /* DBUS_ENABLE_STATS */ - /** * Gets the approximate number of uni fds of all messages in the * outgoing message queue. diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c index fcea0790..95a491f9 100644 --- a/dbus/dbus-internals.c +++ b/dbus/dbus-internals.c @@ -347,6 +347,7 @@ _dbus_verbose_init (void) static char *_dbus_file_path_extract_elements_from_tail(const char *file,int level) { static int prefix = -1; + char *p; if (prefix == -1) { diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 4e383bca..06e6c16b 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -108,20 +108,20 @@ dbus_bool_t _dbus_is_verbose_real (void); # define _dbus_is_verbose _dbus_is_verbose_real #else # ifdef HAVE_ISO_VARARGS -# define _dbus_verbose(...) do { } while (0) +# define _dbus_verbose(...) # elif defined (HAVE_GNUC_VARARGS) -# define _dbus_verbose(format...) do { } while (0) +# define _dbus_verbose(format...) # else static void _dbus_verbose(const char * x,...) {;} # endif -# define _dbus_verbose_reset() do { } while (0) +# define _dbus_verbose_reset() # define _dbus_is_verbose() FALSE #endif /* !DBUS_ENABLE_VERBOSE_MODE */ const char* _dbus_strerror (int error_number); #ifdef DBUS_DISABLE_ASSERT -#define _dbus_assert(condition) do { } while (0) +#define _dbus_assert(condition) #else void _dbus_real_assert (dbus_bool_t condition, const char *condition_text, @@ -133,7 +133,7 @@ void _dbus_real_assert (dbus_bool_t condition, #endif /* !DBUS_DISABLE_ASSERT */ #ifdef DBUS_DISABLE_ASSERT -#define _dbus_assert_not_reached(explanation) do { } while (0) +#define _dbus_assert_not_reached(explanation) #else void _dbus_real_assert_not_reached (const char *explanation, const char *file, @@ -181,8 +181,8 @@ extern const char *_dbus_return_if_fail_warning_format; /* this is an assert and not an error, but in the typical --disable-checks case (you're trying * to really minimize code size), disabling these assertions makes sense. */ -#define _DBUS_ASSERT_ERROR_IS_SET(error) do { } while (0) -#define _DBUS_ASSERT_ERROR_IS_CLEAR(error) do { } while (0) +#define _DBUS_ASSERT_ERROR_IS_SET(error) +#define _DBUS_ASSERT_ERROR_IS_CLEAR(error) #else #define _DBUS_ASSERT_ERROR_IS_SET(error) _dbus_assert ((error) == NULL || dbus_error_is_set ((error))) #define _DBUS_ASSERT_ERROR_IS_CLEAR(error) _dbus_assert ((error) == NULL || !dbus_error_is_set ((error))) diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c index d4d74f69..6a16ed60 100644 --- a/dbus/dbus-list.c +++ b/dbus/dbus-list.c @@ -146,18 +146,6 @@ link_after (DBusList **list, } } -#ifdef DBUS_ENABLE_STATS -void -_dbus_list_get_stats (dbus_uint32_t *in_use_p, - dbus_uint32_t *in_free_list_p, - dbus_uint32_t *allocated_p) -{ - _DBUS_LOCK (list); - _dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p); - _DBUS_UNLOCK (list); -} -#endif - /** @} */ /** diff --git a/dbus/dbus-list.h b/dbus/dbus-list.h index 2e346d5e..663ad257 100644 --- a/dbus/dbus-list.h +++ b/dbus/dbus-list.h @@ -84,6 +84,8 @@ void _dbus_list_prepend_link (DBusList **list, dbus_bool_t _dbus_list_length_is_one (DBusList **list); + + void _dbus_list_foreach (DBusList **list, DBusForeachFunction function, void *data); @@ -91,11 +93,6 @@ void _dbus_list_foreach (DBusList **list, #define _dbus_list_get_next_link(list, link) ((link)->next == *(list) ? NULL : (link)->next) #define _dbus_list_get_prev_link(list, link) ((link) == *(list) ? NULL : (link)->prev) -/* if DBUS_ENABLE_STATS */ -void _dbus_list_get_stats (dbus_uint32_t *in_use_p, - dbus_uint32_t *in_free_list_p, - dbus_uint32_t *allocated_p); - DBUS_END_DECLS #endif /* DBUS_LIST_H */ diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c index 1a046a1f..43159a70 100644 --- a/dbus/dbus-mainloop.c +++ b/dbus/dbus-mainloop.c @@ -26,7 +26,6 @@ #ifndef DOXYGEN_SHOULD_SKIP_THIS -#include <dbus/dbus-hash.h> #include <dbus/dbus-list.h> #include <dbus/dbus-sysdeps.h> #include <dbus/dbus-watch.h> @@ -57,9 +56,7 @@ watch_flags_to_string (int flags) struct DBusLoop { int refcount; - /** fd => dbus_malloc'd DBusList ** of references to DBusWatch */ - DBusHashTable *watches; - DBusList *timeouts; + DBusList *callbacks; int callback_list_serial; int watch_count; int timeout_count; @@ -67,47 +64,69 @@ struct DBusLoop DBusList *need_dispatch; }; -static short -watch_flags_to_poll_events (unsigned int flags) +typedef enum { - short events = 0; + CALLBACK_WATCH, + CALLBACK_TIMEOUT +} CallbackType; - if (flags & DBUS_WATCH_READABLE) - events |= _DBUS_POLLIN; - if (flags & DBUS_WATCH_WRITABLE) - events |= _DBUS_POLLOUT; - - return events; -} +typedef struct +{ + int refcount; + CallbackType type; + void *data; + DBusFreeFunction free_data_func; +} Callback; -static unsigned int -watch_flags_from_poll_revents (short revents) +typedef struct { - unsigned int condition = 0; - - if (revents & _DBUS_POLLIN) - condition |= DBUS_WATCH_READABLE; - if (revents & _DBUS_POLLOUT) - condition |= DBUS_WATCH_WRITABLE; - if (revents & _DBUS_POLLHUP) - condition |= DBUS_WATCH_HANGUP; - if (revents & _DBUS_POLLERR) - condition |= DBUS_WATCH_ERROR; - - return condition; -} + Callback callback; + DBusWatchFunction function; + DBusWatch *watch; + /* last watch handle failed due to OOM */ + unsigned int last_iteration_oom : 1; +} WatchCallback; typedef struct { + Callback callback; DBusTimeout *timeout; + DBusTimeoutFunction function; unsigned long last_tv_sec; unsigned long last_tv_usec; } TimeoutCallback; +#define WATCH_CALLBACK(callback) ((WatchCallback*)callback) #define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback) +static WatchCallback* +watch_callback_new (DBusWatch *watch, + DBusWatchFunction function, + void *data, + DBusFreeFunction free_data_func) +{ + WatchCallback *cb; + + cb = dbus_new (WatchCallback, 1); + if (cb == NULL) + return NULL; + + cb->watch = watch; + cb->function = function; + cb->last_iteration_oom = FALSE; + cb->callback.refcount = 1; + cb->callback.type = CALLBACK_WATCH; + cb->callback.data = data; + cb->callback.free_data_func = free_data_func; + + return cb; +} + static TimeoutCallback* -timeout_callback_new (DBusTimeout *timeout) +timeout_callback_new (DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data, + DBusFreeFunction free_data_func) { TimeoutCallback *cb; @@ -116,37 +135,84 @@ timeout_callback_new (DBusTimeout *timeout) return NULL; cb->timeout = timeout; + cb->function = function; _dbus_get_current_time (&cb->last_tv_sec, &cb->last_tv_usec); + cb->callback.refcount = 1; + cb->callback.type = CALLBACK_TIMEOUT; + cb->callback.data = data; + cb->callback.free_data_func = free_data_func; + return cb; } -static void -timeout_callback_free (TimeoutCallback *cb) +static Callback * +callback_ref (Callback *cb) { - dbus_free (cb); + _dbus_assert (cb->refcount > 0); + + cb->refcount += 1; + + return cb; } static void -free_watch_table_entry (void *data) +callback_unref (Callback *cb) { - DBusList **watches = data; - DBusWatch *watch; + _dbus_assert (cb->refcount > 0); - /* DBusHashTable sometimes calls free_function(NULL) even if you never - * have NULL as a value */ - if (watches == NULL) - return; + cb->refcount -= 1; - for (watch = _dbus_list_pop_first (watches); - watch != NULL; - watch = _dbus_list_pop_first (watches)) + if (cb->refcount == 0) { - _dbus_watch_unref (watch); + if (cb->free_data_func) + (* cb->free_data_func) (cb->data); + + dbus_free (cb); } +} + +static dbus_bool_t +add_callback (DBusLoop *loop, + Callback *cb) +{ + if (!_dbus_list_append (&loop->callbacks, cb)) + return FALSE; - _dbus_assert (*watches == NULL); - dbus_free (watches); + loop->callback_list_serial += 1; + + switch (cb->type) + { + case CALLBACK_WATCH: + loop->watch_count += 1; + break; + case CALLBACK_TIMEOUT: + loop->timeout_count += 1; + break; + } + + return TRUE; +} + +static void +remove_callback (DBusLoop *loop, + DBusList *link) +{ + Callback *cb = link->data; + + switch (cb->type) + { + case CALLBACK_WATCH: + loop->watch_count -= 1; + break; + case CALLBACK_TIMEOUT: + loop->timeout_count -= 1; + break; + } + + callback_unref (cb); + _dbus_list_remove_link (&loop->callbacks, link); + loop->callback_list_serial += 1; } DBusLoop* @@ -158,17 +224,8 @@ _dbus_loop_new (void) if (loop == NULL) return NULL; - loop->watches = _dbus_hash_table_new (DBUS_HASH_INT, NULL, - free_watch_table_entry); - - if (loop->watches == NULL) - { - dbus_free (loop); - return NULL; - } - loop->refcount = 1; - + return loop; } @@ -198,168 +255,82 @@ _dbus_loop_unref (DBusLoop *loop) dbus_connection_unref (connection); } - - _dbus_hash_table_unref (loop->watches); + dbus_free (loop); } } -static DBusList ** -ensure_watch_table_entry (DBusLoop *loop, - int fd) -{ - DBusList **watches; - - watches = _dbus_hash_table_lookup_int (loop->watches, fd); - - if (watches == NULL) - { - watches = dbus_new0 (DBusList *, 1); - - if (watches == NULL) - return watches; - - if (!_dbus_hash_table_insert_int (loop->watches, fd, watches)) - { - dbus_free (watches); - watches = NULL; - } - } - - return watches; -} - -static void -cull_watches_for_invalid_fd (DBusLoop *loop, - int fd) -{ - DBusList *link; - DBusList **watches; - - _dbus_warn ("invalid request, socket fd %d not open\n", fd); - watches = _dbus_hash_table_lookup_int (loop->watches, fd); - - if (watches != NULL) - { - for (link = _dbus_list_get_first_link (watches); - link != NULL; - link = _dbus_list_get_next_link (watches, link)) - _dbus_watch_invalidate (link->data); - } - - _dbus_hash_table_remove_int (loop->watches, fd); -} - -static void -gc_watch_table_entry (DBusLoop *loop, - DBusList **watches, - int fd) -{ - /* If watches is already NULL we have nothing to do */ - if (watches == NULL) - return; - - /* We can't GC hash table entries if they're non-empty lists */ - if (*watches != NULL) - return; - - _dbus_hash_table_remove_int (loop->watches, fd); -} - dbus_bool_t -_dbus_loop_add_watch (DBusLoop *loop, - DBusWatch *watch) +_dbus_loop_add_watch (DBusLoop *loop, + DBusWatch *watch, + DBusWatchFunction function, + void *data, + DBusFreeFunction free_data_func) { - int fd; - DBusList **watches; + WatchCallback *wcb; - fd = dbus_watch_get_socket (watch); - _dbus_assert (fd != -1); - - watches = ensure_watch_table_entry (loop, fd); - - if (watches == NULL) + wcb = watch_callback_new (watch, function, data, free_data_func); + if (wcb == NULL) return FALSE; - if (_dbus_list_append (watches, _dbus_watch_ref (watch))) + if (!add_callback (loop, (Callback*) wcb)) { - loop->callback_list_serial += 1; - loop->watch_count += 1; + wcb->callback.free_data_func = NULL; /* don't want to have this side effect */ + callback_unref ((Callback*) wcb); + return FALSE; } - else - { - _dbus_watch_unref (watch); - gc_watch_table_entry (loop, watches, fd); - - return FALSE; - } - + return TRUE; } void -_dbus_loop_remove_watch (DBusLoop *loop, - DBusWatch *watch) +_dbus_loop_remove_watch (DBusLoop *loop, + DBusWatch *watch, + DBusWatchFunction function, + void *data) { - DBusList **watches; DBusList *link; - int fd; - - /* This relies on people removing watches before they invalidate them, - * which has been safe since fd.o #33336 was fixed. Assert about it - * so we don't regress. */ - fd = dbus_watch_get_socket (watch); - _dbus_assert (fd != -1); - - watches = _dbus_hash_table_lookup_int (loop->watches, fd); - - if (watches != NULL) + + link = _dbus_list_get_first_link (&loop->callbacks); + while (link != NULL) { - link = _dbus_list_get_first_link (watches); - while (link != NULL) - { - DBusList *next = _dbus_list_get_next_link (watches, link); - DBusWatch *this = link->data; - - if (this == watch) - { - _dbus_list_remove_link (watches, link); - loop->callback_list_serial += 1; - loop->watch_count -= 1; - _dbus_watch_unref (this); - - /* if that was the last watch for that fd, drop the hash table - * entry too */ - gc_watch_table_entry (loop, watches, fd); - - return; - } + DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link); + Callback *this = link->data; - link = next; - } - } + if (this->type == CALLBACK_WATCH && + WATCH_CALLBACK (this)->watch == watch && + this->data == data && + WATCH_CALLBACK (this)->function == function) + { + remove_callback (loop, link); + + return; + } + + link = next; + } - _dbus_warn ("could not find watch %p to remove\n", watch); + _dbus_warn ("could not find watch %p function %p data %p to remove\n", + watch, (void *)function, data); } dbus_bool_t -_dbus_loop_add_timeout (DBusLoop *loop, - DBusTimeout *timeout) +_dbus_loop_add_timeout (DBusLoop *loop, + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data, + DBusFreeFunction free_data_func) { TimeoutCallback *tcb; - tcb = timeout_callback_new (timeout); + tcb = timeout_callback_new (timeout, function, data, free_data_func); if (tcb == NULL) return FALSE; - if (_dbus_list_append (&loop->timeouts, tcb)) + if (!add_callback (loop, (Callback*) tcb)) { - loop->callback_list_serial += 1; - loop->timeout_count += 1; - } - else - { - timeout_callback_free (tcb); + tcb->callback.free_data_func = NULL; /* don't want to have this side effect */ + callback_unref ((Callback*) tcb); return FALSE; } @@ -367,31 +338,34 @@ _dbus_loop_add_timeout (DBusLoop *loop, } void -_dbus_loop_remove_timeout (DBusLoop *loop, - DBusTimeout *timeout) +_dbus_loop_remove_timeout (DBusLoop *loop, + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data) { DBusList *link; - link = _dbus_list_get_first_link (&loop->timeouts); + link = _dbus_list_get_first_link (&loop->callbacks); while (link != NULL) { - DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link); - TimeoutCallback *this = link->data; + DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link); + Callback *this = link->data; - if (this->timeout == timeout) + if (this->type == CALLBACK_TIMEOUT && + TIMEOUT_CALLBACK (this)->timeout == timeout && + this->data == data && + TIMEOUT_CALLBACK (this)->function == function) { - _dbus_list_remove_link (&loop->timeouts, link); - loop->callback_list_serial += 1; - loop->timeout_count -= 1; - timeout_callback_free (this); - + remove_callback (loop, link); + return; } link = next; } - _dbus_warn ("could not find timeout %p to remove\n", timeout); + _dbus_warn ("could not find timeout %p function %p data %p to remove\n", + timeout, (void *)function, data); } /* Convolutions from GLib, there really must be a better way @@ -551,6 +525,8 @@ _dbus_loop_iterate (DBusLoop *loop, DBusPollFD *fds; DBusPollFD stack_fds[N_STACK_DESCRIPTORS]; int n_fds; + WatchCallback **watches_for_fds; + WatchCallback *stack_watches_for_fds[N_STACK_DESCRIPTORS]; int i; DBusList *link; int n_ready; @@ -558,11 +534,11 @@ _dbus_loop_iterate (DBusLoop *loop, long timeout; dbus_bool_t oom_watch_pending; int orig_depth; - DBusHashIter hash_iter; - + retval = FALSE; fds = NULL; + watches_for_fds = NULL; n_fds = 0; oom_watch_pending = FALSE; orig_depth = loop->depth; @@ -571,9 +547,8 @@ _dbus_loop_iterate (DBusLoop *loop, _dbus_verbose ("Iteration block=%d depth=%d timeout_count=%d watch_count=%d\n", block, loop->depth, loop->timeout_count, loop->watch_count); #endif - - if (_dbus_hash_table_get_n_entries (loop->watches) == 0 && - loop->timeouts == NULL) + + if (loop->callbacks == NULL) goto next_iteration; if (loop->watch_count > N_STACK_DESCRIPTORS) @@ -585,40 +560,41 @@ _dbus_loop_iterate (DBusLoop *loop, _dbus_wait_for_memory (); fds = dbus_new0 (DBusPollFD, loop->watch_count); } + + watches_for_fds = dbus_new (WatchCallback*, loop->watch_count); + while (watches_for_fds == NULL) + { + _dbus_wait_for_memory (); + watches_for_fds = dbus_new (WatchCallback*, loop->watch_count); + } } else { fds = stack_fds; + watches_for_fds = stack_watches_for_fds; } /* fill our array of fds and watches */ n_fds = 0; - _dbus_hash_iter_init (loop->watches, &hash_iter); - - while (_dbus_hash_iter_next (&hash_iter)) + link = _dbus_list_get_first_link (&loop->callbacks); + while (link != NULL) { - DBusList **watches; - unsigned int flags; - int fd; - - fd = _dbus_hash_iter_get_int_key (&hash_iter); - watches = _dbus_hash_iter_get_value (&hash_iter); - flags = 0; - - for (link = _dbus_list_get_first_link (watches); - link != NULL; - link = _dbus_list_get_next_link (watches, link)) + DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link); + Callback *cb = link->data; + if (cb->type == CALLBACK_WATCH) { - DBusWatch *watch = link->data; + unsigned int flags; + WatchCallback *wcb = WATCH_CALLBACK (cb); + int fd = dbus_watch_get_socket (wcb->watch); - if (_dbus_watch_get_oom_last_time (watch)) + if (wcb->last_iteration_oom) { /* we skip this one this time, but reenable it next time, * and have a timeout on this iteration */ - _dbus_watch_set_oom_last_time (watch, FALSE); + wcb->last_iteration_oom = FALSE; oom_watch_pending = TRUE; - + retval = TRUE; /* return TRUE here to keep the loop going, * since we don't know the watch is inactive */ @@ -628,35 +604,49 @@ _dbus_loop_iterate (DBusLoop *loop, fd); #endif } - else if (dbus_watch_get_enabled (watch)) + else if (_DBUS_UNLIKELY (fd == -1)) { - flags |= dbus_watch_get_flags (watch); + _dbus_warn ("watch %p was invalidated but not removed; " + "removing it now\n", wcb->watch); + _dbus_loop_remove_watch (loop, wcb->watch, wcb->function, + ((Callback *)wcb)->data); } - } + else if (dbus_watch_get_enabled (wcb->watch)) + { + watches_for_fds[n_fds] = wcb; - if (flags != 0) - { - fds[n_fds].fd = fd; - fds[n_fds].revents = 0; - fds[n_fds].events = watch_flags_to_poll_events (flags); + callback_ref (cb); + + flags = dbus_watch_get_flags (wcb->watch); + + fds[n_fds].fd = fd; + fds[n_fds].revents = 0; + fds[n_fds].events = 0; + if (flags & DBUS_WATCH_READABLE) + fds[n_fds].events |= _DBUS_POLLIN; + if (flags & DBUS_WATCH_WRITABLE) + fds[n_fds].events |= _DBUS_POLLOUT; #if MAINLOOP_SPEW - _dbus_verbose (" polling watch on fd %d %s\n", - loop->fds[loop->n_fds].fd, watch_flags_to_string (flags)); + _dbus_verbose (" polling watch on fd %d %s\n", + fd, watch_flags_to_string (flags)); #endif - n_fds += 1; - } - else - { + n_fds += 1; + } + else + { #if MAINLOOP_SPEW - _dbus_verbose (" skipping disabled watch on fd %d %s\n", - fd, - watch_flags_to_string (dbus_watch_get_flags (watch))); + _dbus_verbose (" skipping disabled watch on fd %d %s\n", + fd, + watch_flags_to_string (dbus_watch_get_flags (wcb->watch))); #endif + } } + + link = next; } - + timeout = -1; if (loop->timeout_count > 0) { @@ -664,15 +654,17 @@ _dbus_loop_iterate (DBusLoop *loop, unsigned long tv_usec; _dbus_get_current_time (&tv_sec, &tv_usec); - - link = _dbus_list_get_first_link (&loop->timeouts); + + link = _dbus_list_get_first_link (&loop->callbacks); while (link != NULL) { - DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link); - TimeoutCallback *tcb = link->data; + DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link); + Callback *cb = link->data; - if (dbus_timeout_get_enabled (tcb->timeout)) + if (cb->type == CALLBACK_TIMEOUT && + dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { + TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); int msecs_remaining; check_timeout (tv_sec, tv_usec, tcb, &msecs_remaining); @@ -693,7 +685,7 @@ _dbus_loop_iterate (DBusLoop *loop, break; /* it's not going to get shorter... */ } #if MAINLOOP_SPEW - else + else if (cb->type == CALLBACK_TIMEOUT) { _dbus_verbose (" skipping disabled timeout\n"); } @@ -734,20 +726,22 @@ _dbus_loop_iterate (DBusLoop *loop, _dbus_get_current_time (&tv_sec, &tv_usec); /* It'd be nice to avoid this O(n) thingy here */ - link = _dbus_list_get_first_link (&loop->timeouts); + link = _dbus_list_get_first_link (&loop->callbacks); while (link != NULL) { - DBusList *next = _dbus_list_get_next_link (&loop->timeouts, link); - TimeoutCallback *tcb = link->data; + DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link); + Callback *cb = link->data; if (initial_serial != loop->callback_list_serial) goto next_iteration; if (loop->depth != orig_depth) goto next_iteration; - - if (dbus_timeout_get_enabled (tcb->timeout)) + + if (cb->type == CALLBACK_TIMEOUT && + dbus_timeout_get_enabled (TIMEOUT_CALLBACK (cb)->timeout)) { + TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); int msecs_remaining; if (check_timeout (tv_sec, tv_usec, @@ -760,11 +754,9 @@ _dbus_loop_iterate (DBusLoop *loop, #if MAINLOOP_SPEW _dbus_verbose (" invoking timeout\n"); #endif - - /* can theoretically return FALSE on OOM, but we just - * let it fire again later - in practice that's what - * every wrapper callback in dbus-daemon used to do */ - dbus_timeout_handle (tcb->timeout); + + (* tcb->function) (tcb->timeout, + cb->data); retval = TRUE; } @@ -776,7 +768,7 @@ _dbus_loop_iterate (DBusLoop *loop, } } #if MAINLOOP_SPEW - else + else if (cb->type == CALLBACK_TIMEOUT) { _dbus_verbose (" skipping invocation of disabled timeout\n"); } @@ -788,12 +780,9 @@ _dbus_loop_iterate (DBusLoop *loop, if (n_ready > 0) { - for (i = 0; i < n_fds; i++) + i = 0; + while (i < n_fds) { - DBusList **watches; - DBusList *next; - unsigned int condition; - /* FIXME I think this "restart if we change the watches" * approach could result in starving watches * toward the end of the list. @@ -804,62 +793,54 @@ _dbus_loop_iterate (DBusLoop *loop, if (loop->depth != orig_depth) goto next_iteration; - if (fds[i].revents == 0) - continue; - - if (_DBUS_UNLIKELY (fds[i].revents & _DBUS_POLLNVAL)) - { - cull_watches_for_invalid_fd (loop, fds[i].fd); - goto next_iteration; - } - - condition = watch_flags_from_poll_revents (fds[i].revents); - - /* condition may still be 0 if we got some - * weird POLLFOO thing like POLLWRBAND - */ - if (condition == 0) - continue; - - watches = _dbus_hash_table_lookup_int (loop->watches, fds[i].fd); - - if (watches == NULL) - continue; - - for (link = _dbus_list_get_first_link (watches); - link != NULL; - link = next) + if (fds[i].revents != 0) { - DBusWatch *watch = link->data; - - next = _dbus_list_get_next_link (watches, link); - - if (dbus_watch_get_enabled (watch)) + WatchCallback *wcb; + unsigned int condition; + + wcb = watches_for_fds[i]; + + condition = 0; + if (fds[i].revents & _DBUS_POLLIN) + condition |= DBUS_WATCH_READABLE; + if (fds[i].revents & _DBUS_POLLOUT) + condition |= DBUS_WATCH_WRITABLE; + if (fds[i].revents & _DBUS_POLLHUP) + condition |= DBUS_WATCH_HANGUP; + if (fds[i].revents & _DBUS_POLLERR) + condition |= DBUS_WATCH_ERROR; + + /* condition may still be 0 if we got some + * weird POLLFOO thing like POLLWRBAND + */ + + if (condition != 0 && + dbus_watch_get_enabled (wcb->watch)) { - dbus_bool_t oom; - - oom = !dbus_watch_handle (watch, condition); - - if (oom) - { - _dbus_watch_set_oom_last_time (watch, TRUE); - } + if (!(* wcb->function) (wcb->watch, + condition, + ((Callback*)wcb)->data)) + wcb->last_iteration_oom = TRUE; #if MAINLOOP_SPEW - _dbus_verbose (" Invoked watch, oom = %d\n", oom); + _dbus_verbose (" Invoked watch, oom = %d\n", + wcb->last_iteration_oom); #endif + retval = TRUE; + } - /* We re-check this every time, in case the callback - * added/removed watches, which might make our position in - * the linked list invalid. See the FIXME above. */ - if (initial_serial != loop->callback_list_serial) - goto next_iteration; - - if (loop->depth != orig_depth) - goto next_iteration; + if (_DBUS_UNLIKELY (fds[i].revents & _DBUS_POLLNVAL)) + { + _dbus_warn ("invalid request, socket fd %d not open\n", + fds[i].fd); + _dbus_watch_invalidate (wcb->watch); + _dbus_loop_remove_watch (loop, wcb->watch, wcb->function, + ((Callback *)wcb)->data); } } + + ++i; } } @@ -870,7 +851,19 @@ _dbus_loop_iterate (DBusLoop *loop, if (fds && fds != stack_fds) dbus_free (fds); - + if (watches_for_fds) + { + i = 0; + while (i < n_fds) + { + callback_unref (&watches_for_fds[i]->callback); + ++i; + } + + if (watches_for_fds != stack_watches_for_fds) + dbus_free (watches_for_fds); + } + if (_dbus_loop_dispatch (loop)) retval = TRUE; diff --git a/dbus/dbus-mainloop.h b/dbus/dbus-mainloop.h index a3417adb..656f8231 100644 --- a/dbus/dbus-mainloop.h +++ b/dbus/dbus-mainloop.h @@ -33,18 +33,30 @@ typedef struct DBusLoop DBusLoop; typedef dbus_bool_t (* DBusWatchFunction) (DBusWatch *watch, unsigned int condition, void *data); +typedef void (* DBusTimeoutFunction) (DBusTimeout *timeout, + void *data); DBusLoop* _dbus_loop_new (void); DBusLoop* _dbus_loop_ref (DBusLoop *loop); void _dbus_loop_unref (DBusLoop *loop); dbus_bool_t _dbus_loop_add_watch (DBusLoop *loop, - DBusWatch *watch); + DBusWatch *watch, + DBusWatchFunction function, + void *data, + DBusFreeFunction free_data_func); void _dbus_loop_remove_watch (DBusLoop *loop, - DBusWatch *watch); + DBusWatch *watch, + DBusWatchFunction function, + void *data); dbus_bool_t _dbus_loop_add_timeout (DBusLoop *loop, - DBusTimeout *timeout); + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data, + DBusFreeFunction free_data_func); void _dbus_loop_remove_timeout (DBusLoop *loop, - DBusTimeout *timeout); + DBusTimeout *timeout, + DBusTimeoutFunction function, + void *data); dbus_bool_t _dbus_loop_queue_dispatch (DBusLoop *loop, DBusConnection *connection); diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c index b63761e9..b1398539 100644 --- a/dbus/dbus-marshal-basic.c +++ b/dbus/dbus-marshal-basic.c @@ -1267,6 +1267,44 @@ _dbus_type_get_alignment (int typecode) } } + +/** + * Return #TRUE if the typecode is a valid typecode. + * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and + * random unknown bytes aren't either. This function is safe with + * untrusted data. + * + * @returns #TRUE if valid + */ +dbus_bool_t +_dbus_type_is_valid (int typecode) +{ + switch (typecode) + { + case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + case DBUS_TYPE_DOUBLE: + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + case DBUS_TYPE_SIGNATURE: + case DBUS_TYPE_ARRAY: + case DBUS_TYPE_STRUCT: + case DBUS_TYPE_DICT_ENTRY: + case DBUS_TYPE_VARIANT: + case DBUS_TYPE_UNIX_FD: + return TRUE; + + default: + return FALSE; + } +} + /** * Returns a string describing the given type. * diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h index 3c448dff..0c27fc9e 100644 --- a/dbus/dbus-marshal-basic.h +++ b/dbus/dbus-marshal-basic.h @@ -254,6 +254,7 @@ dbus_uint32_t _dbus_marshal_read_uint32 (const DBusString *str, int pos, int byte_order, int *new_pos); +dbus_bool_t _dbus_type_is_valid (int typecode); int _dbus_type_get_alignment (int typecode); dbus_bool_t _dbus_type_is_fixed (int typecode); int _dbus_type_get_alignment (int typecode); diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c index 4a763fba..a6c9b80d 100644 --- a/dbus/dbus-marshal-header.c +++ b/dbus/dbus-marshal-header.c @@ -165,20 +165,6 @@ _dbus_header_cache_one (DBusHeader *header, } /** - * Returns the header's byte order. - * - * @param header the header - * @returns the byte order - */ -char -_dbus_header_get_byte_order (const DBusHeader *header) -{ - _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET); - - return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET); -} - -/** * Revalidates the fields cache * * @param header the header @@ -198,7 +184,7 @@ _dbus_header_cache_revalidate (DBusHeader *header) } _dbus_type_reader_init (&reader, - _dbus_header_get_byte_order (header), + header->byte_order, &_dbus_header_signature_str, FIELDS_ARRAY_SIGNATURE_OFFSET, &header->data, @@ -412,7 +398,7 @@ _dbus_header_set_serial (DBusHeader *header, _dbus_marshal_set_uint32 (&header->data, SERIAL_OFFSET, serial, - _dbus_header_get_byte_order (header)); + header->byte_order); } /** @@ -426,7 +412,7 @@ _dbus_header_get_serial (DBusHeader *header) { return _dbus_marshal_read_uint32 (&header->data, SERIAL_OFFSET, - _dbus_header_get_byte_order (header), + header->byte_order, NULL); } @@ -436,12 +422,15 @@ _dbus_header_get_serial (DBusHeader *header) * _dbus_header_create(). * * @param header header to re-initialize + * @param byte_order byte order of the header */ void -_dbus_header_reinit (DBusHeader *header) +_dbus_header_reinit (DBusHeader *header, + int byte_order) { _dbus_string_set_length (&header->data, 0); + header->byte_order = byte_order; header->padding = 0; _dbus_header_cache_invalidate_all (header); @@ -456,12 +445,13 @@ _dbus_header_reinit (DBusHeader *header) * @returns #FALSE if not enough memory */ dbus_bool_t -_dbus_header_init (DBusHeader *header) +_dbus_header_init (DBusHeader *header, + int byte_order) { if (!_dbus_string_init_preallocated (&header->data, 32)) return FALSE; - _dbus_header_reinit (header); + _dbus_header_reinit (header, byte_order); return TRUE; } @@ -524,7 +514,6 @@ _dbus_header_copy (const DBusHeader *header, */ dbus_bool_t _dbus_header_create (DBusHeader *header, - int byte_order, int message_type, const char *destination, const char *path, @@ -537,8 +526,6 @@ _dbus_header_create (DBusHeader *header, DBusTypeWriter writer; DBusTypeWriter array; - _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN || - byte_order == DBUS_BIG_ENDIAN); _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) || (error_name) || !(interface || member || error_name)); @@ -547,12 +534,12 @@ _dbus_header_create (DBusHeader *header, if (!reserve_header_padding (header)) return FALSE; - _dbus_type_writer_init_values_only (&writer, byte_order, + _dbus_type_writer_init_values_only (&writer, header->byte_order, &_dbus_header_signature_str, 0, &header->data, HEADER_END_BEFORE_PADDING (header)); - v_BYTE = byte_order; + v_BYTE = header->byte_order; if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE, &v_BYTE)) goto oom; @@ -924,8 +911,7 @@ load_and_validate_field (DBusHeader *header, _dbus_assert (bad_string_code != DBUS_VALID); len = _dbus_marshal_read_uint32 (value_str, value_pos, - _dbus_header_get_byte_order (header), - NULL); + header->byte_order, NULL); #if 0 _dbus_verbose ("Validating string header field; code %d if fails\n", @@ -1056,6 +1042,7 @@ _dbus_header_load (DBusHeader *header, _dbus_type_reader_next (&reader); _dbus_assert (v_byte == byte_order); + header->byte_order = byte_order; /* MESSAGE TYPE */ _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE); @@ -1197,7 +1184,7 @@ _dbus_header_update_lengths (DBusHeader *header, _dbus_marshal_set_uint32 (&header->data, BODY_LENGTH_OFFSET, body_len, - _dbus_header_get_byte_order (header)); + header->byte_order); } static dbus_bool_t @@ -1211,7 +1198,7 @@ find_field_for_modification (DBusHeader *header, retval = FALSE; _dbus_type_reader_init (realign_root, - _dbus_header_get_byte_order (header), + header->byte_order, &_dbus_header_signature_str, FIELDS_ARRAY_SIGNATURE_OFFSET, &header->data, @@ -1284,7 +1271,7 @@ _dbus_header_set_field_basic (DBusHeader *header, DBusTypeWriter array; _dbus_type_writer_init_values_only (&writer, - _dbus_header_get_byte_order (header), + header->byte_order, &_dbus_header_signature_str, FIELDS_ARRAY_SIGNATURE_OFFSET, &header->data, @@ -1354,7 +1341,7 @@ _dbus_header_get_field_basic (DBusHeader *header, _dbus_marshal_read_basic (&header->data, header->fields[field].value_pos, - type, value, _dbus_header_get_byte_order (header), + type, value, header->byte_order, NULL); return TRUE; @@ -1481,19 +1468,34 @@ void _dbus_header_byteswap (DBusHeader *header, int new_order) { - char byte_order; - - byte_order = _dbus_header_get_byte_order (header); + unsigned char byte_order; - if (byte_order == new_order) + if (header->byte_order == new_order) return; + byte_order = _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET); + _dbus_assert (header->byte_order == byte_order); + _dbus_marshal_byteswap (&_dbus_header_signature_str, - 0, byte_order, + 0, header->byte_order, new_order, &header->data, 0); _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order); + header->byte_order = new_order; } /** @} */ + +#ifdef DBUS_BUILD_TESTS +#include "dbus-test.h" +#include <stdio.h> + +dbus_bool_t +_dbus_marshal_header_test (void) +{ + + return TRUE; +} + +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-marshal-header.h b/dbus/dbus-marshal-header.h index 350fe5c4..fd16c5f0 100644 --- a/dbus/dbus-marshal-header.h +++ b/dbus/dbus-marshal-header.h @@ -59,11 +59,12 @@ struct DBusHeader dbus_uint32_t byte_order : 8; /**< byte order of header */ }; -dbus_bool_t _dbus_header_init (DBusHeader *header); +dbus_bool_t _dbus_header_init (DBusHeader *header, + int byte_order); void _dbus_header_free (DBusHeader *header); -void _dbus_header_reinit (DBusHeader *header); +void _dbus_header_reinit (DBusHeader *header, + int byte_order); dbus_bool_t _dbus_header_create (DBusHeader *header, - int byte_order, int type, const char *destination, const char *path, @@ -121,7 +122,6 @@ dbus_bool_t _dbus_header_load (DBusHeader *header, int len); void _dbus_header_byteswap (DBusHeader *header, int new_order); -char _dbus_header_get_byte_order (const DBusHeader *header); diff --git a/dbus/dbus-marshal-recursive-util.c b/dbus/dbus-marshal-recursive-util.c index 345b891f..3508bb0d 100644 --- a/dbus/dbus-marshal-recursive-util.c +++ b/dbus/dbus-marshal-recursive-util.c @@ -3326,6 +3326,7 @@ dict_write_value (TestTypeNode *node, DBusString dict_entry_signature; int i; int n_entries; + int entry_value_type; TestTypeNode *child; n_entries = node->klass->subclass_detail; @@ -3362,7 +3363,9 @@ dict_write_value (TestTypeNode *node, if (!_dbus_string_append_byte (&dict_entry_signature, DBUS_DICT_ENTRY_END_CHAR)) goto oom; - + + entry_value_type = _dbus_first_type_in_signature (&entry_value_signature, 0); + if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY, &dict_entry_signature, 0, &sub)) diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c index 9187a3e9..4304467d 100644 --- a/dbus/dbus-marshal-validate.c +++ b/dbus/dbus-marshal-validate.c @@ -250,7 +250,7 @@ _dbus_validate_signature_with_reason (const DBusString *type_str, if (last == DBUS_DICT_ENTRY_BEGIN_CHAR) { - if (!(dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) + if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p))) { result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; goto out; @@ -393,7 +393,7 @@ validate_body_helper (DBusTypeReader *reader, { int array_elem_type = _dbus_type_reader_get_element_type (reader); - if (!dbus_type_is_valid (array_elem_type)) + if (!_dbus_type_is_valid (array_elem_type)) { return DBUS_INVALID_UNKNOWN_TYPECODE; } @@ -1082,11 +1082,23 @@ _dbus_validate_error_name (const DBusString *str, ((c) >= 'a' && (c) <= 'z') || \ ((c) == '_') || ((c) == '-')) -static dbus_bool_t -_dbus_validate_bus_name_full (const DBusString *str, - int start, - int len, - dbus_bool_t is_namespace) +/** + * Checks that the given range of the string is a valid bus name in + * the D-Bus protocol. This includes a length restriction, etc., see + * the specification. + * + * @todo this is inconsistent with most of DBusString in that + * it allows a start,len range that extends past the string end. + * + * @param str the string + * @param start first byte index to check + * @param len number of bytes to check + * @returns #TRUE if the byte range exists and is a valid name + */ +dbus_bool_t +_dbus_validate_bus_name (const DBusString *str, + int start, + int len) { const unsigned char *s; const unsigned char *end; @@ -1164,55 +1176,13 @@ _dbus_validate_bus_name_full (const DBusString *str, ++s; } - if (!is_namespace && _DBUS_UNLIKELY (last_dot == NULL)) + if (_DBUS_UNLIKELY (last_dot == NULL)) return FALSE; return TRUE; } /** - * Checks that the given range of the string is a valid bus name in - * the D-Bus protocol. This includes a length restriction, etc., see - * the specification. - * - * @todo this is inconsistent with most of DBusString in that - * it allows a start,len range that extends past the string end. - * - * @param str the string - * @param start first byte index to check - * @param len number of bytes to check - * @returns #TRUE if the byte range exists and is a valid name - */ -dbus_bool_t -_dbus_validate_bus_name (const DBusString *str, - int start, - int len) -{ - return _dbus_validate_bus_name_full (str, start, len, FALSE); -} - -/** - * Checks that the given range of the string is a prefix of a valid bus name in - * the D-Bus protocol. Unlike _dbus_validate_bus_name(), this accepts strings - * with only one period-separated component. - * - * @todo this is inconsistent with most of DBusString in that - * it allows a start,len range that extends past the string end. - * - * @param str the string - * @param start first byte index to check - * @param len number of bytes to check - * @returns #TRUE if the byte range exists and is a valid name - */ -dbus_bool_t -_dbus_validate_bus_namespace (const DBusString *str, - int start, - int len) -{ - return _dbus_validate_bus_name_full (str, start, len, TRUE); -} - -/** * Checks that the given range of the string is a valid message type * signature in the D-Bus protocol. * diff --git a/dbus/dbus-marshal-validate.h b/dbus/dbus-marshal-validate.h index 06434201..1d2e26b8 100644 --- a/dbus/dbus-marshal-validate.h +++ b/dbus/dbus-marshal-validate.h @@ -144,9 +144,6 @@ dbus_bool_t _dbus_validate_error_name (const DBusString *str, dbus_bool_t _dbus_validate_bus_name (const DBusString *str, int start, int len); -dbus_bool_t _dbus_validate_bus_namespace (const DBusString *str, - int start, - int len); dbus_bool_t _dbus_validate_signature (const DBusString *str, int start, int len); diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c index c5f46413..ee40e82b 100644 --- a/dbus/dbus-memory.c +++ b/dbus/dbus-memory.c @@ -233,6 +233,7 @@ _dbus_get_fail_alloc_failures (void) } #ifdef DBUS_BUILD_TESTS +static dbus_bool_t called = 0; /** * Called when about to alloc some memory; if * it returns #TRUE, then the allocation should @@ -247,8 +248,6 @@ _dbus_decrement_fail_alloc_counter (void) _dbus_initialize_malloc_debug (); #ifdef DBUS_WIN_FIXME { - static dbus_bool_t called = 0; - if (!called) { _dbus_verbose("TODO: memory allocation testing errors disabled for now\n"); diff --git a/dbus/dbus-mempool.c b/dbus/dbus-mempool.c index 563bffc6..680586b7 100644 --- a/dbus/dbus-mempool.c +++ b/dbus/dbus-mempool.c @@ -390,48 +390,6 @@ _dbus_mem_pool_dealloc (DBusMemPool *pool, } } -#ifdef DBUS_ENABLE_STATS -void -_dbus_mem_pool_get_stats (DBusMemPool *pool, - dbus_uint32_t *in_use_p, - dbus_uint32_t *in_free_list_p, - dbus_uint32_t *allocated_p) -{ - DBusMemBlock *block; - DBusFreedElement *freed; - dbus_uint32_t in_use = 0; - dbus_uint32_t in_free_list = 0; - dbus_uint32_t allocated = 0; - - if (pool != NULL) - { - in_use = pool->element_size * pool->allocated_elements; - - for (freed = pool->free_elements; freed != NULL; freed = freed->next) - { - in_free_list += pool->element_size; - } - - for (block = pool->blocks; block != NULL; block = block->next) - { - if (block == pool->blocks) - allocated += pool->block_size; - else - allocated += block->used_so_far; - } - } - - if (in_use_p != NULL) - *in_use_p = in_use; - - if (in_free_list_p != NULL) - *in_free_list_p = in_free_list; - - if (allocated_p != NULL) - *allocated_p = allocated; -} -#endif /* DBUS_ENABLE_STATS */ - /** @} */ #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-mempool.h b/dbus/dbus-mempool.h index 6693eeb2..afe52472 100644 --- a/dbus/dbus-mempool.h +++ b/dbus/dbus-mempool.h @@ -39,12 +39,6 @@ void* _dbus_mem_pool_alloc (DBusMemPool *pool); dbus_bool_t _dbus_mem_pool_dealloc (DBusMemPool *pool, void *element); -/* if DBUS_ENABLE_STATS */ -void _dbus_mem_pool_get_stats (DBusMemPool *pool, - dbus_uint32_t *in_use_p, - dbus_uint32_t *in_free_list_p, - dbus_uint32_t *allocated_p); - DBUS_END_DECLS #endif /* DBUS_MEMPOOL_H */ diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c index efa4e029..7ecf8270 100644 --- a/dbus/dbus-message-factory.c +++ b/dbus/dbus-message-factory.c @@ -27,7 +27,6 @@ #ifdef DBUS_BUILD_TESTS #include "dbus-message-factory.h" #include "dbus-message-private.h" -#include "dbus-signature.h" #include "dbus-test.h" #include <stdio.h> @@ -170,7 +169,6 @@ generate_many_bodies_inner (DBusMessageDataIter *iter, DBusMessage *message; DBusString signature; DBusString body; - char byte_order; /* Keeping this small makes things go faster */ message = dbus_message_new_method_call ("o.z.F", @@ -180,15 +178,13 @@ generate_many_bodies_inner (DBusMessageDataIter *iter, if (message == NULL) _dbus_assert_not_reached ("oom"); - byte_order = _dbus_header_get_byte_order (&message->header); - set_reply_serial (message); if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) _dbus_assert_not_reached ("oom"); if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter), - byte_order, + message->byte_order, &signature, &body)) { const char *v_SIGNATURE; @@ -205,7 +201,7 @@ generate_many_bodies_inner (DBusMessageDataIter *iter, _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET, _dbus_string_get_length (&message->body), - byte_order); + message->byte_order); *message_p = message; } @@ -581,18 +577,15 @@ generate_special (DBusMessageDataIter *iter, } else if (item_seq == 8) { - char byte_order; - message = simple_method_call (); - byte_order = _dbus_header_get_byte_order (&message->header); generate_from_message (data, expected_validity, message); _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4, - byte_order); + message->byte_order); _dbus_marshal_set_uint32 (data, FIELDS_ARRAY_LENGTH_OFFSET, DBUS_MAXIMUM_MESSAGE_LENGTH / 2 + 4, - byte_order); + message->byte_order); *expected_validity = DBUS_INVALID_MESSAGE_TOO_LONG; } else if (item_seq == 9) @@ -942,9 +935,6 @@ generate_byte_changed (DBusMessageDataIter *iter, return TRUE; } -#if 0 -/* This is really expensive and doesn't add too much coverage */ - static dbus_bool_t find_next_typecode (DBusMessageDataIter *iter, DBusString *data, @@ -988,7 +978,7 @@ find_next_typecode (DBusMessageDataIter *iter, _dbus_assert (byte_seq < _dbus_string_get_length (data)); - if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq))) + if (_dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq))) break; else iter_next (iter); @@ -1027,7 +1017,7 @@ static const int typecodes[] = { DBUS_TYPE_UNIX_FD, 255 /* random invalid typecode */ }; - + static dbus_bool_t generate_typecode_changed (DBusMessageDataIter *iter, DBusString *data, @@ -1084,7 +1074,6 @@ generate_typecode_changed (DBusMessageDataIter *iter, *expected_validity = DBUS_VALIDITY_UNKNOWN; return TRUE; } -#endif typedef struct { diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h index d4e8a6c5..870934b9 100644 --- a/dbus/dbus-message-internal.h +++ b/dbus/dbus-message-internal.h @@ -46,7 +46,8 @@ dbus_bool_t _dbus_message_add_counter (DBusMessage *message, void _dbus_message_add_counter_link (DBusMessage *message, DBusList *link); void _dbus_message_remove_counter (DBusMessage *message, - DBusCounter *counter); + DBusCounter *counter, + DBusList **link_return); DBusMessageLoader* _dbus_message_loader_new (void); DBusMessageLoader* _dbus_message_loader_ref (DBusMessageLoader *loader); diff --git a/dbus/dbus-message-private.h b/dbus/dbus-message-private.h index e64258ca..c5e3b3ea 100644 --- a/dbus/dbus-message-private.h +++ b/dbus/dbus-message-private.h @@ -102,6 +102,8 @@ struct DBusMessage DBusString body; /**< Body network data. */ + char byte_order; /**< Message byte order. */ + unsigned int locked : 1; /**< Message being sent, no modifications allowed. */ #ifndef DBUS_DISABLE_CHECKS diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 0c7e80d6..a95ad0fa 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -115,11 +115,8 @@ _dbus_message_byteswap (DBusMessage *message) { const DBusString *type_str; int type_pos; - char byte_order; - - byte_order = _dbus_header_get_byte_order (&message->header); - - if (byte_order == DBUS_COMPILER_BYTE_ORDER) + + if (message->byte_order == DBUS_COMPILER_BYTE_ORDER) return; _dbus_verbose ("Swapping message into compiler byte order\n"); @@ -127,13 +124,13 @@ _dbus_message_byteswap (DBusMessage *message) get_const_signature (&message->header, &type_str, &type_pos); _dbus_marshal_byteswap (type_str, type_pos, - byte_order, + message->byte_order, DBUS_COMPILER_BYTE_ORDER, &message->body, 0); + message->byte_order = DBUS_COMPILER_BYTE_ORDER; + _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER); - _dbus_assert (_dbus_header_get_byte_order (&message->header) == - DBUS_COMPILER_BYTE_ORDER); } /** byte-swap the message if it doesn't match our byte order. @@ -142,7 +139,9 @@ _dbus_message_byteswap (DBusMessage *message) * Otherwise should not be called since it would do needless * work. */ -#define ensure_byte_order(message) _dbus_message_byteswap (message) +#define ensure_byte_order(message) \ + if (message->byte_order != DBUS_COMPILER_BYTE_ORDER) \ + _dbus_message_byteswap (message) /** * Gets the data to be sent over the network for this message. @@ -218,11 +217,6 @@ dbus_message_set_serial (DBusMessage *message, * itself not incremented. Ownership of link and counter refcount is * passed to the message. * - * This function may be called with locks held. As a result, the counter's - * notify function is not called; the caller is expected to either call - * _dbus_counter_notify() on the counter when they are no longer holding - * locks, or take the same action that would be taken by the notify function. - * * @param message the message * @param link link with counter as data */ @@ -266,11 +260,6 @@ _dbus_message_add_counter_link (DBusMessage *message, * of this message, and decremented by the size/unix fds of this * message when this message if finalized. * - * This function may be called with locks held. As a result, the counter's - * notify function is not called; the caller is expected to either call - * _dbus_counter_notify() on the counter when they are no longer holding - * locks, or take the same action that would be taken by the notify function. - * * @param message the message * @param counter the counter * @returns #FALSE if no memory @@ -296,11 +285,13 @@ _dbus_message_add_counter (DBusMessage *message, * decrements the counter by the size/unix fds of this message. * * @param message the message + * @param link_return return the link used * @param counter the counter */ void _dbus_message_remove_counter (DBusMessage *message, - DBusCounter *counter) + DBusCounter *counter, + DBusList **link_return) { DBusList *link; @@ -308,7 +299,12 @@ _dbus_message_remove_counter (DBusMessage *message, counter); _dbus_assert (link != NULL); - _dbus_list_remove_link (&message->counters, link); + _dbus_list_unlink (&message->counters, + link); + if (link_return) + *link_return = link; + else + _dbus_list_free_link (link); _dbus_counter_adjust_size (counter, - message->size_counter_delta); @@ -316,7 +312,6 @@ _dbus_message_remove_counter (DBusMessage *message, _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta); #endif - _dbus_counter_notify (counter); _dbus_counter_unref (counter); } @@ -579,7 +574,6 @@ free_counter (void *element, _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta); #endif - _dbus_counter_notify (counter); _dbus_counter_unref (counter); } @@ -668,19 +662,15 @@ dbus_message_cache_or_finalize (DBusMessage *message) static dbus_bool_t _dbus_message_iter_check (DBusMessageRealIter *iter) { - char byte_order; - if (iter == NULL) { _dbus_warn_check_failed ("dbus message iterator is NULL\n"); return FALSE; } - byte_order = _dbus_header_get_byte_order (&iter->message->header); - if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER) { - if (iter->u.reader.byte_order != byte_order) + if (iter->u.reader.byte_order != iter->message->byte_order) { _dbus_warn_check_failed ("dbus message changed byte order since iterator was created\n"); return FALSE; @@ -690,7 +680,7 @@ _dbus_message_iter_check (DBusMessageRealIter *iter) } else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER) { - if (iter->u.writer.byte_order != byte_order) + if (iter->u.writer.byte_order != iter->message->byte_order) { _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created\n"); return FALSE; @@ -1102,6 +1092,7 @@ dbus_message_new_empty_header (void) _dbus_atomic_inc (&message->refcount); + message->byte_order = DBUS_COMPILER_BYTE_ORDER; message->locked = FALSE; #ifndef DBUS_DISABLE_CHECKS message->in_cache = FALSE; @@ -1121,12 +1112,12 @@ dbus_message_new_empty_header (void) if (from_cache) { - _dbus_header_reinit (&message->header); + _dbus_header_reinit (&message->header, message->byte_order); _dbus_string_set_length (&message->body, 0); } else { - if (!_dbus_header_init (&message->header)) + if (!_dbus_header_init (&message->header, message->byte_order)) { dbus_free (message); return NULL; @@ -1167,7 +1158,6 @@ dbus_message_new (int message_type) return NULL; if (!_dbus_header_create (&message->header, - DBUS_COMPILER_BYTE_ORDER, message_type, NULL, NULL, NULL, NULL, NULL)) { @@ -1221,7 +1211,6 @@ dbus_message_new_method_call (const char *destination, return NULL; if (!_dbus_header_create (&message->header, - DBUS_COMPILER_BYTE_ORDER, DBUS_MESSAGE_TYPE_METHOD_CALL, destination, path, interface, method, NULL)) { @@ -1256,7 +1245,6 @@ dbus_message_new_method_return (DBusMessage *method_call) return NULL; if (!_dbus_header_create (&message->header, - DBUS_COMPILER_BYTE_ORDER, DBUS_MESSAGE_TYPE_METHOD_RETURN, sender, NULL, NULL, NULL, NULL)) { @@ -1309,7 +1297,6 @@ dbus_message_new_signal (const char *path, return NULL; if (!_dbus_header_create (&message->header, - DBUS_COMPILER_BYTE_ORDER, DBUS_MESSAGE_TYPE_SIGNAL, NULL, path, interface, name, NULL)) { @@ -1360,7 +1347,6 @@ dbus_message_new_error (DBusMessage *reply_to, return NULL; if (!_dbus_header_create (&message->header, - DBUS_COMPILER_BYTE_ORDER, DBUS_MESSAGE_TYPE_ERROR, sender, NULL, NULL, NULL, error_name)) { @@ -1465,7 +1451,7 @@ dbus_message_copy (const DBusMessage *message) return NULL; _dbus_atomic_inc (&retval->refcount); - + retval->byte_order = message->byte_order; retval->locked = FALSE; #ifndef DBUS_DISABLE_CHECKS retval->generation = message->generation; @@ -1951,7 +1937,7 @@ dbus_message_iter_init (DBusMessage *message, DBUS_MESSAGE_ITER_TYPE_READER); _dbus_type_reader_init (&real->u.reader, - _dbus_header_get_byte_order (&message->header), + message->byte_order, type_str, type_pos, &message->body, 0); @@ -2267,14 +2253,12 @@ dbus_message_iter_get_fixed_array (DBusMessageIter *iter, int *n_elements) { DBusMessageRealIter *real = (DBusMessageRealIter *)iter; -#ifndef DBUS_DISABLE_CHECKS int subtype = _dbus_type_reader_get_current_type(&real->u.reader); _dbus_return_if_fail (_dbus_message_iter_check (real)); _dbus_return_if_fail (value != NULL); _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) || (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD)); -#endif _dbus_type_reader_read_fixed_multi (&real->u.reader, value, n_elements); @@ -2308,7 +2292,7 @@ dbus_message_iter_init_append (DBusMessage *message, * due to OOM. */ _dbus_type_writer_init_types_delayed (&real->u.writer, - _dbus_header_get_byte_order (&message->header), + message->byte_order, &message->body, _dbus_string_get_length (&message->body)); } @@ -2826,14 +2810,12 @@ dbus_message_iter_abandon_container (DBusMessageIter *iter, DBusMessageIter *sub) { DBusMessageRealIter *real = (DBusMessageRealIter *)iter; -#ifndef DBUS_DISABLE_CHECKS DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub; _dbus_return_if_fail (_dbus_message_iter_append_check (real)); _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER); _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub)); _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER); -#endif _dbus_message_iter_abandon_signature (real); } @@ -4021,6 +4003,8 @@ load_message (DBusMessageLoader *loader, _dbus_assert (validity == DBUS_VALID); + message->byte_order = byte_order; + /* 2. VALIDATE BODY */ if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY) { @@ -4705,7 +4689,6 @@ dbus_message_demarshal_bytes_needed(const char *buf, if (validity == DBUS_VALID) { _dbus_assert (have_message || (header_len + body_len) > len); - (void) have_message; /* unused unless asserting */ return header_len + body_len; } else diff --git a/dbus/dbus-nonce.c b/dbus/dbus-nonce.c index e74c2dd5..d30b2535 100644 --- a/dbus/dbus-nonce.c +++ b/dbus/dbus-nonce.c @@ -196,6 +196,7 @@ _dbus_send_nonce (int fd, const DBusString *noncefile, DBusError *error) { dbus_bool_t read_result; int send_result; + size_t sendLen; DBusString nonce; _DBUS_ASSERT_ERROR_IS_CLEAR (error); @@ -239,6 +240,7 @@ do_noncefile_create (DBusNonceFile *noncefile, DBusError *error, dbus_bool_t use_subdir) { + dbus_bool_t ret; DBusString randomStr; _DBUS_ASSERT_ERROR_IS_CLEAR (error); diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c index 172c9d95..d244045c 100644 --- a/dbus/dbus-object-tree.c +++ b/dbus/dbus-object-tree.c @@ -745,8 +745,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree, */ DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, - DBusMessage *message, - dbus_bool_t *found_object) + DBusMessage *message) { char **path; dbus_bool_t exact_match; @@ -792,9 +791,6 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, /* Find the deepest path that covers the path in the message */ subtree = find_handler (tree, (const char**) path, &exact_match); - if (found_object) - *found_object = !!subtree; - /* Build a list of all paths that cover the path in the message */ list = NULL; @@ -1395,7 +1391,7 @@ do_test_dispatch (DBusObjectTree *tree, ++j; } - result = _dbus_object_tree_dispatch_and_unlock (tree, message, NULL); + result = _dbus_object_tree_dispatch_and_unlock (tree, message); if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) goto oom; diff --git a/dbus/dbus-object-tree.h b/dbus/dbus-object-tree.h index 5576c25d..022dd93f 100644 --- a/dbus/dbus-object-tree.h +++ b/dbus/dbus-object-tree.h @@ -42,8 +42,7 @@ dbus_bool_t _dbus_object_tree_register (DBusObjectTree void _dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree, const char **path); DBusHandlerResult _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree, - DBusMessage *message, - dbus_bool_t *found_object); + DBusMessage *message); void* _dbus_object_tree_get_user_data_unlocked (DBusObjectTree *tree, const char **path); void _dbus_object_tree_free_all_unlocked (DBusObjectTree *tree); diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c index e7f5cd98..cfb2bafe 100644 --- a/dbus/dbus-pending-call.c +++ b/dbus/dbus-pending-call.c @@ -353,8 +353,6 @@ _dbus_pending_call_set_timeout_error_unlocked (DBusPendingCall *pending, reply_link = _dbus_list_alloc_link (reply); if (reply_link == NULL) { - /* it's OK to unref this, nothing that could have attached a callback - * has ever seen it */ dbus_message_unref (reply); return FALSE; } @@ -808,3 +806,19 @@ dbus_pending_call_get_data (DBusPendingCall *pending, } /** @} */ + +#ifdef DBUS_BUILD_TESTS + +/** + * @ingroup DBusPendingCallInternals + * Unit test for DBusPendingCall. + * + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_pending_call_test (const char *test_data_dir) +{ + + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-resources.c b/dbus/dbus-resources.c index 42aedf58..5f7001cc 100644 --- a/dbus/dbus-resources.c +++ b/dbus/dbus-resources.c @@ -58,17 +58,11 @@ struct DBusCounter long size_value; /**< current size counter value */ long unix_fd_value; /**< current unix fd counter value */ -#ifdef DBUS_ENABLE_STATS - long peak_size_value; /**< largest ever size counter value */ - long peak_unix_fd_value; /**< largest ever unix fd counter value */ -#endif - long notify_size_guard_value; /**< call notify function when crossing this size value */ long notify_unix_fd_guard_value; /**< call notify function when crossing this unix fd value */ DBusCounterNotifyFunction notify_function; /**< notify function */ void *notify_data; /**< data for notify function */ - dbus_bool_t notify_pending : 1; /**< TRUE if the guard value has been crossed */ }; /** @} */ /* end of resource limits internals docs */ @@ -97,16 +91,10 @@ _dbus_counter_new (void) counter->size_value = 0; counter->unix_fd_value = 0; -#ifdef DBUS_ENABLE_STATS - counter->peak_size_value = 0; - counter->peak_unix_fd_value = 0; -#endif - counter->notify_size_guard_value = 0; counter->notify_unix_fd_guard_value = 0; counter->notify_function = NULL; counter->notify_data = NULL; - counter->notify_pending = FALSE; return counter; } @@ -150,9 +138,8 @@ _dbus_counter_unref (DBusCounter *counter) /** * Adjusts the value of the size counter by the given * delta which may be positive or negative. - * - * This function may be called with locks held. After calling it, when - * any relevant locks are no longer held you must call _dbus_counter_notify(). + * Calls the notify function from _dbus_counter_set_notify() + * if that function has been specified. * * @param counter the counter * @param delta value to add to the size counter's current value @@ -165,11 +152,6 @@ _dbus_counter_adjust_size (DBusCounter *counter, counter->size_value += delta; -#ifdef DBUS_ENABLE_STATS - if (counter->peak_size_value < counter->size_value) - counter->peak_size_value = counter->size_value; -#endif - #if 0 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", old, delta, counter->size_value); @@ -180,33 +162,14 @@ _dbus_counter_adjust_size (DBusCounter *counter, counter->size_value >= counter->notify_size_guard_value) || (old >= counter->notify_size_guard_value && counter->size_value < counter->notify_size_guard_value))) - counter->notify_pending = TRUE; -} - -/** - * Calls the notify function from _dbus_counter_set_notify(), - * if that function has been specified and the counter has crossed the - * guard value (in either direction) since the last call to this function. - * - * This function must not be called with locks held, since it can call out - * to user code. - */ -void -_dbus_counter_notify (DBusCounter *counter) -{ - if (counter->notify_pending) - { - counter->notify_pending = FALSE; - (* counter->notify_function) (counter, counter->notify_data); - } + (* counter->notify_function) (counter, counter->notify_data); } /** * Adjusts the value of the unix fd counter by the given * delta which may be positive or negative. - * - * This function may be called with locks held. After calling it, when - * any relevant locks are no longer held you must call _dbus_counter_notify(). + * Calls the notify function from _dbus_counter_set_notify() + * if that function has been specified. * * @param counter the counter * @param delta value to add to the unix fds counter's current value @@ -219,11 +182,6 @@ _dbus_counter_adjust_unix_fd (DBusCounter *counter, counter->unix_fd_value += delta; -#ifdef DBUS_ENABLE_STATS - if (counter->peak_unix_fd_value < counter->unix_fd_value) - counter->peak_unix_fd_value = counter->unix_fd_value; -#endif - #if 0 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", old, delta, counter->unix_fd_value); @@ -234,7 +192,7 @@ _dbus_counter_adjust_unix_fd (DBusCounter *counter, counter->unix_fd_value >= counter->notify_unix_fd_guard_value) || (old >= counter->notify_unix_fd_guard_value && counter->unix_fd_value < counter->notify_unix_fd_guard_value))) - counter->notify_pending = TRUE; + (* counter->notify_function) (counter, counter->notify_data); } /** @@ -283,21 +241,6 @@ _dbus_counter_set_notify (DBusCounter *counter, counter->notify_unix_fd_guard_value = unix_fd_guard_value; counter->notify_function = function; counter->notify_data = user_data; - counter->notify_pending = FALSE; -} - -#ifdef DBUS_ENABLE_STATS -long -_dbus_counter_get_peak_size_value (DBusCounter *counter) -{ - return counter->peak_size_value; } -long -_dbus_counter_get_peak_unix_fd_value (DBusCounter *counter) -{ - return counter->peak_unix_fd_value; -} -#endif - /** @} */ /* end of resource limits exported API */ diff --git a/dbus/dbus-resources.h b/dbus/dbus-resources.h index 781a5756..4763a97f 100644 --- a/dbus/dbus-resources.h +++ b/dbus/dbus-resources.h @@ -42,7 +42,6 @@ void _dbus_counter_adjust_size (DBusCounter *counter, long delta); void _dbus_counter_adjust_unix_fd (DBusCounter *counter, long delta); -void _dbus_counter_notify (DBusCounter *counter); long _dbus_counter_get_size_value (DBusCounter *counter); long _dbus_counter_get_unix_fd_value (DBusCounter *counter); @@ -52,9 +51,6 @@ void _dbus_counter_set_notify (DBusCounter *counter, DBusCounterNotifyFunction function, void *user_data); -/* if DBUS_ENABLE_STATS */ -long _dbus_counter_get_peak_size_value (DBusCounter *counter); -long _dbus_counter_get_peak_unix_fd_value (DBusCounter *counter); DBUS_END_DECLS diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c index 8e31da9d..e8a24e48 100644 --- a/dbus/dbus-server-socket.c +++ b/dbus/dbus-server-socket.c @@ -89,8 +89,10 @@ handle_new_client_fd_and_unlock (DBusServer *server, DBusConnection *connection; DBusTransport *transport; DBusNewConnectionFunction new_connection_function; + DBusServerSocket* socket_server; void *new_connection_data; + socket_server = (DBusServerSocket*)server; _dbus_verbose ("Creating new client connection with fd %d\n", client_fd); HAVE_LOCK_CHECK (server); @@ -234,7 +236,6 @@ socket_disconnect (DBusServer *server) { _dbus_server_remove_watch (server, socket_server->watch[i]); - _dbus_watch_invalidate (socket_server->watch[i]); _dbus_watch_unref (socket_server->watch[i]); socket_server->watch[i] = NULL; } diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c index c130de5b..9c13ff43 100644 --- a/dbus/dbus-signature.c +++ b/dbus/dbus-signature.c @@ -284,8 +284,7 @@ dbus_signature_validate_single (const char *signature, * container types. #DBUS_TYPE_INVALID is not a container type. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #TRUE if type is a container @@ -294,7 +293,7 @@ dbus_bool_t dbus_type_is_container (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); return TYPE_IS_CONTAINER (typecode); } @@ -308,8 +307,7 @@ dbus_type_is_container (int typecode) * type. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #TRUE if type is basic @@ -318,7 +316,7 @@ dbus_bool_t dbus_type_is_basic (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); /* everything that isn't invalid or a container */ @@ -339,8 +337,7 @@ dbus_type_is_basic (int typecode) * function. * * It is an error to pass an invalid type-code, other than DBUS_TYPE_INVALID, - * to this function. The valid type-codes are defined by dbus-protocol.h - * and can be checked with dbus_type_is_valid(). + * to this function. The valid type-codes are defined by dbus-protocol.h. * * @param typecode either a valid type-code or DBUS_TYPE_INVALID * @returns #FALSE if the type can occupy different lengths @@ -349,7 +346,7 @@ dbus_bool_t dbus_type_is_fixed (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ - _dbus_return_val_if_fail (dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, + _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); switch (typecode) @@ -370,44 +367,6 @@ dbus_type_is_fixed (int typecode) } } -/** - * Return #TRUE if the argument is a valid typecode. - * #DBUS_TYPE_INVALID surprisingly enough is not considered valid, and - * random unknown bytes aren't either. This function is safe with - * untrusted data. - * - * @param typecode a potential type-code - * @returns #TRUE if valid - */ -dbus_bool_t -dbus_type_is_valid (int typecode) -{ - switch (typecode) - { - case DBUS_TYPE_BYTE: - case DBUS_TYPE_BOOLEAN: - case DBUS_TYPE_INT16: - case DBUS_TYPE_UINT16: - case DBUS_TYPE_INT32: - case DBUS_TYPE_UINT32: - case DBUS_TYPE_INT64: - case DBUS_TYPE_UINT64: - case DBUS_TYPE_DOUBLE: - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: - case DBUS_TYPE_ARRAY: - case DBUS_TYPE_STRUCT: - case DBUS_TYPE_DICT_ENTRY: - case DBUS_TYPE_VARIANT: - case DBUS_TYPE_UNIX_FD: - return TRUE; - - default: - return FALSE; - } -} - /** @} */ /* end of DBusSignature group */ #ifdef DBUS_BUILD_TESTS diff --git a/dbus/dbus-signature.h b/dbus/dbus-signature.h index 443941c8..ebf00c1e 100644 --- a/dbus/dbus-signature.h +++ b/dbus/dbus-signature.h @@ -79,9 +79,6 @@ dbus_bool_t dbus_signature_validate_single (const char *signatur DBusError *error); DBUS_EXPORT -dbus_bool_t dbus_type_is_valid (int typecode); - -DBUS_EXPORT dbus_bool_t dbus_type_is_basic (int typecode); DBUS_EXPORT dbus_bool_t dbus_type_is_container (int typecode); diff --git a/dbus/dbus-spawn-win.c b/dbus/dbus-spawn-win.c index cb6ebb2d..8ac837ed 100644 --- a/dbus/dbus-spawn-win.c +++ b/dbus/dbus-spawn-win.c @@ -42,7 +42,6 @@ #include "dbus-protocol.h" #define WIN32_LEAN_AND_MEAN -#include <windows.h> //#define STRICT //#include <windows.h> //#undef STRICT @@ -82,8 +81,6 @@ struct DBusBabysitter DBusWatchList *watches; DBusWatch *sitter_watch; - DBusBabysitterFinishedFunc finished_cb; - void *finished_data; dbus_bool_t have_spawn_errno; int spawn_errno; @@ -157,27 +154,6 @@ _dbus_babysitter_ref (DBusBabysitter *sitter) return sitter; } -static void -close_socket_to_babysitter (DBusBabysitter *sitter) -{ - _dbus_verbose ("Closing babysitter\n"); - - if (sitter->sitter_watch != NULL) - { - _dbus_assert (sitter->watches != NULL); - _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch); - _dbus_watch_invalidate (sitter->sitter_watch); - _dbus_watch_unref (sitter->sitter_watch); - sitter->sitter_watch = NULL; - } - - if (sitter->socket_to_babysitter != -1) - { - _dbus_close_socket (sitter->socket_to_babysitter, NULL); - sitter->socket_to_babysitter = -1; - } -} - /** * Decrement the reference count on the babysitter object. * @@ -196,7 +172,11 @@ _dbus_babysitter_unref (DBusBabysitter *sitter) if (sitter->refcount == 0) { - close_socket_to_babysitter (sitter); + if (sitter->socket_to_babysitter != -1) + { + _dbus_close_socket (sitter->socket_to_babysitter, NULL); + sitter->socket_to_babysitter = -1; + } if (sitter->socket_to_main != -1) { @@ -392,15 +372,9 @@ handle_watch (DBusWatch *watch, */ PING(); - close_socket_to_babysitter (sitter); + _dbus_close_socket (sitter->socket_to_babysitter, NULL); PING(); - - if (_dbus_babysitter_get_child_exited (sitter) && - sitter->finished_cb != NULL) - { - sitter->finished_cb (sitter, sitter->finished_data); - sitter->finished_cb = NULL; - } + sitter->socket_to_babysitter = -1; return TRUE; } @@ -503,7 +477,8 @@ compose_string (char **strings, char separator) int n = 0; char *buf; char *p; - + const char *ptr; + if (!strings || !strings[0]) return 0; for (i = 0; strings[i]; i++) @@ -545,7 +520,6 @@ spawn_program (char* name, char** argv, char** envp) STARTUPINFOA si; char *arg_string, *env_string; BOOL result; - char exe_path[MAX_PATH]; #ifdef DBUS_WINCE if (argv && argv[0]) @@ -560,45 +534,14 @@ spawn_program (char* name, char** argv, char** envp) env_string = build_env_string(envp); -#ifndef DBUS_WINCE - // handle relative pathes - if (strlen(name) > 2 && name[0] != '\\' && name[0] != '/' && name[1] != ':') - { - char install_root[2*MAX_PATH]; - LPSTR lpFile; - char *p; - _dbus_verbose ("babysitter: spawning %s", name); - if (!_dbus_get_install_root (install_root, sizeof(install_root))) - return INVALID_HANDLE_VALUE; - - strcat(install_root,name); - - // add exe extension, if not present - p = strrchr(name,'.'); - if (!p) - strcat(install_root,".exe"); - - // convert '/' into '\\' - while((p = strchr(install_root,'/')) != 0) - *p = '\\'; - - // separate path from filename - p = strrchr(install_root,'\\'); - // no complete path: error condition - if (!p) - return INVALID_HANDLE_VALUE; - *p = 0; - if (!SearchPathA(install_root, p+1, NULL, sizeof(exe_path), exe_path, &lpFile)) - return INVALID_HANDLE_VALUE; - } - else -#endif - strncpy(exe_path,name,MAX_PATH); - memset (&si, 0, sizeof (si)); si.cb = sizeof (si); - result = CreateProcessA (exe_path, arg_string, NULL, NULL, FALSE, 0, - (LPVOID)env_string, NULL, &si, &pi); +#ifdef DBUS_WINCE + result = CreateProcessA (name, arg_string, NULL, NULL, FALSE, 0, +#else + result = CreateProcessA (NULL, arg_string, NULL, NULL, FALSE, 0, +#endif + (LPVOID)env_string, NULL, &si, &pi); free (arg_string); if (env_string) free (env_string); @@ -615,7 +558,7 @@ static DWORD __stdcall babysitter (void *parameter) { DBusBabysitter *sitter = (DBusBabysitter *) parameter; - + int fd; PING(); _dbus_babysitter_ref (sitter); @@ -725,12 +668,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, PING(); if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) { - /* we need to free it early so the destructor won't try to remove it - * without it having been added, which DBusLoop doesn't allow */ - _dbus_watch_invalidate (sitter->sitter_watch); - _dbus_watch_unref (sitter->sitter_watch); - sitter->sitter_watch = NULL; - _DBUS_SET_OOM (error); goto out0; } @@ -776,41 +713,8 @@ out0: return FALSE; } -void -_dbus_babysitter_set_result_function (DBusBabysitter *sitter, - DBusBabysitterFinishedFunc finished, - void *user_data) -{ - sitter->finished_cb = finished; - sitter->finished_data = user_data; -} - #ifdef DBUS_BUILD_TESTS -static char * -get_test_exec (const char *exe, - DBusString *scratch_space) -{ - const char *dbus_test_exec; - - dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC"); - - if (dbus_test_exec == NULL) - dbus_test_exec = DBUS_TEST_EXEC; - - if (!_dbus_string_init (scratch_space)) - return NULL; - - if (!_dbus_string_append_printf (scratch_space, "%s/%s%s", - dbus_test_exec, exe, DBUS_EXEEXT)) - { - _dbus_string_free (scratch_space); - return NULL; - } - - return _dbus_string_get_data (scratch_space); -} - #define LIVE_CHILDREN(sitter) ((sitter)->child_handle != NULL) static void @@ -873,7 +777,6 @@ check_spawn_segfault (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter; DBusError error; - DBusString argv0; sitter = NULL; @@ -881,14 +784,7 @@ check_spawn_segfault (void *data) /*** Test launching segfault binary */ - argv[0] = get_test_exec ("test-segfault", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + argv[0] = TEST_SEGFAULT_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -897,8 +793,6 @@ check_spawn_segfault (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); @@ -928,7 +822,6 @@ check_spawn_exit (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter; DBusError error; - DBusString argv0; sitter = NULL; @@ -936,14 +829,7 @@ check_spawn_exit (void *data) /*** Test launching exit failure binary */ - argv[0] = get_test_exec ("test-exit", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + argv[0] = TEST_EXIT_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -952,8 +838,6 @@ check_spawn_exit (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); @@ -983,7 +867,6 @@ check_spawn_and_kill (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter; DBusError error; - DBusString argv0; sitter = NULL; @@ -991,14 +874,7 @@ check_spawn_and_kill (void *data) /*** Test launching sleeping binary then killing it */ - argv[0] = get_test_exec ("test-sleep-forever", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + argv[0] = TEST_SLEEP_FOREVER_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -1010,8 +886,6 @@ check_spawn_and_kill (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index ef00801c..a1bab3df 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -205,9 +205,6 @@ struct DBusBabysitter DBusWatch *error_watch; /**< Error pipe watch */ DBusWatch *sitter_watch; /**< Sitter pipe watch */ - DBusBabysitterFinishedFunc finished_cb; - void *finished_data; - int errnum; /**< Error number */ int status; /**< Exit status code */ unsigned int have_child_status : 1; /**< True if child status has been reaped */ @@ -260,9 +257,6 @@ _dbus_babysitter_ref (DBusBabysitter *sitter) return sitter; } -static void close_socket_to_babysitter (DBusBabysitter *sitter); -static void close_error_pipe_from_child (DBusBabysitter *sitter); - /** * Decrement the reference count on the babysitter object. * When the reference count of the babysitter object reaches @@ -279,17 +273,25 @@ _dbus_babysitter_unref (DBusBabysitter *sitter) sitter->refcount -= 1; if (sitter->refcount == 0) - { - /* If we haven't forked other babysitters - * since this babysitter and socket were - * created then this close will cause the - * babysitter to wake up from poll with - * a hangup and then the babysitter will - * quit itself. - */ - close_socket_to_babysitter (sitter); + { + if (sitter->socket_to_babysitter >= 0) + { + /* If we haven't forked other babysitters + * since this babysitter and socket were + * created then this close will cause the + * babysitter to wake up from poll with + * a hangup and then the babysitter will + * quit itself. + */ + _dbus_close_socket (sitter->socket_to_babysitter, NULL); + sitter->socket_to_babysitter = -1; + } - close_error_pipe_from_child (sitter); + if (sitter->error_pipe_from_child >= 0) + { + _dbus_close_socket (sitter->error_pipe_from_child, NULL); + sitter->error_pipe_from_child = -1; + } if (sitter->sitter_pid > 0) { @@ -339,7 +341,21 @@ _dbus_babysitter_unref (DBusBabysitter *sitter) sitter->sitter_pid = -1; } + + if (sitter->error_watch) + { + _dbus_watch_invalidate (sitter->error_watch); + _dbus_watch_unref (sitter->error_watch); + sitter->error_watch = NULL; + } + if (sitter->sitter_watch) + { + _dbus_watch_invalidate (sitter->sitter_watch); + _dbus_watch_unref (sitter->sitter_watch); + sitter->sitter_watch = NULL; + } + if (sitter->watches) _dbus_watch_list_free (sitter->watches); @@ -460,42 +476,16 @@ static void close_socket_to_babysitter (DBusBabysitter *sitter) { _dbus_verbose ("Closing babysitter\n"); - - if (sitter->sitter_watch != NULL) - { - _dbus_assert (sitter->watches != NULL); - _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch); - _dbus_watch_invalidate (sitter->sitter_watch); - _dbus_watch_unref (sitter->sitter_watch); - sitter->sitter_watch = NULL; - } - - if (sitter->socket_to_babysitter >= 0) - { - _dbus_close_socket (sitter->socket_to_babysitter, NULL); - sitter->socket_to_babysitter = -1; - } + _dbus_close_socket (sitter->socket_to_babysitter, NULL); + sitter->socket_to_babysitter = -1; } static void close_error_pipe_from_child (DBusBabysitter *sitter) { _dbus_verbose ("Closing child error\n"); - - if (sitter->error_watch != NULL) - { - _dbus_assert (sitter->watches != NULL); - _dbus_watch_list_remove_watch (sitter->watches, sitter->error_watch); - _dbus_watch_invalidate (sitter->error_watch); - _dbus_watch_unref (sitter->error_watch); - sitter->error_watch = NULL; - } - - if (sitter->error_pipe_from_child >= 0) - { - _dbus_close_socket (sitter->error_pipe_from_child, NULL); - sitter->error_pipe_from_child = -1; - } + _dbus_close_socket (sitter->error_pipe_from_child, NULL); + sitter->error_pipe_from_child = -1; } static void @@ -762,7 +752,7 @@ handle_watch (DBusWatch *watch, unsigned int condition, void *data) { - DBusBabysitter *sitter = _dbus_babysitter_ref (data); + DBusBabysitter *sitter = data; int revents; int fd; @@ -785,19 +775,31 @@ handle_watch (DBusWatch *watch, babysitter_iteration (sitter, FALSE)) ; - /* fd.o #32992: if the handle_* methods closed their sockets, they previously - * didn't always remove the watches. Check that we don't regress. */ - _dbus_assert (sitter->socket_to_babysitter != -1 || sitter->sitter_watch == NULL); - _dbus_assert (sitter->error_pipe_from_child != -1 || sitter->error_watch == NULL); + /* Those might have closed the sockets we're watching. Before returning + * to the main loop, we must sort that out. */ - if (_dbus_babysitter_get_child_exited (sitter) && - sitter->finished_cb != NULL) + if (sitter->error_watch != NULL && sitter->error_pipe_from_child == -1) { - sitter->finished_cb (sitter, sitter->finished_data); - sitter->finished_cb = NULL; + _dbus_watch_invalidate (sitter->error_watch); + + if (sitter->watches != NULL) + _dbus_watch_list_remove_watch (sitter->watches, sitter->error_watch); + + _dbus_watch_unref (sitter->error_watch); + sitter->error_watch = NULL; + } + + if (sitter->sitter_watch != NULL && sitter->socket_to_babysitter == -1) + { + _dbus_watch_invalidate (sitter->sitter_watch); + + if (sitter->watches != NULL) + _dbus_watch_list_remove_watch (sitter->watches, sitter->sitter_watch); + + _dbus_watch_unref (sitter->sitter_watch); + sitter->sitter_watch = NULL; } - _dbus_babysitter_unref (sitter); return TRUE; } @@ -1103,9 +1105,7 @@ babysit (pid_t grandchild_pid, { char b; if (read (sigchld_pipe[READ_END], &b, 1) == -1) - { - /* ignore */ - } + /* ignore */; /* do waitpid check */ check_babysit_events (grandchild_pid, parent_pipe, 0); } @@ -1189,12 +1189,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, if (!_dbus_watch_list_add_watch (sitter->watches, sitter->error_watch)) { - /* we need to free it early so the destructor won't try to remove it - * without it having been added, which DBusLoop doesn't allow */ - _dbus_watch_invalidate (sitter->error_watch); - _dbus_watch_unref (sitter->error_watch); - sitter->error_watch = NULL; - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto cleanup_and_fail; } @@ -1210,12 +1204,6 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, if (!_dbus_watch_list_add_watch (sitter->watches, sitter->sitter_watch)) { - /* we need to free it early so the destructor won't try to remove it - * without it having been added, which DBusLoop doesn't allow */ - _dbus_watch_invalidate (sitter->sitter_watch); - _dbus_watch_unref (sitter->sitter_watch); - sitter->sitter_watch = NULL; - dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); goto cleanup_and_fail; } @@ -1310,43 +1298,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, return FALSE; } -void -_dbus_babysitter_set_result_function (DBusBabysitter *sitter, - DBusBabysitterFinishedFunc finished, - void *user_data) -{ - sitter->finished_cb = finished; - sitter->finished_data = user_data; -} - /** @} */ #ifdef DBUS_BUILD_TESTS -static char * -get_test_exec (const char *exe, - DBusString *scratch_space) -{ - const char *dbus_test_exec; - - dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC"); - - if (dbus_test_exec == NULL) - dbus_test_exec = DBUS_TEST_EXEC; - - if (!_dbus_string_init (scratch_space)) - return NULL; - - if (!_dbus_string_append_printf (scratch_space, "%s/%s%s", - dbus_test_exec, exe, DBUS_EXEEXT)) - { - _dbus_string_free (scratch_space); - return NULL; - } - - return _dbus_string_get_data (scratch_space); -} - static void _dbus_babysitter_block_for_child_exit (DBusBabysitter *sitter) { @@ -1401,18 +1356,10 @@ check_spawn_segfault (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter = NULL; DBusError error = DBUS_ERROR_INIT; - DBusString argv0; /*** Test launching segfault binary */ - - argv[0] = get_test_exec ("test-segfault", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + + argv[0] = TEST_SEGFAULT_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -1421,8 +1368,6 @@ check_spawn_segfault (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); @@ -1452,18 +1397,10 @@ check_spawn_exit (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter = NULL; DBusError error = DBUS_ERROR_INIT; - DBusString argv0; /*** Test launching exit failure binary */ - - argv[0] = get_test_exec ("test-exit", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + + argv[0] = TEST_EXIT_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -1472,8 +1409,6 @@ check_spawn_exit (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); @@ -1503,18 +1438,10 @@ check_spawn_and_kill (void *data) char *argv[4] = { NULL, NULL, NULL, NULL }; DBusBabysitter *sitter = NULL; DBusError error = DBUS_ERROR_INIT; - DBusString argv0; /*** Test launching sleeping binary then killing it */ - argv[0] = get_test_exec ("test-sleep-forever", &argv0); - - if (argv[0] == NULL) - { - /* OOM was simulated, never mind */ - return TRUE; - } - + argv[0] = TEST_SLEEP_FOREVER_BINARY; if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL, NULL, NULL, &error)) @@ -1526,8 +1453,6 @@ check_spawn_and_kill (void *data) _dbus_babysitter_set_child_exit_error (sitter, &error); } - _dbus_string_free (&argv0); - if (sitter) _dbus_babysitter_unref (sitter); diff --git a/dbus/dbus-spawn.h b/dbus/dbus-spawn.h index a8814fb9..5af54b72 100644 --- a/dbus/dbus-spawn.h +++ b/dbus/dbus-spawn.h @@ -35,18 +35,12 @@ typedef void (* DBusSpawnChildSetupFunc) (void *user_data); typedef struct DBusBabysitter DBusBabysitter; -typedef void (* DBusBabysitterFinishedFunc) (DBusBabysitter *sitter, - void *user_data); - dbus_bool_t _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p, char **argv, char **env, DBusSpawnChildSetupFunc child_setup, void *user_data, DBusError *error); -void _dbus_babysitter_set_result_function (DBusBabysitter *sitter, - DBusBabysitterFinishedFunc finished, - void *user_data); DBusBabysitter* _dbus_babysitter_ref (DBusBabysitter *sitter); void _dbus_babysitter_unref (DBusBabysitter *sitter); void _dbus_babysitter_kill_child (DBusBabysitter *sitter); diff --git a/dbus/dbus-string-private.h b/dbus/dbus-string-private.h index 2e6de900..b17c2b9f 100644 --- a/dbus/dbus-string-private.h +++ b/dbus/dbus-string-private.h @@ -45,6 +45,7 @@ typedef struct unsigned char *str; /**< String data, plus nul termination */ int len; /**< Length without nul */ int allocated; /**< Allocated size of data */ + int max_length; /**< Max length of this string, without nul byte */ unsigned int constant : 1; /**< String data is not owned by DBusString */ unsigned int locked : 1; /**< DBusString has been locked and can't be changed */ unsigned int invalid : 1; /**< DBusString is invalid (e.g. already freed) */ @@ -64,25 +65,17 @@ _DBUS_STATIC_ASSERT (sizeof (DBusRealString) == sizeof (DBusString)); */ /** - * The maximum length of a DBusString + * This is the maximum max length (and thus also the maximum length) + * of a DBusString */ -#define _DBUS_STRING_MAX_LENGTH (_DBUS_INT32_MAX - _DBUS_STRING_ALLOCATION_PADDING) +#define _DBUS_STRING_MAX_MAX_LENGTH (_DBUS_INT32_MAX - _DBUS_STRING_ALLOCATION_PADDING) /** * Checks a bunch of assertions about a string object * * @param real the DBusRealString */ -#define DBUS_GENERIC_STRING_PREAMBLE(real) \ - do { \ - (void) real; /* might be unused unless asserting */ \ - _dbus_assert ((real) != NULL); \ - _dbus_assert (!(real)->invalid); \ - _dbus_assert ((real)->len >= 0); \ - _dbus_assert ((real)->allocated >= 0); \ - _dbus_assert ((real)->len <= ((real)->allocated - _DBUS_STRING_ALLOCATION_PADDING)); \ - _dbus_assert ((real)->len <= _DBUS_STRING_MAX_LENGTH); \ - } while (0) +#define DBUS_GENERIC_STRING_PREAMBLE(real) _dbus_assert ((real) != NULL); _dbus_assert (!(real)->invalid); _dbus_assert ((real)->len >= 0); _dbus_assert ((real)->allocated >= 0); _dbus_assert ((real)->max_length >= 0); _dbus_assert ((real)->len <= ((real)->allocated - _DBUS_STRING_ALLOCATION_PADDING)); _dbus_assert ((real)->len <= (real)->max_length) /** * Checks assertions about a string object that needs to be diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c index 421ac1b4..4d42bb0b 100644 --- a/dbus/dbus-string-util.c +++ b/dbus/dbus-string-util.c @@ -120,6 +120,26 @@ _dbus_string_find_byte_backward (const DBusString *str, #include <stdio.h> static void +test_max_len (DBusString *str, + int max_len) +{ + if (max_len > 0) + { + if (!_dbus_string_set_length (str, max_len - 1)) + _dbus_assert_not_reached ("setting len to one less than max should have worked"); + } + + if (!_dbus_string_set_length (str, max_len)) + _dbus_assert_not_reached ("setting len to max len should have worked"); + + if (_dbus_string_set_length (str, max_len + 1)) + _dbus_assert_not_reached ("setting len to one more than max len should not have worked"); + + if (!_dbus_string_set_length (str, 0)) + _dbus_assert_not_reached ("setting len to zero should have worked"); +} + +static void test_hex_roundtrip (const unsigned char *data, int len) { @@ -212,6 +232,25 @@ test_roundtrips (TestRoundtripFunc func) } } +#ifdef DBUS_BUILD_TESTS +/* The max length thing is sort of a historical artifact + * from a feature that turned out to be dumb; perhaps + * we should purge it entirely. The problem with + * the feature is that it looks like memory allocation + * failure, but is not a transient or resolvable failure. + */ +static void +set_max_length (DBusString *str, + int max_length) +{ + DBusRealString *real; + + real = (DBusRealString*) str; + + real->max_length = max_length; +} +#endif /* DBUS_BUILD_TESTS */ + /** * @ingroup DBusStringInternals * Unit test for DBusString. @@ -227,12 +266,26 @@ _dbus_string_test (void) { DBusString str; DBusString other; - int i, a, end; + int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; dbus_unichar_t ch; + + i = 0; + while (i < _DBUS_N_ELEMENTS (lens)) + { + if (!_dbus_string_init (&str)) + _dbus_assert_not_reached ("failed to init string"); + + set_max_length (&str, lens[i]); + + test_max_len (&str, lens[i]); + _dbus_string_free (&str); + + ++i; + } /* Test shortening and setting length */ i = 0; @@ -243,6 +296,8 @@ _dbus_string_test (void) if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); + set_max_length (&str, lens[i]); + if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); @@ -458,94 +513,10 @@ _dbus_string_test (void) _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); - - _dbus_string_free (&str); - _dbus_string_free (&other); - - /* Different tests are provided because different behaviours are - * implemented in _dbus_string_replace_len() in function of replacing and - * replaced lengths - */ - - if (!_dbus_string_init (&str)) - _dbus_assert_not_reached ("failed to init string"); - - if (!_dbus_string_append (&str, "Hello World")) - _dbus_assert_not_reached ("could not append to string"); - - i = _dbus_string_get_length (&str); - if (!_dbus_string_init (&other)) - _dbus_assert_not_reached ("could not init string"); - - if (!_dbus_string_append (&other, "Foo String")) - _dbus_assert_not_reached ("could not append to string"); - - a = _dbus_string_get_length (&other); - - if (!_dbus_string_replace_len (&str, 0, 6, - &other, 4, 0)) - _dbus_assert_not_reached ("could not replace 0 length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String")); - - if (!_dbus_string_replace_len (&str, 5, 6, - &other, - _dbus_string_get_length (&other), - 0)) - _dbus_assert_not_reached ("could not replace at the end"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String World")); - - if (!_dbus_string_replace_len (&str, 0, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_assert_not_reached ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo Hello String Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, 4, 12)) - _dbus_assert_not_reached ("could not replace with shorter string"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 5); - _dbus_assert (_dbus_string_equal_c_str (&other, - "Foo World Hello")); - - if (!_dbus_string_replace_len (&str, 0, 1, - &other, 0, 3)) - _dbus_assert_not_reached ("could not replace at the beginning"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World Hello")); - - if (!_dbus_string_replace_len (&str, 6, 5, - &other, - _dbus_string_get_length (&other) - 5, - 5)) - _dbus_assert_not_reached ("could not replace same length"); - - _dbus_assert (_dbus_string_get_length (&str) == i); - _dbus_assert (_dbus_string_get_length (&other) == a + 3); - _dbus_assert (_dbus_string_equal_c_str (&other, - "H World World")); - _dbus_string_free (&str); _dbus_string_free (&other); - + /* Check append/get unichar */ if (!_dbus_string_init (&str)) diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 6658abd4..ca3a670b 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -154,6 +154,7 @@ _dbus_string_init_preallocated (DBusString *str, real->len = 0; real->str[real->len] = '\0'; + real->max_length = _DBUS_STRING_MAX_MAX_LENGTH; real->constant = FALSE; real->locked = FALSE; real->invalid = FALSE; @@ -177,6 +178,25 @@ _dbus_string_init (DBusString *str) return _dbus_string_init_preallocated (str, 0); } +#ifdef DBUS_BUILD_TESTS +/* The max length thing is sort of a historical artifact + * from a feature that turned out to be dumb; perhaps + * we should purge it entirely. The problem with + * the feature is that it looks like memory allocation + * failure, but is not a transient or resolvable failure. + */ +static void +set_max_length (DBusString *str, + int max_length) +{ + DBusRealString *real; + + real = (DBusRealString*) str; + + real->max_length = max_length; +} +#endif /* DBUS_BUILD_TESTS */ + /** * Initializes a constant string. The value parameter is not copied * (should be static), and the string may never be modified. @@ -215,7 +235,7 @@ _dbus_string_init_const_len (DBusString *str, _dbus_assert (str != NULL); _dbus_assert (len == 0 || value != NULL); - _dbus_assert (len <= _DBUS_STRING_MAX_LENGTH); + _dbus_assert (len <= _DBUS_STRING_MAX_MAX_LENGTH); _dbus_assert (len >= 0); real = (DBusRealString*) str; @@ -223,6 +243,7 @@ _dbus_string_init_const_len (DBusString *str, real->str = (unsigned char*) value; real->len = len; real->allocated = real->len + _DBUS_STRING_ALLOCATION_PADDING; /* a lie, just to avoid special-case assertions... */ + real->max_length = real->len + 1; real->constant = TRUE; real->locked = TRUE; real->invalid = FALSE; @@ -315,8 +336,8 @@ reallocate_for_length (DBusRealString *real, /* at least double our old allocation to avoid O(n), avoiding * overflow */ - if (real->allocated > (_DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2) - new_allocated = _DBUS_STRING_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING; + if (real->allocated > (_DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING) / 2) + new_allocated = _DBUS_STRING_MAX_MAX_LENGTH + _DBUS_STRING_ALLOCATION_PADDING; else new_allocated = real->allocated * 2; @@ -379,7 +400,7 @@ set_length (DBusRealString *real, /* Note, we are setting the length not including nul termination */ /* exceeding max length is the same as failure to allocate memory */ - if (_DBUS_UNLIKELY (new_length > _DBUS_STRING_MAX_LENGTH)) + if (_DBUS_UNLIKELY (new_length > real->max_length)) return FALSE; else if (new_length > (real->allocated - _DBUS_STRING_ALLOCATION_PADDING) && _DBUS_UNLIKELY (!reallocate_for_length (real, new_length))) @@ -400,7 +421,7 @@ open_gap (int len, if (len == 0) return TRUE; - if (len > _DBUS_STRING_MAX_LENGTH - dest->len) + if (len > dest->max_length - dest->len) return FALSE; /* detected overflow of dest->len + len below */ if (!set_length (dest, dest->len + len)) @@ -619,6 +640,7 @@ dbus_bool_t _dbus_string_steal_data (DBusString *str, char **data_return) { + int old_max_length; DBUS_STRING_PREAMBLE (str); _dbus_assert (data_return != NULL); @@ -626,6 +648,8 @@ _dbus_string_steal_data (DBusString *str, *data_return = (char*) real->str; + old_max_length = real->max_length; + /* reset the string */ if (!_dbus_string_init (str)) { @@ -636,9 +660,64 @@ _dbus_string_steal_data (DBusString *str, return FALSE; } + real->max_length = old_max_length; + return TRUE; } +#ifdef DBUS_BUILD_TESTS +/** + * Like _dbus_string_get_data_len(), but removes the gotten data from + * the original string. The caller must free the data returned. This + * function may fail due to lack of memory, and return #FALSE. + * The returned string is nul-terminated and has length len. + * + * @todo this function is broken because on failure it + * may corrupt the source string. + * + * @param str the string + * @param data_return location to return the buffer + * @param start the start of segment to steal + * @param len the length of segment to steal + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_string_steal_data_len (DBusString *str, + char **data_return, + int start, + int len) +{ + DBusString dest; + DBUS_STRING_PREAMBLE (str); + _dbus_assert (data_return != NULL); + _dbus_assert (start >= 0); + _dbus_assert (len >= 0); + _dbus_assert (start <= real->len); + _dbus_assert (len <= real->len - start); + + if (!_dbus_string_init (&dest)) + return FALSE; + + set_max_length (&dest, real->max_length); + + if (!_dbus_string_move_len (str, start, len, &dest, 0)) + { + _dbus_string_free (&dest); + return FALSE; + } + + _dbus_warn ("Broken code in _dbus_string_steal_data_len(), see @todo, FIXME\n"); + if (!_dbus_string_steal_data (&dest, data_return)) + { + _dbus_string_free (&dest); + return FALSE; + } + + _dbus_string_free (&dest); + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ + /** * Copies the data from the string into a char* * @@ -706,6 +785,53 @@ _dbus_string_copy_to_buffer_with_nul (const DBusString *str, memcpy (buffer, real->str, real->len+1); } +#ifdef DBUS_BUILD_TESTS +/** + * Copies a segment of the string into a char* + * + * @param str the string + * @param data_return place to return the data + * @param start start index + * @param len length to copy + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_string_copy_data_len (const DBusString *str, + char **data_return, + int start, + int len) +{ + DBusString dest; + + DBUS_CONST_STRING_PREAMBLE (str); + _dbus_assert (data_return != NULL); + _dbus_assert (start >= 0); + _dbus_assert (len >= 0); + _dbus_assert (start <= real->len); + _dbus_assert (len <= real->len - start); + + if (!_dbus_string_init (&dest)) + return FALSE; + + set_max_length (&dest, real->max_length); + + if (!_dbus_string_copy_len (str, start, len, &dest, 0)) + { + _dbus_string_free (&dest); + return FALSE; + } + + if (!_dbus_string_steal_data (&dest, data_return)) + { + _dbus_string_free (&dest); + return FALSE; + } + + _dbus_string_free (&dest); + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ + /* Only have the function if we don't have the macro */ #ifndef _dbus_string_get_length /** @@ -741,7 +867,7 @@ _dbus_string_lengthen (DBusString *str, DBUS_STRING_PREAMBLE (str); _dbus_assert (additional_length >= 0); - if (_DBUS_UNLIKELY (additional_length > _DBUS_STRING_MAX_LENGTH - real->len)) + if (_DBUS_UNLIKELY (additional_length > real->max_length - real->len)) return FALSE; /* would overflow */ return set_length (real, @@ -807,7 +933,7 @@ align_insert_point_then_open_gap (DBusString *str, gap_pos = _DBUS_ALIGN_VALUE (insert_at, alignment); new_len = real->len + (gap_pos - insert_at) + gap_size; - if (_DBUS_UNLIKELY (new_len > (unsigned long) _DBUS_STRING_MAX_LENGTH)) + if (_DBUS_UNLIKELY (new_len > (unsigned long) real->max_length)) return FALSE; delta = new_len - real->len; @@ -919,7 +1045,7 @@ _dbus_string_append (DBusString *str, _dbus_assert (buffer != NULL); buffer_len = strlen (buffer); - if (buffer_len > (unsigned long) _DBUS_STRING_MAX_LENGTH) + if (buffer_len > (unsigned long) real->max_length) return FALSE; return append (real, buffer, buffer_len); @@ -1266,7 +1392,7 @@ _dbus_string_append_unichar (DBusString *str, len = 6; } - if (len > (_DBUS_STRING_MAX_LENGTH - real->len)) + if (len > (real->max_length - real->len)) return FALSE; /* real->len + len would overflow */ if (!set_length (real, real->len + len)) @@ -1415,6 +1541,9 @@ _dbus_string_copy (const DBusString *source, * Like _dbus_string_move(), but can move a segment from * the middle of the source string. * + * @todo this doesn't do anything with max_length field. + * we should probably just kill the max_length field though. + * * @param source the source string * @param start first byte of source string to move * @param len length of segment to move @@ -1509,6 +1638,15 @@ _dbus_string_copy_len (const DBusString *source, /** * Replaces a segment of dest string with a segment of source string. * + * @todo optimize the case where the two lengths are the same, and + * avoid memmoving the data in the trailing part of the string twice. + * + * @todo avoid inserting the source into dest, then deleting + * the replaced chunk of dest (which creates a potentially large + * intermediate string). Instead, extend the replaced chunk + * of dest with padding to the same size as the source chunk, + * then copy in the source bytes. + * * @param source the source string * @param start where to start copying the source string * @param len length of segment to copy @@ -1534,37 +1672,11 @@ _dbus_string_replace_len (const DBusString *source, _dbus_assert (replace_at <= real_dest->len); _dbus_assert (replace_len <= real_dest->len - replace_at); - if (len == replace_len) - { - memmove (real_dest->str + replace_at, - real_source->str + start, len); - } - else if (len < replace_len) - { - memmove (real_dest->str + replace_at, - real_source->str + start, len); - delete (real_dest, replace_at + len, - replace_len - len); - } - else - { - int diff; - - _dbus_assert (len > replace_len); - - diff = len - replace_len; - - /* First of all we check if destination string can be enlarged as - * required, then we overwrite previous bytes - */ - - if (!copy (real_source, start + replace_len, diff, - real_dest, replace_at + replace_len)) - return FALSE; + if (!copy (real_source, start, len, + real_dest, replace_at)) + return FALSE; - memmove (real_dest->str + replace_at, - real_source->str + start, replace_len); - } + delete (real_dest, replace_at + len, replace_len); return TRUE; } diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h index 2f1fe878..2f1ed31c 100644 --- a/dbus/dbus-string.h +++ b/dbus/dbus-string.h @@ -48,10 +48,11 @@ struct DBusString #endif int dummy2; /**< placeholder */ int dummy3; /**< placeholder */ - unsigned int dummy_bit1 : 1; /**< placeholder */ - unsigned int dummy_bit2 : 1; /**< placeholder */ - unsigned int dummy_bit3 : 1; /**< placeholder */ - unsigned int dummy_bits : 3; /**< placeholder */ + int dummy4; /**< placeholder */ + unsigned int dummy5 : 1; /**< placeholder */ + unsigned int dummy6 : 1; /**< placeholder */ + unsigned int dummy7 : 1; /**< placeholder */ + unsigned int dummy8 : 3; /**< placeholder */ }; #ifdef DBUS_DISABLE_ASSERT @@ -323,6 +324,7 @@ void _dbus_string_zero (DBusString *str); sizeof(_dbus_static_string_##name), \ sizeof(_dbus_static_string_##name) + \ _DBUS_STRING_ALLOCATION_PADDING, \ + sizeof(_dbus_static_string_##name), \ TRUE, TRUE, FALSE, 0 } DBUS_END_DECLS diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 9fc5f57b..98667f24 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -164,6 +164,13 @@ _dbus_open_socket (int *fd_p, } } +dbus_bool_t +_dbus_open_tcp_socket (int *fd, + DBusError *error) +{ + return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error); +} + /** * Opens a UNIX domain socket (as in the socket() call). * Does not bind the socket. @@ -174,7 +181,7 @@ _dbus_open_socket (int *fd_p, * @param error return location for an error * @returns #FALSE if error is set */ -static dbus_bool_t +dbus_bool_t _dbus_open_unix_socket (int *fd, DBusError *error) { @@ -2526,6 +2533,8 @@ void _dbus_get_current_time (long *tv_sec, long *tv_usec) { + struct timeval t; + #ifdef HAVE_MONOTONIC_CLOCK struct timespec ts; clock_gettime (CLOCK_MONOTONIC, &ts); @@ -2535,8 +2544,6 @@ _dbus_get_current_time (long *tv_sec, if (tv_usec) *tv_usec = ts.tv_nsec / 1000; #else - struct timeval t; - gettimeofday (&t, NULL); if (tv_sec) @@ -3500,10 +3507,10 @@ _dbus_lookup_launchd_socket (DBusString *socket_path, #endif } -#ifdef DBUS_ENABLE_LAUNCHD static dbus_bool_t _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) { +#ifdef DBUS_ENABLE_LAUNCHD dbus_bool_t valid_socket; DBusString socket_path; @@ -3545,8 +3552,12 @@ _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) _dbus_string_free(&socket_path); return TRUE; -} +#else + dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, + "can't lookup session address from launchd; launchd support not compiled in"); + return FALSE; #endif +} /** * Determines the address of the session bus by querying a diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h index 200ec8a3..d7022b07 100644 --- a/dbus/dbus-sysdeps-unix.h +++ b/dbus/dbus-sysdeps-unix.h @@ -63,6 +63,8 @@ _dbus_write_two (int fd, int start2, int len2); +dbus_bool_t _dbus_open_unix_socket (int *fd, + DBusError *error); int _dbus_connect_unix_socket (const char *path, dbus_bool_t abstract, DBusError *error); diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index a1915cb3..d57e6aad 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -389,6 +389,7 @@ _dbus_request_file_descriptor_limit (unsigned int limit) #ifdef HAVE_SETRLIMIT struct rlimit lim; struct rlimit target_lim; + unsigned int current_limit; /* No point to doing this practically speaking * if we're not uid 0. We expect the system diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 0694de93..aea704d2 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -820,6 +820,9 @@ _dbus_full_duplex_pipe (int *fd1, struct sockaddr_in saddr; int len; u_long arg; + fd_set read_set, write_set; + struct timeval tv; + int res; _dbus_win_startup_winsock (); @@ -955,6 +958,7 @@ _dbus_poll (DBusPollFD *fds, msgp += sprintf (msgp, "WSAEventSelect: to=%d\n\t", timeout_milliseconds); for (i = 0; i < n_fds; i++) { + static dbus_bool_t warned = FALSE; DBusPollFD *fdp = &fds[i]; @@ -1092,6 +1096,7 @@ _dbus_poll (DBusPollFD *fds, msgp += sprintf (msgp, "select: to=%d\n\t", timeout_milliseconds); for (i = 0; i < n_fds; i++) { + static dbus_bool_t warned = FALSE; DBusPollFD *fdp = &fds[i]; @@ -2618,7 +2623,9 @@ dbus_bool_t _dbus_daemon_is_session_bus_address_published (const char *scope) { HANDLE lock; + HANDLE mutex; DBusString mutex_name; + DWORD ret; if (!_dbus_get_mutex_name(&mutex_name,scope)) { @@ -2663,6 +2670,8 @@ _dbus_daemon_publish_session_bus_address (const char* address, const char *scope { HANDLE lock; char *shared_addr = NULL; + DWORD ret; + char addressInfo[1024]; DBusString shm_name; DBusString mutex_name; @@ -3151,6 +3160,8 @@ dbus_bool_t _dbus_get_install_root(char *prefix, int len) { //To find the prefix, we cut the filename and also \bin\ if present + char* p = 0; + int i; DWORD pathLength; char *lastSlash; SetLastError( 0 ); @@ -3304,6 +3315,7 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory, { DBusString homedir; DBusString dotdir; + dbus_uid_t uid; const char *homepath; const char *homedrive; diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index f8438f43..d4883c1b 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -125,6 +125,8 @@ typedef unsigned long dbus_gid_t; * */ +dbus_bool_t _dbus_open_tcp_socket (int *fd, + DBusError *error); dbus_bool_t _dbus_close_socket (int fd, DBusError *error); int _dbus_read_socket (int fd, diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index b2eeb724..1fbaf8c8 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -150,6 +150,8 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir, const char *speci run_test ("marshal-validate", specific_test, _dbus_marshal_validate_test); + run_test ("marshal-header", specific_test, _dbus_marshal_header_test); + run_data_test ("message", specific_test, _dbus_message_test, test_data_dir); run_test ("hash", specific_test, _dbus_hash_test); @@ -170,6 +172,8 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir, const char *speci run_data_test ("auth", specific_test, _dbus_auth_test, test_data_dir); + run_data_test ("pending-call", specific_test, _dbus_pending_call_test, test_data_dir); + printf ("%s: completed successfully\n", "dbus-test"); #else printf ("Not compiled with unit tests, not running any\n"); diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index d97d142a..0238b0ce 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -29,10 +29,12 @@ #include <dbus/dbus-marshal-validate.h> dbus_bool_t _dbus_hash_test (void); +dbus_bool_t _dbus_dict_test (void); dbus_bool_t _dbus_list_test (void); dbus_bool_t _dbus_marshal_test (void); dbus_bool_t _dbus_marshal_recursive_test (void); dbus_bool_t _dbus_marshal_byteswap_test (void); +dbus_bool_t _dbus_marshal_header_test (void); dbus_bool_t _dbus_marshal_validate_test (void); dbus_bool_t _dbus_misc_test (void); dbus_bool_t _dbus_signature_test (void); @@ -42,6 +44,7 @@ dbus_bool_t _dbus_address_test (void); dbus_bool_t _dbus_server_test (void); dbus_bool_t _dbus_message_test (const char *test_data_dir); dbus_bool_t _dbus_auth_test (const char *test_data_dir); +dbus_bool_t _dbus_md5_test (void); dbus_bool_t _dbus_sha_test (const char *test_data_dir); dbus_bool_t _dbus_keyring_test (void); dbus_bool_t _dbus_data_slot_test (void); @@ -50,6 +53,7 @@ dbus_bool_t _dbus_spawn_test (const char *test_data_dir); dbus_bool_t _dbus_userdb_test (const char *test_data_dir); dbus_bool_t _dbus_memory_test (void); dbus_bool_t _dbus_object_tree_test (void); +dbus_bool_t _dbus_pending_call_test (const char *test_data_dir); dbus_bool_t _dbus_credentials_test (const char *test_data_dir); void dbus_internal_do_not_use_run_tests (const char *test_data_dir, diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 0673a8ce..1d4c2bf7 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -677,8 +677,8 @@ do_writing (DBusTransport *transport) _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); _dbus_string_compact (&socket_transport->encoded_outgoing, 2048); - _dbus_connection_message_sent_unlocked (transport->connection, - message); + _dbus_connection_message_sent (transport->connection, + message); } } } @@ -1278,10 +1278,8 @@ _dbus_transport_new_for_socket (int fd, return (DBusTransport*) socket_transport; failed_4: - _dbus_watch_invalidate (socket_transport->read_watch); _dbus_watch_unref (socket_transport->read_watch); failed_3: - _dbus_watch_invalidate (socket_transport->write_watch); _dbus_watch_unref (socket_transport->write_watch); failed_2: _dbus_string_free (&socket_transport->encoded_incoming); diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index f743d010..ba6bd4b4 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -72,16 +72,12 @@ live_messages_notify (DBusCounter *counter, _dbus_verbose ("Unix FD counter value is now %d\n", (int) _dbus_counter_get_unix_fd_value (counter)); #endif - + /* disable or re-enable the read watch for the transport if * required. */ if (transport->vtable->live_messages_changed) - { - _dbus_connection_lock (transport->connection); - (* transport->vtable->live_messages_changed) (transport); - _dbus_connection_unlock (transport->connection); - } + (* transport->vtable->live_messages_changed) (transport); _dbus_transport_unref (transport); } @@ -1148,13 +1144,6 @@ _dbus_transport_queue_messages (DBusTransport *transport) } else { - /* We didn't call the notify function when we added the counter, so - * catch up now. Since we have the connection's lock, it's desirable - * that we bypass the notify function and call this virtual method - * directly. */ - if (transport->vtable->live_messages_changed) - (* transport->vtable->live_messages_changed) (transport); - /* pass ownership of link and message ref to connection */ _dbus_connection_queue_received_message_link (transport->connection, link); @@ -1493,26 +1482,4 @@ _dbus_transport_set_allow_anonymous (DBusTransport *transport, transport->allow_anonymous = value != FALSE; } -#ifdef DBUS_ENABLE_STATS -void -_dbus_transport_get_stats (DBusTransport *transport, - dbus_uint32_t *queue_bytes, - dbus_uint32_t *queue_fds, - dbus_uint32_t *peak_queue_bytes, - dbus_uint32_t *peak_queue_fds) -{ - if (queue_bytes != NULL) - *queue_bytes = _dbus_counter_get_size_value (transport->live_messages); - - if (queue_fds != NULL) - *queue_fds = _dbus_counter_get_unix_fd_value (transport->live_messages); - - if (peak_queue_bytes != NULL) - *peak_queue_bytes = _dbus_counter_get_peak_size_value (transport->live_messages); - - if (peak_queue_fds != NULL) - *peak_queue_fds = _dbus_counter_get_peak_unix_fd_value (transport->live_messages); -} -#endif /* DBUS_ENABLE_STATS */ - /** @} */ diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h index 4b821517..0db048a2 100644 --- a/dbus/dbus-transport.h +++ b/dbus/dbus-transport.h @@ -97,12 +97,6 @@ dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport void _dbus_transport_set_allow_anonymous (DBusTransport *transport, dbus_bool_t value); -/* if DBUS_ENABLE_STATS */ -void _dbus_transport_get_stats (DBusTransport *transport, - dbus_uint32_t *queue_bytes, - dbus_uint32_t *queue_fds, - dbus_uint32_t *peak_queue_bytes, - dbus_uint32_t *peak_queue_fds); DBUS_END_DECLS diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c index b9f4ac23..8d759e5e 100644 --- a/dbus/dbus-watch.c +++ b/dbus/dbus-watch.c @@ -50,7 +50,6 @@ struct DBusWatch void *data; /**< Application data. */ DBusFreeFunction free_data_function; /**< Free the application data. */ unsigned int enabled : 1; /**< Whether it's enabled. */ - unsigned int oom_last_time : 1; /**< Whether it was OOM last time. */ }; dbus_bool_t @@ -59,19 +58,6 @@ _dbus_watch_get_enabled (DBusWatch *watch) return watch->enabled; } -dbus_bool_t -_dbus_watch_get_oom_last_time (DBusWatch *watch) -{ - return watch->oom_last_time; -} - -void -_dbus_watch_set_oom_last_time (DBusWatch *watch, - dbus_bool_t oom) -{ - watch->oom_last_time = oom; -} - /** * Creates a new DBusWatch. Used to add a file descriptor to be polled * by a main loop. @@ -143,9 +129,6 @@ _dbus_watch_unref (DBusWatch *watch) watch->refcount -= 1; if (watch->refcount == 0) { - if (watch->fd != -1) - _dbus_warn ("this watch should have been invalidated"); - dbus_watch_set_data (watch, NULL, NULL); /* call free_data_function */ if (watch->free_handler_data_function) diff --git a/dbus/dbus-watch.h b/dbus/dbus-watch.h index dd23b862..fa953ec1 100644 --- a/dbus/dbus-watch.h +++ b/dbus/dbus-watch.h @@ -76,10 +76,6 @@ void _dbus_watch_list_toggle_watch (DBusWatchList *watch_li dbus_bool_t enabled); dbus_bool_t _dbus_watch_get_enabled (DBusWatch *watch); -dbus_bool_t _dbus_watch_get_oom_last_time (DBusWatch *watch); -void _dbus_watch_set_oom_last_time (DBusWatch *watch, - dbus_bool_t oom); - /** @} */ DBUS_END_DECLS diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 7280cf17..836b64b7 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -6,8 +6,8 @@ <article id="index"> <articleinfo> <title>D-Bus Specification</title> - <releaseinfo>Version 0.19</releaseinfo> - <date>UNRELEASED</date> + <releaseinfo>Version 0.15</releaseinfo> + <date>3 November 2010</date> <authorgroup> <author> <firstname>Havoc</firstname> @@ -49,26 +49,6 @@ </address> </affiliation> </author> - <author> - <firstname>Simon</firstname> - <surname>McVittie</surname> - <affiliation> - <orgname>Collabora Ltd.</orgname> - <address> - <email>simon.mcvittie@collabora.co.uk</email> - </address> - </affiliation> - </author> - <author> - <firstname>David</firstname> - <surname>Zeuthen</surname> - <affiliation> - <orgname>Red Hat, Inc.</orgname> - <address> - <email>davidz@redhat.com</email> - </address> - </affiliation> - </author> </authorgroup> <revhistory> <revision> @@ -78,27 +58,6 @@ <revremark></revremark> </revision> <revision> - <revnumber>0.18</revnumber> - <date>29 July 2011</date> - <authorinitials>smcv</authorinitials> - <revremark>define eavesdropping, unicast, broadcast; add eavesdrop - match keyword; promote type system to a top-level section</revremark> - </revision> - <revision> - <revnumber>0.17</revnumber> - <date>1 June 2011</date> - <authorinitials>smcv/davidz</authorinitials> - <revremark>define ObjectManager; reserve extra pseudo-type-codes used - by GVariant</revremark> - </revision> - <revision> - <revnumber>0.16</revnumber> - <date>11 April 2011</date> - <authorinitials></authorinitials> - <revremark>add path_namespace, arg0namespace; argNpath matches object - paths</revremark> - </revision> - <revision> <revnumber>0.15</revnumber> <date>3 November 2010</date> <authorinitials></authorinitials> @@ -271,13 +230,27 @@ </sect1> - <sect1 id="type-system"> - <title>Type System</title> + <sect1 id="message-protocol"> + <title>Message Protocol</title> + + <para> + A <firstterm>message</firstterm> consists of a + <firstterm>header</firstterm> and a <firstterm>body</firstterm>. If you + think of a message as a package, the header is the address, and the body + contains the package contents. The message delivery system uses the header + information to figure out where to send the message and how to interpret + it; the recipient interprets the body of the message. + </para> + + <para> + The body of the message is made up of zero or more + <firstterm>arguments</firstterm>, which are typed values, such as an + integer or a byte array. + </para> <para> - D-Bus has a type system, in which values of various types can be - serialized into a sequence of bytes referred to as the - <firstterm>wire format</firstterm> in a standard way. + Both header and body use the same type system and format for + serializing data. Each type of value has a wire format. Converting a value from some other representation into the wire format is called <firstterm>marshaling</firstterm> and converting it back from the wire format is <firstterm>unmarshaling</firstterm>. @@ -498,10 +471,7 @@ </row><row> <entry><literal>STRUCT</literal></entry> <entry>114 (ASCII 'r'), 40 (ASCII '('), 41 (ASCII ')')</entry> - <entry>Struct; type code 114 'r' is reserved for use in - bindings and implementations to represent the general - concept of a struct, and must not appear in signatures - used on D-Bus.</entry> + <entry>Struct</entry> </row><row> <entry><literal>VARIANT</literal></entry> <entry>118 (ASCII 'v') </entry> @@ -509,48 +479,12 @@ </row><row> <entry><literal>DICT_ENTRY</literal></entry> <entry>101 (ASCII 'e'), 123 (ASCII '{'), 125 (ASCII '}') </entry> - <entry>Entry in a dict or map (array of key-value pairs). - Type code 101 'e' is reserved for use in bindings and - implementations to represent the general concept of a - dict or dict-entry, and must not appear in signatures - used on D-Bus.</entry> + <entry>Entry in a dict or map (array of key-value pairs)</entry> </row><row> <entry><literal>UNIX_FD</literal></entry> <entry>104 (ASCII 'h')</entry> <entry>Unix file descriptor</entry> </row> - <row> - <entry>(reserved)</entry> - <entry>109 (ASCII 'm')</entry> - <entry>Reserved for <ulink - url="https://bugs.freedesktop.org/show_bug.cgi?id=27857">a - 'maybe' type compatible with the one in GVariant</ulink>, - and must not appear in signatures used on D-Bus until - specified here</entry> - </row> - <row> - <entry>(reserved)</entry> - <entry>42 (ASCII '*')</entry> - <entry>Reserved for use in bindings/implementations to - represent any <firstterm>single complete type</firstterm>, - and must not appear in signatures used on D-Bus.</entry> - </row> - <row> - <entry>(reserved)</entry> - <entry>63 (ASCII '?')</entry> - <entry>Reserved for use in bindings/implementations to - represent any <firstterm>basic type</firstterm>, and must - not appear in signatures used on D-Bus.</entry> - </row> - <row> - <entry>(reserved)</entry> - <entry>64 (ASCII '@'), 38 (ASCII '&'), - 94 (ASCII '^')</entry> - <entry>Reserved for internal use by bindings/implementations, - and must not appear in signatures used on D-Bus. - GVariant uses these type-codes to encode calling - conventions.</entry> - </row> </tbody> </tgroup> </informaltable> @@ -836,31 +770,6 @@ </sect2> - </sect1> - - <sect1 id="message-protocol"> - <title>Message Protocol</title> - - <para> - A <firstterm>message</firstterm> consists of a - <firstterm>header</firstterm> and a <firstterm>body</firstterm>. If you - think of a message as a package, the header is the address, and the body - contains the package contents. The message delivery system uses the header - information to figure out where to send the message and how to interpret - it; the recipient interprets the body of the message. - </para> - - <para> - The body of the message is made up of zero or more - <firstterm>arguments</firstterm>, which are typed values, such as an - integer or a byte array. - </para> - - <para> - Both header and body use the D-Bus <link linkend="type-system">type - system</link> and format for serializing data. - </para> - <sect2 id="message-protocol-messages"> <title>Message Format</title> @@ -3082,114 +2991,6 @@ annotation. </para> </sect2> - - <sect2 id="standard-interfaces-objectmanager"> - <title><literal>org.freedesktop.DBus.ObjectManager</literal></title> - <para> - An API can optionally make use of this interface for one or - more sub-trees of objects. The root of each sub-tree implements - this interface so other applications can get all objects, - interfaces and properties in a single method call. It is - appropriate to use this interface if users of the tree of - objects are expected to be interested in all interfaces of all - objects in the tree; a more granular API should be used if - users of the objects are expected to be interested in a small - subset of the objects, a small subset of their interfaces, or - both. - </para> - <para> - The method that applications can use to get all objects and - properties is <literal>GetManagedObjects</literal>: - </para> - <para> - <programlisting> - org.freedesktop.DBus.ObjectManager.GetManagedObjects (out DICT<OBJPATH,DICT<STRING,DICT<STRING,VARIANT>>> objpath_interfaces_and_properties); - </programlisting> - </para> - <para> - The return value of this method is a dict whose keys are - object paths. All returned object paths are children of the - object path implementing this interface, i.e. their object - paths start with the ObjectManager's object path plus '/'. - </para> - <para> - Each value is a dict whose keys are interfaces names. Each - value in this inner dict is the same dict that would be - returned by the <link - linkend="standard-interfaces-properties">org.freedesktop.DBus.Properties.GetAll()</link> - method for that combination of object path and interface. If - an interface has no properties, the empty dict is returned. - </para> - <para> - Changes are emitted using the following two signals: - </para> - <para> - <programlisting> - org.freedesktop.DBus.ObjectManager.InterfacesAdded (OBJPATH object_path, - DICT<STRING,DICT<STRING,VARIANT>> interfaces_and_properties); - org.freedesktop.DBus.ObjectManager.InterfacesRemoved (OBJPATH object_path, - ARRAY<STRING> interfaces); - </programlisting> - </para> - <para> - The <literal>InterfacesAdded</literal> signal is emitted when - either a new object is added or when an existing object gains - one or more interfaces. The - <literal>InterfacesRemoved</literal> signal is emitted - whenever an object is removed or it loses one or more - interfaces. The second parameter of the - <literal>InterfacesAdded</literal> signal contains a dict with - the interfaces and properties (if any) that have been added to - the given object path. Similarly, the second parameter of the - <literal>InterfacesRemoved</literal> signal contains an array - of the interfaces that were removed. Note that changes on - properties on existing interfaces are not reported using this - interface - an application should also monitor the existing <link - linkend="standard-interfaces-properties">PropertiesChanged</link> - signal on each object. - </para> - <para> - Applications SHOULD NOT export objects that are children of an - object (directly or otherwise) implementing this interface but - which are not returned in the reply from the - <literal>GetManagedObjects()</literal> method of this - interface on the given object. - </para> - <para> - The intent of the <literal>ObjectManager</literal> interface - is to make it easy to write a robust client - implementation. The trivial client implementation only needs - to make two method calls: - </para> - <para> - <programlisting> - org.freedesktop.DBus.AddMatch (bus_proxy, - "type='signal',name='org.example.App',path_namespace='/org/example/App'"); - objects = org.freedesktop.DBus.ObjectManager.GetManagedObjects (app_proxy); - </programlisting> - </para> - <para> - on the message bus and the remote application's - <literal>ObjectManager</literal>, respectively. Whenever a new - remote object is created (or an existing object gains a new - interface), the <literal>InterfacesAdded</literal> signal is - emitted, and since this signal contains all properties for the - interfaces, no calls to the - <literal>org.freedesktop.Properties</literal> interface on the - remote object are needed. Additionally, since the initial - <literal>AddMatch()</literal> rule already includes signal - messages from the newly created child object, no new - <literal>AddMatch()</literal> call is needed. - </para> - - <para> - <emphasis> - The <literal>org.freedesktop.DBus.ObjectManager</literal> - interface was added in version 0.17 of the D-Bus - specification. - </emphasis> - </para> - </sect2> </sect1> <sect1 id="introspection-format"> @@ -3392,10 +3193,39 @@ </para> <para> - Applications may send <firstterm>unicast messages</firstterm> to - a specific recipient or to the message bus itself, or - <firstterm>broadcast messages</firstterm> to all interested recipients. - See <xref linkend="message-bus-routing"/> for details. + Messages may have a <literal>DESTINATION</literal> field (see <xref + linkend="message-protocol-header-fields"/>). If the + <literal>DESTINATION</literal> field is present, it specifies a message + recipient by name. Method calls and replies normally specify this field. + The message bus must send messages (of any type) with the + <literal>DESTINATION</literal> field set to the specified recipient, + regardless of whether the recipient has set up a match rule matching + the message. + </para> + + <para> + Signals normally do not specify a destination; they are sent to all + applications with <firstterm>message matching rules</firstterm> that + match the message. + </para> + + <para> + When the message bus receives a method call, if the + <literal>DESTINATION</literal> field is absent, the call is taken to be + a standard one-to-one message and interpreted by the message bus + itself. For example, sending an + <literal>org.freedesktop.DBus.Peer.Ping</literal> message with no + <literal>DESTINATION</literal> will cause the message bus itself to + reply to the ping immediately; the message bus will not make this + message visible to other applications. + </para> + + <para> + Continuing the <literal>org.freedesktop.DBus.Peer.Ping</literal> example, if + the ping message were sent with a <literal>DESTINATION</literal> name of + <literal>com.yoyodyne.Screensaver</literal>, then the ping would be + forwarded, and the Yoyodyne Corporation screensaver application would be + expected to reply to the ping. </para> </sect2> @@ -3829,122 +3659,20 @@ <sect2 id="message-bus-routing"> <title>Message Bus Message Routing</title> - - <para> - Messages may have a <literal>DESTINATION</literal> field (see <xref - linkend="message-protocol-header-fields"/>), resulting in a - <firstterm>unicast message</firstterm>. If the - <literal>DESTINATION</literal> field is present, it specifies a message - recipient by name. Method calls and replies normally specify this field. - The message bus must send messages (of any type) with the - <literal>DESTINATION</literal> field set to the specified recipient, - regardless of whether the recipient has set up a match rule matching - the message. - </para> - - <para> - When the message bus receives a signal, if the - <literal>DESTINATION</literal> field is absent, it is considered to - be a <firstterm>broadcast signal</firstterm>, and is sent to all - applications with <firstterm>message matching rules</firstterm> that - match the message. Most signal messages are broadcasts. - </para> - <para> - Unicast signal messages (those with a <literal>DESTINATION</literal> - field) are not commonly used, but they are treated like any unicast - message: they are delivered to the specified receipient, - regardless of its match rules. One use for unicast signals is to - avoid a race condition in which a signal is emitted before the intended - recipient can call <xref linkend="bus-messages-add-match"/> to - receive that signal: if the signal is sent directly to that recipient - using a unicast message, it does not need to add a match rule at all, - and there is no race condition. Another use for unicast signals, - on message buses whose security policy prevents eavesdropping, is to - send sensitive information which should only be visible to one - recipient. + FIXME </para> - - <para> - When the message bus receives a method call, if the - <literal>DESTINATION</literal> field is absent, the call is taken to be - a standard one-to-one message and interpreted by the message bus - itself. For example, sending an - <literal>org.freedesktop.DBus.Peer.Ping</literal> message with no - <literal>DESTINATION</literal> will cause the message bus itself to - reply to the ping immediately; the message bus will not make this - message visible to other applications. - </para> - - <para> - Continuing the <literal>org.freedesktop.DBus.Peer.Ping</literal> example, if - the ping message were sent with a <literal>DESTINATION</literal> name of - <literal>com.yoyodyne.Screensaver</literal>, then the ping would be - forwarded, and the Yoyodyne Corporation screensaver application would be - expected to reply to the ping. - </para> - - <para> - Message bus implementations may impose a security policy which - prevents certain messages from being sent or received. - When a message cannot be sent or received due to a security - policy, the message bus should send an error reply, unless the - original message had the <literal>NO_REPLY</literal> flag. - </para> - - <sect3 id="message-bus-routing-eavesdropping"> - <title>Eavesdropping</title> - <para> - Receiving a unicast message whose <literal>DESTINATION</literal> - indicates a different recipient is called - <firstterm>eavesdropping</firstterm>. On a message bus which acts as - a security boundary (like the standard system bus), the security - policy should usually prevent eavesdropping, since unicast messages - are normally kept private and may contain security-sensitive - information. - </para> - - <para> - Eavesdropping is mainly useful for debugging tools, such as - the <literal>dbus-monitor</literal> tool in the reference - implementation of D-Bus. Tools which eavesdrop on the message bus - should be careful to avoid sending a reply or error in response to - messages intended for a different client. - </para> - - <para> - Clients may attempt to eavesdrop by adding match rules - (see <xref linkend="message-bus-routing-match-rules"/>) containing - the <literal>eavesdrop='true'</literal> match. If the message bus' - security policy does not allow eavesdropping, the match rule can - still be added, but will not have any practical effect. For - compatibility with older message bus implementations, if adding such - a match rule results in an error reply, the client may fall back to - adding the same rule with the <literal>eavesdrop</literal> match - omitted. - </para> - </sect3> - <sect3 id="message-bus-routing-match-rules"> <title>Match Rules</title> <para> - An important part of the message bus routing protocol is match - rules. Match rules describe the messages that should be sent to a - client, based on the contents of the message. Broadcast signals - are only sent to clients which have a suitable match rule: this - avoids waking up client processes to deal with signals that are - not relevant to that client. - </para> - <para> - Messages that list a client as their <literal>DESTINATION</literal> - do not need to match the client's match rules, and are sent to that - client regardless. As a result, match rules are mainly used to - receive a subset of broadcast signals. - </para> - <para> - Match rules can also be used for eavesdropping - (see <xref linkend="message-bus-routing-eavesdropping"/>), - if the security policy of the message bus allows it. + An important part of the message bus routing protocol is match + rules. Match rules describe what messages can be sent to a client + based on the contents of the message. When a message is routed + through the bus it is compared to clients' match rules. If any + of the rules match, the message is dispatched to the client. + If none of the rules match the message never leaves the bus. This + is an effective way to control traffic over the bus and to make sure + only relevant message need to be processed by the client. </para> <para> Match rules are added using the AddMatch bus method @@ -4004,43 +3732,6 @@ path match is path='/org/freedesktop/Hal/Manager'</entry> </row> <row> - <entry><literal>path_namespace</literal></entry> - <entry>An object path</entry> - <entry> - <para> - Matches messages which are sent from or to an - object for which the object path is either the - given value, or that value followed by one or - more path components. - </para> - - <para> - For example, - <literal>path_namespace='/com/example/foo'</literal> - would match signals sent by - <literal>/com/example/foo</literal> - or by - <literal>/com/example/foo/bar</literal>, - but not by - <literal>/com/example/foobar</literal>. - </para> - - <para> - Using both <literal>path</literal> and - <literal>path_namespace</literal> in the same match - rule is not allowed. - </para> - - <para> - <emphasis> - This match key was added in version 0.16 of the - D-Bus specification and implemented by the bus - daemon in dbus 1.5.0 and later. - </emphasis> - </para> - </entry> - </row> - <row> <entry><literal>destination</literal></entry> <entry>A unique name (see <xref linkend="term-unique-name"/>)</entry> <entry>Matches messages which are being sent to the given unique name. An @@ -4050,99 +3741,24 @@ <entry><literal>arg[0, 1, 2, 3, ...]</literal></entry> <entry>Any string</entry> <entry>Arg matches are special and are used for further restricting the - match based on the arguments in the body of a message. Only arguments of type - STRING can be matched in this way. An example of an argument match + match based on the arguments in the body of a message. As of this time + only string arguments can be matched. An example of an argument match would be arg3='Foo'. Only argument indexes from 0 to 63 should be accepted.</entry> </row> <row> <entry><literal>arg[0, 1, 2, 3, ...]path</literal></entry> <entry>Any string</entry> - <entry> - <para>Argument path matches provide a specialised form of wildcard matching for - path-like namespaces. They can match arguments whose type is either STRING or - OBJECT_PATH. As with normal argument matches, - if the argument is exactly equal to the string given in the match - rule then the rule is satisfied. Additionally, there is also a - match when either the string given in the match rule or the - appropriate message argument ends with '/' and is a prefix of the - other. An example argument path match is arg0path='/aa/bb/'. This - would match messages with first arguments of '/', '/aa/', - '/aa/bb/', '/aa/bb/cc/' and '/aa/bb/cc'. It would not match - messages with first arguments of '/aa/b', '/aa' or even '/aa/bb'.</para> - - <para>This is intended for monitoring “directories” in file system-like - hierarchies, as used in the <citetitle>dconf</citetitle> configuration - system. An application interested in all nodes in a particular hierarchy would - monitor <literal>arg0path='/ca/example/foo/'</literal>. Then the service could - emit a signal with zeroth argument <literal>"/ca/example/foo/bar"</literal> to - represent a modification to the “bar” property, or a signal with zeroth - argument <literal>"/ca/example/"</literal> to represent atomic modification of - many properties within that directory, and the interested application would be - notified in both cases.</para> - <para> - <emphasis> - This match key was added in version 0.12 of the - D-Bus specification, implemented for STRING - arguments by the bus daemon in dbus 1.2.0 and later, - and implemented for OBJECT_PATH arguments in dbus 1.5.0 - and later. - </emphasis> - </para> - </entry> - </row> - <row> - <entry><literal>arg0namespace</literal></entry> - <entry>Like a bus name, except that the string is not - required to contain a '.' (period)</entry> - <entry> - <para>Match messages whose first argument is of type STRING, and is a bus name - or interface name within the specified namespace. This is primarily intended - for watching name owner changes for a group of related bus names, rather than - for a single name or all name changes.</para> - - <para>Because every valid interface name is also a valid - bus name, this can also be used for messages whose - first argument is an interface name.</para> - - <para>For example, the match rule - <literal>member='NameOwnerChanged',arg0namespace='com.example.backend'</literal> - matches name owner changes for bus names such as - <literal>com.example.backend.foo</literal>, - <literal>com.example.backend.foo.bar</literal>, and - <literal>com.example.backend</literal> itself.</para> - - <para>See also <xref linkend='bus-messages-name-owner-changed'/>.</para> - <para> - <emphasis> - This match key was added in version 0.16 of the - D-Bus specification and implemented by the bus - daemon in dbus 1.5.0 and later. - </emphasis> - </para> - </entry> - </row> - <row> - <entry><literal>eavesdrop</literal></entry> - <entry><literal>'true'</literal>, <literal>'false'</literal></entry> - <entry>Since D-Bus 1.5.6, match rules do not - match messages which have a <literal>DESTINATION</literal> - field unless the match rule specifically - requests this - (see <xref linkend="message-bus-routing-eavesdropping"/>) - by specifying <literal>eavesdrop='true'</literal> - in the match rule. <literal>eavesdrop='false'</literal> - restores the default behaviour. Messages are - delivered to their <literal>DESTINATION</literal> - regardless of match rules, so this match does not - affect normal delivery of unicast messages. - If the message bus has a security policy which forbids - eavesdropping, this match may still be used without error, - but will not have any practical effect. - In older versions of D-Bus, this match was not allowed - in match rules, and all match rules behaved as if - <literal>eavesdrop='true'</literal> had been used. - </entry> + <entry>Argument path matches provide a specialised form of wildcard + matching for path-like namespaces. As with normal argument matches, + if the argument is exactly equal to the string given in the match + rule then the rule is satisfied. Additionally, there is also a + match when either the string given in the match rule or the + appropriate message argument ends with '/' and is a prefix of the + other. An example argument path match is arg0path='/aa/bb/'. This + would match messages with first arguments of '/', '/aa/', + '/aa/bb/', '/aa/bb/cc/' and '/aa/bb/cc'. It would not match + messages with first arguments of '/aa/b', '/aa' or even '/aa/bb'.</entry> </row> </tbody> </tgroup> diff --git a/test/Makefile.am b/test/Makefile.am index 2eca473e..b890c638 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,29 +4,9 @@ SUBDIRS= . name-test DIST_SUBDIRS=name-test -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(GLIB_CFLAGS) \ - $(DBUS_GLIB_CFLAGS) \ - $(NULL) - -# improve backtraces from test stuff -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ +INCLUDES=-I$(top_srcdir) $(DBUS_TEST_CFLAGS) -static_cppflags = \ - $(AM_CPPFLAGS) \ - -DDBUS_STATIC_BUILD \ - $(NULL) - -libdbus_testutils_la_CPPFLAGS = \ - $(static_cppflags) -libdbus_testutils_la_SOURCES = \ - test-utils.c \ - test-utils.h \ - $(NULL) -libdbus_testutils_la_LIBADD = \ - $(top_builddir)/dbus/libdbus-internal.la \ - $(NULL) +libdbus_testutils_la_SOURCES = test-utils.h test-utils.c noinst_LTLIBRARIES = libdbus-testutils.la @@ -72,26 +52,58 @@ endif !DBUS_BUILD_TESTS noinst_PROGRAMS= $(TEST_BINARIES) -test_service_CPPFLAGS = $(static_cppflags) -test_service_LDADD = libdbus-testutils.la -test_names_CPPFLAGS = $(static_cppflags) -test_names_LDADD = libdbus-testutils.la -## break_loader_CPPFLAGS = $(static_cppflags) -## break_loader_LDADD = $(top_builddir)/dbus/libdbus-internal.la -test_shell_service_CPPFLAGS = $(static_cppflags) -test_shell_service_LDADD = libdbus-testutils.la -shell_test_CPPFLAGS = $(static_cppflags) -shell_test_LDADD = libdbus-testutils.la -spawn_test_CPPFLAGS = $(static_cppflags) -spawn_test_LDADD = $(top_builddir)/dbus/libdbus-internal.la +test_service_SOURCES= \ + test-service.c + +test_names_SOURCES= \ + test-names.c + +##break_loader_SOURCES= \ +## break-loader.c + +test_shell_service_SOURCES = \ + test-shell-service.c + +shell_test_SOURCES= \ + shell-test.c + +spawn_test_SOURCES= \ + spawn-test.c + +test_exit_SOURCES = \ + test-exit.c + +test_segfault_SOURCES = \ + test-segfault.c + +test_sleep_forever_SOURCES = \ + test-sleep-forever.c + +# This assumes that most tests will be linked to libdbus-internal; +# tests linked to only the public libdbus have their own CPPFLAGS. +AM_CPPFLAGS=-DDBUS_STATIC_BUILD +TEST_LIBS=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_TEST_LIBS) + +test_service_LDADD=libdbus-testutils.la $(TEST_LIBS) +test_service_LDFLAGS=@R_DYNAMIC_LDFLAG@ +test_names_LDADD=libdbus-testutils.la $(TEST_LIBS) +test_names_LDFLAGS=@R_DYNAMIC_LDFLAG@ +## break_loader_LDADD= $(TEST_LIBS) +## break_loader_LDFLAGS=@R_DYNAMIC_LDFLAG@ +test_shell_service_LDADD=libdbus-testutils.la $(TEST_LIBS) +test_shell_service_LDFLAGS=@R_DYNAMIC_LDFLAG@ +shell_test_LDADD=libdbus-testutils.la $(TEST_LIBS) +shell_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ +spawn_test_LDADD=$(TEST_LIBS) +spawn_test_LDFLAGS=@R_DYNAMIC_LDFLAG@ test_refs_SOURCES = internals/refs.c -test_refs_CPPFLAGS = $(static_cppflags) -test_refs_LDADD = libdbus-testutils.la $(GLIB_LIBS) +test_refs_CPPFLAGS = -DDBUS_STATIC_BUILD $(GLIB_CFLAGS) +test_refs_LDADD = libdbus-testutils.la $(GLIB_LIBS) $(TEST_LIBS) test_syslog_SOURCES = internals/syslog.c -test_syslog_CPPFLAGS = $(static_cppflags) -test_syslog_LDADD = libdbus-testutils.la $(GLIB_LIBS) +test_syslog_CPPFLAGS = -DDBUS_STATIC_BUILD $(GLIB_CFLAGS) +test_syslog_LDADD = libdbus-testutils.la $(GLIB_LIBS) $(TEST_LIBS) EXTRA_DIST = dbus-test-runner @@ -102,7 +114,6 @@ testexec_PROGRAMS = installable_tests = \ test-corrupt \ test-dbus-daemon \ - test-dbus-daemon-eavesdrop \ test-loopback \ test-marshal \ test-refs \ @@ -125,33 +136,36 @@ TESTS_ENVIRONMENT = \ $(NULL) test_corrupt_SOURCES = corrupt.c +test_corrupt_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) +test_corrupt_LDFLAGS = @R_DYNAMIC_LDFLAG@ test_corrupt_LDADD = $(top_builddir)/dbus/libdbus-1.la \ $(GLIB_LIBS) \ $(DBUS_GLIB_LIBS) test_loopback_SOURCES = loopback.c +test_loopback_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) +test_loopback_LDFLAGS = @R_DYNAMIC_LDFLAG@ test_loopback_LDADD = $(top_builddir)/dbus/libdbus-1.la \ $(GLIB_LIBS) \ $(DBUS_GLIB_LIBS) test_relay_SOURCES = relay.c +test_relay_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) +test_relay_LDFLAGS = @R_DYNAMIC_LDFLAG@ test_relay_LDADD = $(top_builddir)/dbus/libdbus-1.la \ $(GLIB_LIBS) \ $(DBUS_GLIB_LIBS) test_dbus_daemon_SOURCES = dbus-daemon.c +test_dbus_daemon_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) +test_dbus_daemon_LDFLAGS = @R_DYNAMIC_LDFLAG@ test_dbus_daemon_LDADD = $(top_builddir)/dbus/libdbus-1.la \ $(GLIB_LIBS) \ $(DBUS_GLIB_LIBS) -test_dbus_daemon_eavesdrop_SOURCES = dbus-daemon-eavesdrop.c -test_dbus_daemon_eavesdrop_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) -test_dbus_daemon_eavesdrop_LDFLAGS = @R_DYNAMIC_LDFLAG@ -test_dbus_daemon_eavesdrop_LDADD = $(top_builddir)/dbus/libdbus-1.la \ - $(GLIB_LIBS) \ - $(DBUS_GLIB_LIBS) - test_marshal_SOURCES = marshal.c +test_marshal_CPPFLAGS = $(GLIB_CFLAGS) $(DBUS_GLIB_CFLAGS) +test_marshal_LDFLAGS = @R_DYNAMIC_LDFLAG@ test_marshal_LDADD = $(top_builddir)/dbus/libdbus-1.la \ $(GLIB_LIBS) \ $(DBUS_GLIB_LIBS) diff --git a/test/break-loader.c b/test/break-loader.c index 542f36ff..7bfa7227 100644 --- a/test/break-loader.c +++ b/test/break-loader.c @@ -446,7 +446,7 @@ randomly_change_one_type (const DBusString *orig_data, { int b; b = _dbus_string_get_byte (mutated, i); - if (dbus_type_is_valid (b)) + if (_dbus_type_is_valid (b)) { _dbus_string_set_byte (mutated, i, random_type ()); return; diff --git a/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in b/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in index 7822ffc4..16ace268 100644 --- a/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in +++ b/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in @@ -1,4 +1,4 @@ [D-BUS Service] -Exec=@DBUS_TEST_EXEC@/test-service@EXEEXT@ +Exec=@TEST_SERVICE_BINARY@ User=anyrandomuser diff --git a/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoUser.service.in b/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoUser.service.in index 691e0096..01b898cf 100644 --- a/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoUser.service.in +++ b/test/data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoUser.service.in @@ -1,3 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteNoUser -Exec=@DBUS_TEST_EXEC@/test-service@EXEEXT@ +Exec=@TEST_SERVICE_BINARY@ + diff --git a/test/data/valid-config-files-system/debug-allow-all-fail.conf.cmake b/test/data/valid-config-files-system/debug-allow-all-fail.conf.cmake index 854bfe9c..0c73d8c9 100644 --- a/test/data/valid-config-files-system/debug-allow-all-fail.conf.cmake +++ b/test/data/valid-config-files-system/debug-allow-all-fail.conf.cmake @@ -6,7 +6,7 @@ <listen>@TEST_LISTEN@</listen> <type>system</type> <servicehelper>@TEST_LAUNCH_HELPER_BINARY@</servicehelper> - <servicedir>@DBUS_TEST_DATA@/invalid-service-files-system</servicedir> + <servicedir>@TEST_INVALID_SERVICE_SYSTEM_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-config-files-system/debug-allow-all-fail.conf.in b/test/data/valid-config-files-system/debug-allow-all-fail.conf.in index a61244b6..93a548ce 100644 --- a/test/data/valid-config-files-system/debug-allow-all-fail.conf.in +++ b/test/data/valid-config-files-system/debug-allow-all-fail.conf.in @@ -7,7 +7,7 @@ <listen>unix:tmpdir=@TEST_SOCKET_DIR@</listen> <type>system</type> <servicehelper>@TEST_LAUNCH_HELPER_BINARY@</servicehelper> - <servicedir>@DBUS_TEST_DATA@/invalid-service-files-system</servicedir> + <servicedir>@TEST_INVALID_SERVICE_SYSTEM_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-config-files-system/debug-allow-all-pass.conf.cmake b/test/data/valid-config-files-system/debug-allow-all-pass.conf.cmake index 1ac5c205..d46ec184 100644 --- a/test/data/valid-config-files-system/debug-allow-all-pass.conf.cmake +++ b/test/data/valid-config-files-system/debug-allow-all-pass.conf.cmake @@ -6,7 +6,7 @@ <listen>@TEST_LISTEN@</listen> <type>system</type> <servicehelper>@TEST_LAUNCH_HELPER_BINARY@</servicehelper> - <servicedir>@DBUS_TEST_DATA@/valid-service-files-system</servicedir> + <servicedir>@TEST_VALID_SERVICE_SYSTEM_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-config-files-system/debug-allow-all-pass.conf.in b/test/data/valid-config-files-system/debug-allow-all-pass.conf.in index 6105d841..5b7ffd1a 100644 --- a/test/data/valid-config-files-system/debug-allow-all-pass.conf.in +++ b/test/data/valid-config-files-system/debug-allow-all-pass.conf.in @@ -7,7 +7,7 @@ <listen>unix:tmpdir=@TEST_SOCKET_DIR@</listen> <type>system</type> <servicehelper>@TEST_LAUNCH_HELPER_BINARY@</servicehelper> - <servicedir>@DBUS_TEST_DATA@/valid-service-files-system</servicedir> + <servicedir>@TEST_VALID_SERVICE_SYSTEM_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-config-files/debug-allow-all-sha1.conf.cmake b/test/data/valid-config-files/debug-allow-all-sha1.conf.cmake index 0c66f2ae..416267c1 100644 --- a/test/data/valid-config-files/debug-allow-all-sha1.conf.cmake +++ b/test/data/valid-config-files/debug-allow-all-sha1.conf.cmake @@ -4,7 +4,7 @@ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <listen>@TEST_LISTEN@</listen> - <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <servicedir>@TEST_VALID_SERVICE_DIR@</servicedir> <auth>DBUS_COOKIE_SHA1</auth> <policy context="default"> <allow send_interface="*"/> diff --git a/test/data/valid-config-files/debug-allow-all-sha1.conf.in b/test/data/valid-config-files/debug-allow-all-sha1.conf.in index ba68f453..34c50856 100644 --- a/test/data/valid-config-files/debug-allow-all-sha1.conf.in +++ b/test/data/valid-config-files/debug-allow-all-sha1.conf.in @@ -5,7 +5,7 @@ <busconfig> <listen>debug-pipe:name=test-server</listen> <listen>unix:tmpdir=@TEST_SOCKET_DIR@</listen> - <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <servicedir>@TEST_VALID_SERVICE_DIR@</servicedir> <auth>DBUS_COOKIE_SHA1</auth> <policy context="default"> <allow send_interface="*"/> diff --git a/test/data/valid-config-files/debug-allow-all.conf.cmake b/test/data/valid-config-files/debug-allow-all.conf.cmake index adc3aa59..94bb21e7 100644 --- a/test/data/valid-config-files/debug-allow-all.conf.cmake +++ b/test/data/valid-config-files/debug-allow-all.conf.cmake @@ -4,7 +4,7 @@ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <listen>@TEST_LISTEN@</listen> - <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <servicedir>@TEST_VALID_SERVICE_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-config-files/debug-allow-all.conf.in b/test/data/valid-config-files/debug-allow-all.conf.in index a086976b..3514296f 100644 --- a/test/data/valid-config-files/debug-allow-all.conf.in +++ b/test/data/valid-config-files/debug-allow-all.conf.in @@ -5,7 +5,7 @@ <busconfig> <listen>debug-pipe:name=test-server</listen> <listen>unix:tmpdir=@TEST_SOCKET_DIR@</listen> - <servicedir>@DBUS_TEST_DATA@/valid-service-files</servicedir> + <servicedir>@TEST_VALID_SERVICE_DIR@</servicedir> <policy context="default"> <allow send_interface="*"/> <allow receive_interface="*"/> diff --git a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteEchoService.service.in b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteEchoService.service.in index 3076f3bf..bd0e58e5 100644 --- a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteEchoService.service.in +++ b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteEchoService.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteEchoService -Exec=@DBUS_TEST_EXEC@/test-service@EXEEXT@ +Exec=@TEST_SERVICE_BINARY@ User=anyrandomuser diff --git a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteSegfaultService.service.in b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteSegfaultService.service.in index 705d7148..18d16d1b 100644 --- a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteSegfaultService.service.in +++ b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteSegfaultService.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteSegfaultService -Exec=@DBUS_TEST_EXEC@/test-segfault@EXEEXT@ +Exec=@TEST_SEGFAULT_BINARY@ User=anyrandomuser diff --git a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in index 870835ea..9195e174 100644 --- a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in +++ b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteShellEchoServiceFail -Exec=@DBUS_TEST_EXEC@/test-shell-service@EXEEXT@ "this should 'fail' because of an unterminated quote +Exec=@TEST_SHELL_SERVICE_BINARY@ "this should 'fail' because of an unterminated quote User=anyrandomuser diff --git a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in index 66472614..2236ce55 100644 --- a/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in +++ b/test/data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess -Exec=@DBUS_TEST_EXEC@/test-shell-service@EXEEXT@ -test "that" 'we get' back --what "we put in" +Exec=@TEST_SHELL_SERVICE_BINARY@ -test "that" 'we get' back --what "we put in" User=anyrandomuser diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuite.PrivServer.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuite.PrivServer.service.in index 0fdfeade..2cbdaa8b 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuite.PrivServer.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuite.PrivServer.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuite.PrivServer -Exec=@DBUS_TEST_EXEC@/name-test/test-privserver@EXEEXT@ +Exec=@TEST_PRIVSERVER_BINARY@ diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteEchoService.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteEchoService.service.in index a22a77d1..4202351d 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteEchoService.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteEchoService.service.in @@ -1,3 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteEchoService -Exec=@DBUS_TEST_EXEC@/test-service@EXEEXT@ +Exec=@TEST_SERVICE_BINARY@ + diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteForkingEchoService.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteForkingEchoService.service.in index 633862c7..49fcac39 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteForkingEchoService.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteForkingEchoService.service.in @@ -1,3 +1,3 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteForkingEchoService -Exec=@DBUS_TEST_EXEC@/test-service@EXEEXT@ org.freedesktop.DBus.TestSuiteForkingEchoService fork +Exec=@TEST_SERVICE_BINARY@ org.freedesktop.DBus.TestSuiteForkingEchoService fork diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteSegfaultService.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteSegfaultService.service.in index 76254275..73c7b55b 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteSegfaultService.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteSegfaultService.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteSegfaultService -Exec=@DBUS_TEST_EXEC@/test-segfault@EXEEXT@ +Exec=@TEST_SEGFAULT_BINARY@ diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in index 8f5964a2..4404c78e 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in @@ -1,3 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteShellEchoServiceFail -Exec=@DBUS_TEST_EXEC@/test-shell-service@EXEEXT@ "this should 'fail' because of an unterminated quote +Exec=@TEST_SHELL_SERVICE_BINARY@ "this should 'fail' because of an unterminated quote + diff --git a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in index a52887e5..e5688462 100644 --- a/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in +++ b/test/data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in @@ -1,4 +1,4 @@ [D-BUS Service] Name=org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess -Exec=@DBUS_TEST_EXEC@/test-shell-service@EXEEXT@ -test "that" 'we get' back --what "we put in" +Exec=@TEST_SHELL_SERVICE_BINARY@ -test "that" 'we get' back --what "we put in" diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c index cc871530..e192c68f 100644 --- a/test/dbus-daemon.c +++ b/test/dbus-daemon.c @@ -42,8 +42,6 @@ #endif typedef struct { - gboolean skip; - DBusError e; GError *ge; @@ -151,6 +149,8 @@ echo_filter (DBusConnection *connection, void *user_data) { DBusMessage *reply; + DBusError error = DBUS_ERROR_INIT; + int *sleep_ms = user_data; if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -168,63 +168,42 @@ echo_filter (DBusConnection *connection, return DBUS_HANDLER_RESULT_HANDLED; } -typedef struct { - const char *bug_ref; - guint min_messages; - const char *config_file; -} Config; - static void setup (Fixture *f, - gconstpointer context) + gconstpointer context G_GNUC_UNUSED) { - const Config *config = context; gchar *dbus_daemon; - gchar *arg; + gchar *config; gchar *address; f->ge = NULL; dbus_error_init (&f->e); - if (config != NULL && config->config_file != NULL) - { - if (g_getenv ("DBUS_TEST_DATA") == NULL) - { - g_message ("SKIP: set DBUS_TEST_DATA to a directory containing %s", - config->config_file); - f->skip = TRUE; - return; - } + dbus_daemon = g_strdup (g_getenv ("DBUS_TEST_DAEMON")); - arg = g_strdup_printf ( - "--config-file=%s/%s", - g_getenv ("DBUS_TEST_DATA"), config->config_file); - } - else if (g_getenv ("DBUS_TEST_SYSCONFDIR") != NULL) + if (dbus_daemon == NULL) + dbus_daemon = g_strdup ("dbus-daemon"); + + if (g_getenv ("DBUS_TEST_SYSCONFDIR") != NULL) { - arg = g_strdup_printf ("--config-file=%s/dbus-1/session.conf", + config = g_strdup_printf ("--config-file=%s/dbus-1/session.conf", g_getenv ("DBUS_TEST_SYSCONFDIR")); } else if (g_getenv ("DBUS_TEST_DATA") != NULL) { - arg = g_strdup_printf ( + config = g_strdup_printf ( "--config-file=%s/valid-config-files/session.conf", g_getenv ("DBUS_TEST_DATA")); } else { - arg = g_strdup ("--session"); + config = g_strdup ("--session"); } - dbus_daemon = g_strdup (g_getenv ("DBUS_TEST_DAEMON")); - - if (dbus_daemon == NULL) - dbus_daemon = g_strdup ("dbus-daemon"); - - address = spawn_dbus_daemon (dbus_daemon, arg, &f->daemon_pid); + address = spawn_dbus_daemon (dbus_daemon, config, &f->daemon_pid); g_free (dbus_daemon); - g_free (arg); + g_free (config); f->left_conn = connect_to_bus (address); f->right_conn = connect_to_bus (address); @@ -251,26 +230,16 @@ pc_count (DBusPendingCall *pc, static void test_echo (Fixture *f, - gconstpointer context) + gconstpointer context G_GNUC_UNUSED) { - const Config *config = context; guint count = 2000; guint sent; guint received = 0; double elapsed; - if (f->skip) - return; - - if (config != NULL && config->bug_ref != NULL) - g_test_bug (config->bug_ref); - if (g_test_perf ()) count = 100000; - if (config != NULL) - count = MAX (config->min_messages, count); - add_echo_filter (f); g_test_timer_start (); @@ -336,23 +305,15 @@ teardown (Fixture *f, f->right_conn = NULL; } - if (f->daemon_pid != 0) - { #ifdef DBUS_WIN - TerminateProcess (f->daemon_pid, 1); + TerminateProcess (f->daemon_pid, 1); #else - kill (f->daemon_pid, SIGTERM); + kill (f->daemon_pid, SIGTERM); #endif - g_spawn_close_pid (f->daemon_pid); - f->daemon_pid = 0; - } + g_spawn_close_pid (f->daemon_pid); } -static Config limited_config = { - "34393", 10000, "valid-config-files/incoming-limit.conf" -}; - int main (int argc, char **argv) @@ -361,8 +322,6 @@ main (int argc, g_test_bug_base ("https://bugs.freedesktop.org/show_bug.cgi?id="); g_test_add ("/echo/session", Fixture, NULL, setup, test_echo, teardown); - g_test_add ("/echo/limited", Fixture, &limited_config, - setup, test_echo, teardown); return g_test_run (); } diff --git a/test/internals/refs.c b/test/internals/refs.c index bc0884e3..3d21c894 100644 --- a/test/internals/refs.c +++ b/test/internals/refs.c @@ -181,6 +181,7 @@ new_conn_cb (DBusServer *server, void *data) { Fixture *f = data; + dbus_bool_t have_mem; g_assert (f->server_connection == NULL); f->server_connection = dbus_connection_ref (server_connection); diff --git a/test/marshal.c b/test/marshal.c index e9ac7e30..4cee9412 100644 --- a/test/marshal.c +++ b/test/marshal.c @@ -146,6 +146,7 @@ test_endian (Fixture *f, gconstpointer arg) { const gchar *blob = arg; + const gchar *native_blob; char *output; DBusMessage *m; int len; diff --git a/test/name-test/Makefile.am b/test/name-test/Makefile.am index 6aaf1783..45c21d46 100644 --- a/test/name-test/Makefile.am +++ b/test/name-test/Makefile.am @@ -1,12 +1,4 @@ -# Everything in this directory is statically-linked to libdbus-internal -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - -DDBUS_COMPILATION \ - -DDBUS_STATIC_BUILD \ - $(NULL) - -# if assertions are enabled, improve backtraces -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_GLIB_CFLAGS) $(DBUS_TEST_CFLAGS) -DDBUS_COMPILATION ## note that TESTS has special meaning (stuff to use in make check) ## so if adding tests not to be run in make check, don't add them to @@ -26,14 +18,57 @@ if DBUS_BUILD_TESTS ## build even when not doing "make check" noinst_PROGRAMS=test-pending-call-dispatch test-pending-call-timeout test-threads-init test-ids test-shutdown test-privserver test-privserver-client test-autolaunch -test_pending_call_dispatch_LDADD=$(top_builddir)/dbus/libdbus-internal.la -test_pending_call_timeout_LDADD=$(top_builddir)/dbus/libdbus-internal.la -test_threads_init_LDADD=$(top_builddir)/dbus/libdbus-internal.la -test_ids_LDADD=$(top_builddir)/dbus/libdbus-internal.la +AM_CPPFLAGS = -DDBUS_STATIC_BUILD +test_pending_call_dispatch_SOURCES = \ + test-pending-call-dispatch.c + +test_pending_call_dispatch_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_TEST_LIBS) +test_pending_call_dispatch_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_pending_call_timeout_SOURCES = \ + test-pending-call-timeout.c + +test_pending_call_timeout_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_TEST_LIBS) +test_pending_call_timeout_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_threads_init_SOURCES = \ + test-threads-init.c + +test_threads_init_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_TEST_LIBS) +test_threads_init_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_ids_SOURCES = \ + test-ids.c + +test_ids_LDADD=$(top_builddir)/dbus/libdbus-internal.la $(DBUS_TEST_LIBS) +test_ids_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_shutdown_SOURCES = \ + test-shutdown.c + +test_shutdown_CFLAGS= +test_shutdown_LDADD=$(top_builddir)/dbus/libdbus-internal.la ../libdbus-testutils.la $(DBUS_TEST_LIBS) +test_shutdown_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_privserver_SOURCES = \ + test-privserver.c + +test_privserver_CFLAGS= +test_privserver_LDADD=$(top_builddir)/dbus/libdbus-internal.la ../libdbus-testutils.la $(DBUS_TEST_LIBS) +test_privserver_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_privserver_client_SOURCES = \ + test-privserver-client.c + +test_privserver_client_CFLAGS= +test_privserver_client_LDADD=$(top_builddir)/dbus/libdbus-internal.la ../libdbus-testutils.la $(DBUS_TEST_LIBS) +test_privserver_client_LDFLAGS=@R_DYNAMIC_LDFLAG@ + +test_autolaunch_SOURCES = \ + test-autolaunch.c -test_shutdown_LDADD=../libdbus-testutils.la -test_privserver_LDADD=../libdbus-testutils.la -test_privserver_client_LDADD=../libdbus-testutils.la -test_autolaunch_LDADD=../libdbus-testutils.la +test_autolaunch_CFLAGS= +test_autolaunch_LDADD=$(top_builddir)/dbus/libdbus-internal.la ../libdbus-testutils.la $(DBUS_TEST_LIBS) +test_autolaunch_LDFLAGS=@R_DYNAMIC_LDFLAG@ endif diff --git a/test/name-test/test-privserver-client.c b/test/name-test/test-privserver-client.c index e7f48960..1c43faee 100644 --- a/test/name-test/test-privserver-client.c +++ b/test/name-test/test-privserver-client.c @@ -71,6 +71,7 @@ open_shutdown_private_connection (dbus_bool_t use_guid) DBusMessage *reply; DBusConnection *privconn; char *addr; + char *comma; dbus_bool_t service_died; dbus_bool_t private_conn_lost; diff --git a/test/test-service.c b/test/test-service.c index 7181fa38..6627ea75 100644 --- a/test/test-service.c +++ b/test/test-service.c @@ -477,14 +477,7 @@ main (int argc, dbus_error_free (&error); exit (1); } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - fprintf (stderr, "Unable to acquire service: code %d\n", result); - _dbus_verbose ("*** Failed to acquire service: %d\n", result); - exit (1); - } - + _dbus_verbose ("*** Test service entering main loop\n"); _dbus_loop_run (loop); diff --git a/test/test-shell-service.c b/test/test-shell-service.c index 32a88329..57c16123 100644 --- a/test/test-shell-service.c +++ b/test/test-shell-service.c @@ -176,13 +176,6 @@ main (int argc, exit (1); } - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - fprintf (stderr, "Unable to acquire service: code %d\n", result); - _dbus_verbose ("*** Failed to acquire service: %d\n", result); - exit (1); - } - _dbus_verbose ("*** Test service entering main loop\n"); _dbus_loop_run (loop); diff --git a/test/test-utils.c b/test/test-utils.c index 4fd84fe8..05cd7535 100644 --- a/test/test-utils.c +++ b/test/test-utils.c @@ -9,12 +9,23 @@ typedef struct } CData; static dbus_bool_t +connection_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t add_watch (DBusWatch *watch, void *data) { CData *cd = data; - return _dbus_loop_add_watch (cd->loop, watch); + return _dbus_loop_add_watch (cd->loop, + watch, + connection_watch_callback, + cd, NULL); } static void @@ -23,7 +34,16 @@ remove_watch (DBusWatch *watch, { CData *cd = data; - _dbus_loop_remove_watch (cd->loop, watch); + _dbus_loop_remove_watch (cd->loop, + watch, connection_watch_callback, cd); +} + +static void +connection_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* Can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); } static dbus_bool_t @@ -32,7 +52,8 @@ add_timeout (DBusTimeout *timeout, { CData *cd = data; - return _dbus_loop_add_timeout (cd->loop, timeout); + return _dbus_loop_add_timeout (cd->loop, + timeout, connection_timeout_callback, cd, NULL); } static void @@ -41,7 +62,8 @@ remove_timeout (DBusTimeout *timeout, { CData *cd = data; - _dbus_loop_remove_timeout (cd->loop, timeout); + _dbus_loop_remove_timeout (cd->loop, + timeout, connection_timeout_callback, cd); } static void @@ -204,12 +226,27 @@ serverdata_new (DBusLoop *loop, } static dbus_bool_t +server_watch_callback (DBusWatch *watch, + unsigned int condition, + void *data) +{ + /* FIXME this can be done in dbus-mainloop.c + * if the code in activation.c for the babysitter + * watch handler is fixed. + */ + + return dbus_watch_handle (watch, condition); +} + +static dbus_bool_t add_server_watch (DBusWatch *watch, void *data) { ServerData *context = data; - return _dbus_loop_add_watch (context->loop, watch); + return _dbus_loop_add_watch (context->loop, + watch, server_watch_callback, context, + NULL); } static void @@ -218,7 +255,16 @@ remove_server_watch (DBusWatch *watch, { ServerData *context = data; - _dbus_loop_remove_watch (context->loop, watch); + _dbus_loop_remove_watch (context->loop, + watch, server_watch_callback, context); +} + +static void +server_timeout_callback (DBusTimeout *timeout, + void *data) +{ + /* can return FALSE on OOM but we just let it fire again later */ + dbus_timeout_handle (timeout); } static dbus_bool_t @@ -227,7 +273,8 @@ add_server_timeout (DBusTimeout *timeout, { ServerData *context = data; - return _dbus_loop_add_timeout (context->loop, timeout); + return _dbus_loop_add_timeout (context->loop, + timeout, server_timeout_callback, context, NULL); } static void @@ -236,7 +283,8 @@ remove_server_timeout (DBusTimeout *timeout, { ServerData *context = data; - _dbus_loop_remove_timeout (context->loop, timeout); + _dbus_loop_remove_timeout (context->loop, + timeout, server_timeout_callback, context); } dbus_bool_t diff --git a/tools/Makefile.am b/tools/Makefile.am index 08b90234..ce88c85f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,28 +1,14 @@ configdir=$(sysconfdir)/dbus-1 -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(DBUS_X_CFLAGS) \ - -DDBUS_COMPILATION \ - -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" \ - $(NULL) - -# if assertions are enabled, improve backtraces -AM_LDFLAGS = @R_DYNAMIC_LDFLAG@ - -bin_PROGRAMS = \ - dbus-launch \ - dbus-monitor \ - dbus-send \ - $(NULL) +INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_MACHINE_UUID_FILE=\""$(localstatedir)/lib/dbus/machine-id"\" +extra_bin_programs= if DBUS_UNIX -bin_PROGRAMS += \ - dbus-cleanup-sockets \ - dbus-uuidgen \ - $(NULL) +extra_bin_programs += dbus-cleanup-sockets dbus-uuidgen endif +bin_PROGRAMS=dbus-launch dbus-send dbus-monitor $(extra_bin_programs) + dbus_send_SOURCES= \ dbus-print-message.c \ dbus-print-message.h \ @@ -50,22 +36,17 @@ dbus_cleanup_sockets_SOURCES= \ dbus_uuidgen_SOURCES= \ dbus-uuidgen.c -dbus_send_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NULL) +dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_send_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_monitor_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NETWORK_libs) \ - $(NULL) +dbus_monitor_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_monitor_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_uuidgen_LDADD = \ - $(top_builddir)/dbus/libdbus-1.la \ - $(NULL) +dbus_uuidgen_LDADD= $(top_builddir)/dbus/libdbus-1.la $(DBUS_CLIENT_LIBS) +dbus_uuidgen_LDFLAGS=@R_DYNAMIC_LDFLAG@ -dbus_launch_LDADD = \ - $(DBUS_X_LIBS) \ - $(NULL) +dbus_launch_LDADD= $(DBUS_X_LIBS) $(DBUS_CLIENT_LIBS) +dbus_launch_LDFLAGS=@R_DYNAMIC_LDFLAG@ EXTRA_DIST = run-with-tmp-session-bus.sh strtoll.c strtoull.c CLEANFILES = \ diff --git a/tools/dbus-monitor.c b/tools/dbus-monitor.c index a4b54782..5edb5c0b 100644 --- a/tools/dbus-monitor.c +++ b/tools/dbus-monitor.c @@ -35,8 +35,6 @@ #include "dbus-print-message.h" -#define EAVESDROPPING_RULE "eavesdrop=true" - #ifdef DBUS_WIN /* gettimeofday is not defined on windows */ @@ -78,13 +76,6 @@ gettimeofday (struct timeval *__p, } #endif -inline static void -oom (const char *doing) -{ - fprintf (stderr, "OOM while %s\n", doing); - exit (1); -} - static DBusHandlerResult monitor_filter_func (DBusConnection *connection, DBusMessage *message, @@ -239,6 +230,14 @@ only_one_type (dbus_bool_t *seen_bus_type, } } +static dbus_bool_t sigint_received = FALSE; + +static void +sigint_handler (int signum) +{ + sigint_received = TRUE; +} + int main (int argc, char *argv[]) { @@ -300,21 +299,11 @@ main (int argc, char *argv[]) else if (arg[0] == '-') usage (argv[0], 1); else { - unsigned int filter_len; - numFilters++; - /* Prepend a rule (and a comma) to enable the monitor to eavesdrop. - * Prepending allows the user to add eavesdrop=false at command line - * in order to disable eavesdropping when needed */ - filter_len = strlen (EAVESDROPPING_RULE) + 1 + strlen (arg) + 1; - - filters = (char **) realloc (filters, numFilters * sizeof (char *)); - if (filters == NULL) - oom ("adding a new filter slot"); - filters[j] = (char *) malloc (filter_len * sizeof (char *)); - if (filters[j] == NULL) - oom ("adding a new filter"); - snprintf (filters[j], filter_len, "%s,%s", EAVESDROPPING_RULE, arg); - j++; + numFilters++; + filters = (char **)realloc(filters, numFilters * sizeof(char *)); + filters[j] = (char *)malloc((strlen(arg) + 1) * sizeof(char *)); + snprintf(filters[j], strlen(arg) + 1, "%s", arg); + j++; } } @@ -380,22 +369,22 @@ main (int argc, char *argv[]) else { dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='signal'", + "type='signal'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='method_call'", + "type='method_call'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='method_return'", + "type='method_return'", &error); if (dbus_error_is_set (&error)) goto lose; dbus_bus_add_match (connection, - EAVESDROPPING_RULE ",type='error'", + "type='error'", &error); if (dbus_error_is_set (&error)) goto lose; diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c new file mode 100644 index 00000000..2fd28474 --- /dev/null +++ b/tools/dbus-viewer.c @@ -0,0 +1,617 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-viewer.c Graphical D-Bus frontend utility + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include <config.h> +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <gtk/gtk.h> +#include "dbus-tree-view.h" +#include "dbus-names-model.h" +#include <glib/dbus-gparser.h> +#include <glib/dbus-gutils.h> +#include <dbus/dbus-glib.h> +#include <glib/gi18n.h> + +static void +show_error_dialog (GtkWindow *transient_parent, + GtkWidget **weak_ptr, + const char *message_format, + ...) +{ + char *message; + va_list args; + + if (message_format) + { + va_start (args, message_format); + message = g_strdup_vprintf (message_format, args); + va_end (args); + } + else + message = NULL; + + if (weak_ptr == NULL || *weak_ptr == NULL) + { + GtkWidget *dialog; + dialog = gtk_message_dialog_new (transient_parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + message); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (gtk_widget_destroy), NULL); + + if (weak_ptr != NULL) + { + *weak_ptr = dialog; + g_object_add_weak_pointer (G_OBJECT (dialog), (void**)weak_ptr); + } + + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + + gtk_widget_show_all (dialog); + } + else + { + g_return_if_fail (GTK_IS_MESSAGE_DIALOG (*weak_ptr)); + + gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (*weak_ptr)->label), message); + + gtk_window_present (GTK_WINDOW (*weak_ptr)); + } +} + +typedef struct +{ + DBusGConnection *connection; + + GtkWidget *window; + GtkWidget *treeview; + GtkWidget *name_menu; + + GtkTreeModel *names_model; + + GtkWidget *error_dialog; + +} TreeWindow; + + +static void +tree_window_set_node (TreeWindow *w, + NodeInfo *node) +{ + char **path; + const char *name; + + name = node_info_get_name (node); + if (name == NULL || + name[0] != '/') + { + g_printerr (_("Assuming root node is at path /, since no absolute path is specified")); + name = "/"; + } + + path = _dbus_gutils_split_path (name); + + dbus_tree_view_update (GTK_TREE_VIEW (w->treeview), + (const char**) path, + node); + + g_strfreev (path); +} + +typedef struct +{ + DBusGConnection *connection; + char *service_name; + GError *error; + NodeInfo *node; + TreeWindow *window; /* Not touched from child thread */ +} LoadFromServiceData; + +static gboolean +load_child_nodes (const char *service_name, + NodeInfo *parent, + GString *path, + GError **error) +{ + DBusGConnection *connection; + GSList *tmp; + + connection = dbus_g_bus_get (DBUS_BUS_SESSION, error); + if (connection == NULL) + return FALSE; + + tmp = node_info_get_nodes (parent); + while (tmp != NULL) + { + DBusGProxy *proxy; + char *data; + NodeInfo *child; + NodeInfo *complete_child; + int save_len; + + complete_child = NULL; + + child = tmp->data; + + save_len = path->len; + + if (save_len > 1) + g_string_append (path, "/"); + g_string_append (path, base_info_get_name ((BaseInfo*)child)); + + if (*service_name == ':') + { + proxy = dbus_g_proxy_new_for_name (connection, + service_name, + path->str, + DBUS_INTERFACE_INTROSPECTABLE); + g_assert (proxy != NULL); + } + else + { + proxy = dbus_g_proxy_new_for_name_owner (connection, + service_name, + path->str, + DBUS_INTERFACE_INTROSPECTABLE, + error); + if (proxy == NULL) + goto done; + } + + if (!dbus_g_proxy_call (proxy, "Introspect", error, + G_TYPE_INVALID, + G_TYPE_STRING, &data, + G_TYPE_INVALID)) + goto done; + + complete_child = description_load_from_string (data, -1, error); + g_free (data); + if (complete_child == NULL) + { + g_printerr ("%s\n", data); + goto done; + } + + done: + g_object_unref (proxy); + + if (complete_child == NULL) + return FALSE; + + /* change complete_child's name to relative */ + base_info_set_name ((BaseInfo*)complete_child, + base_info_get_name ((BaseInfo*)child)); + + /* Stitch in complete_child rather than child */ + node_info_replace_node (parent, child, complete_child); + node_info_unref (complete_child); /* ref still held by parent */ + + /* Now recurse */ + if (!load_child_nodes (service_name, complete_child, path, error)) + return FALSE; + + /* restore path */ + g_string_set_size (path, save_len); + + tmp = tmp->next; + } + + return TRUE; +} + +static gboolean +load_from_service_complete_idle (void *data) +{ + /* Called in main thread */ + GThread *thread = data; + LoadFromServiceData *d; + NodeInfo *node; + + d = g_thread_join (thread); + + node = d->node; + + if (d->error) + { + g_assert (d->node == NULL); + show_error_dialog (GTK_WINDOW (d->window->window), &d->window->error_dialog, + _("Unable to load \"%s\": %s\n"), + d->service_name, d->error->message); + g_error_free (d->error); + } + else + { + g_assert (d->error == NULL); + + tree_window_set_node (d->window, node); + node_info_unref (node); + } + + g_free (d->service_name); + dbus_g_connection_unref (d->connection); + g_free (d); + + return FALSE; +} + +static void* +load_from_service_thread_func (void *thread_data) +{ + DBusGProxy *root_proxy; + const char *data; + NodeInfo *node; + GString *path; + LoadFromServiceData *lfsd; + + lfsd = thread_data; + + node = NULL; + path = NULL; + +#if 1 + /* this will end up autolaunching the service when we introspect it */ + root_proxy = dbus_g_proxy_new_for_name (lfsd->connection, + lfsd->service_name, + "/", + DBUS_INTERFACE_INTROSPECTABLE); + g_assert (root_proxy != NULL); +#else + /* this will be an error if the service doesn't exist */ + root_proxy = dbus_g_proxy_new_for_name_owner (lfsd->connection, + lfsd->service_name, + "/", + DBUS_INTERFACE_INTROSPECTABLE, + &lfsd->error); + if (root_proxy == NULL) + { + g_printerr ("Failed to get owner of '%s'\n", lfsd->service_name); + return lfsd->data; + } +#endif + + if (!dbus_g_proxy_call (root_proxy, "Introspect", &lfsd->error, + G_TYPE_INVALID, + G_TYPE_STRING, &data, + G_TYPE_INVALID)) + { + g_printerr ("Failed to Introspect() %s\n", + dbus_g_proxy_get_bus_name (root_proxy)); + goto out; + } + + node = description_load_from_string (data, -1, &lfsd->error); + + /* g_print ("%s\n", data); */ + + if (node == NULL) + goto out; + + base_info_set_name ((BaseInfo*)node, "/"); + + path = g_string_new ("/"); + + if (!load_child_nodes (dbus_g_proxy_get_bus_name (root_proxy), + node, path, &lfsd->error)) + { + node_info_unref (node); + node = NULL; + goto out; + } + + out: + g_object_unref (root_proxy); + + if (path) + g_string_free (path, TRUE); + + lfsd->node = node; + g_assert (lfsd->node || lfsd->error); + g_assert (lfsd->node == NULL || lfsd->error == NULL); + + /* Add idle to main thread that will join us back */ + g_idle_add (load_from_service_complete_idle, g_thread_self ()); + + return lfsd; +} + +static void +start_load_from_service (TreeWindow *w, + DBusGConnection *connection, + const char *service_name) +{ + LoadFromServiceData *d; + + d = g_new0 (LoadFromServiceData, 1); + + d->connection = dbus_g_connection_ref (connection); + d->service_name = g_strdup (service_name); + d->error = NULL; + d->node = NULL; + d->window = w; + + g_thread_create (load_from_service_thread_func, d, TRUE, NULL); +} + +static void +tree_window_set_service (TreeWindow *w, + const char *service_name) +{ + start_load_from_service (w, w->connection, service_name); +} + +static void +name_combo_changed_callback (GtkComboBox *combo, + TreeWindow *w) +{ + GtkTreeIter iter; + + if (gtk_combo_box_get_active_iter (combo, &iter)) + { + GtkTreeModel *model; + char *text; + + model = gtk_combo_box_get_model (combo); + gtk_tree_model_get (model, &iter, 0, &text, -1); + + if (text) + { + tree_window_set_service (w, text); + g_free (text); + } + } +} + +static void +window_closed_callback (GtkWidget *window, + TreeWindow *w) +{ + g_assert (window == w->window); + w->window = NULL; + gtk_main_quit (); +} + +static TreeWindow* +tree_window_new (DBusGConnection *connection, + GtkTreeModel *names_model) +{ + TreeWindow *w; + GtkWidget *sw; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *combo; + + /* Should use glade, blah */ + + w = g_new0 (TreeWindow, 1); + w->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title (GTK_WINDOW (w->window), "D-Bus Viewer"); + gtk_window_set_default_size (GTK_WINDOW (w->window), 400, 500); + + g_signal_connect (w->window, "destroy", G_CALLBACK (window_closed_callback), + w); + gtk_container_set_border_width (GTK_CONTAINER (w->window), 6); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (w->window), vbox); + + /* Create names option menu */ + if (connection) + { + GtkCellRenderer *cell; + + w->connection = connection; + + w->names_model = names_model; + + combo = gtk_combo_box_new_with_model (w->names_model); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, + "text", 0, + NULL); + + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); + + g_signal_connect (combo, "changed", + G_CALLBACK (name_combo_changed_callback), + w); + } + + /* Create tree view */ + hbox = gtk_hbox_new (FALSE, 6); + gtk_container_add (GTK_CONTAINER (vbox), hbox); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0); + + w->treeview = dbus_tree_view_new (); + + gtk_container_add (GTK_CONTAINER (sw), w->treeview); + + /* Show everything */ + gtk_widget_show_all (w->window); + + return w; +} + +static void +usage (int ecode) +{ + fprintf (stderr, "dbus-viewer [--version] [--help]\n"); + exit (ecode); +} + +static void +version (void) +{ + printf ("D-Bus Message Bus Viewer %s\n" + "Copyright (C) 2003 Red Hat, Inc.\n" + "This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", + VERSION); + exit (0); +} + +int +main (int argc, char **argv) +{ + int i; + GSList *files; + gboolean end_of_args; + GSList *tmp; + gboolean services; + DBusGConnection *connection; + GError *error; + GtkTreeModel *names_model; + + g_thread_init (NULL); + dbus_g_thread_init (); + + bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + gtk_init (&argc, &argv); + + services = FALSE; + end_of_args = FALSE; + files = NULL; + i = 1; + while (i < argc) + { + const char *arg = argv[i]; + + if (!end_of_args) + { + if (strcmp (arg, "--help") == 0 || + strcmp (arg, "-h") == 0 || + strcmp (arg, "-?") == 0) + usage (0); + else if (strcmp (arg, "--version") == 0) + version (); + else if (strcmp (arg, "--services") == 0) + services = TRUE; + else if (arg[0] == '-' && + arg[1] == '-' && + arg[2] == '\0') + end_of_args = TRUE; + else if (arg[0] == '-') + { + usage (1); + } + else + { + files = g_slist_prepend (files, (char*) arg); + } + } + else + files = g_slist_prepend (files, (char*) arg); + + ++i; + } + + if (services || files == NULL) + { + error = NULL; + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (connection == NULL) + { + g_printerr ("Could not open bus connection: %s\n", + error->message); + g_error_free (error); + exit (1); + } + + g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL)); + + names_model = names_model_new (connection); + } + else + { + connection = NULL; + names_model = NULL; + } + + if (files == NULL) + { + TreeWindow *w; + + w = tree_window_new (connection, names_model); + } + + files = g_slist_reverse (files); + + tmp = files; + while (tmp != NULL) + { + const char *filename; + TreeWindow *w; + + filename = tmp->data; + + if (services) + { + w = tree_window_new (connection, names_model); + tree_window_set_service (w, filename); + } + else + { + NodeInfo *node; + + error = NULL; + node = description_load_from_file (filename, + &error); + + if (node == NULL) + { + g_assert (error != NULL); + show_error_dialog (NULL, NULL, + _("Unable to load \"%s\": %s\n"), + filename, error->message); + g_error_free (error); + } + else + { + w = tree_window_new (connection, names_model); + tree_window_set_node (w, node); + node_info_unref (node); + } + } + + tmp = tmp->next; + } + + gtk_main (); + + return 0; +} + |