summaryrefslogtreecommitdiff
path: root/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'dbus')
-rw-r--r--dbus/.gitignore2
-rw-r--r--dbus/Makefile.am31
-rw-r--r--dbus/dbus-address.c12
-rw-r--r--dbus/dbus-arch-deps.h.in8
-rw-r--r--dbus/dbus-asv-util.c260
-rw-r--r--dbus/dbus-asv-util.h46
-rw-r--r--dbus/dbus-auth-script.c10
-rw-r--r--dbus/dbus-auth-util.c4
-rw-r--r--dbus/dbus-auth.c12
-rw-r--r--dbus/dbus-auth.h3
-rw-r--r--dbus/dbus-bus.c82
-rw-r--r--dbus/dbus-connection-internal.h2
-rw-r--r--dbus/dbus-connection.c122
-rw-r--r--dbus/dbus-credentials-util.c16
-rw-r--r--dbus/dbus-credentials.c32
-rw-r--r--dbus/dbus-credentials.h4
-rw-r--r--dbus/dbus-dataslot.c77
-rw-r--r--dbus/dbus-dataslot.h8
-rw-r--r--dbus/dbus-errors.c3
-rw-r--r--dbus/dbus-hash.c4
-rw-r--r--dbus/dbus-init-win.cpp52
-rw-r--r--dbus/dbus-internals.c58
-rw-r--r--dbus/dbus-internals.h77
-rw-r--r--dbus/dbus-keyring.c19
-rw-r--r--dbus/dbus-list.c21
-rw-r--r--dbus/dbus-macros.h10
-rw-r--r--dbus/dbus-mainloop.c25
-rw-r--r--dbus/dbus-marshal-basic.c77
-rw-r--r--dbus/dbus-marshal-basic.h39
-rw-r--r--dbus/dbus-marshal-byteswap-util.c4
-rw-r--r--dbus/dbus-marshal-byteswap.c4
-rw-r--r--dbus/dbus-marshal-header.c4
-rw-r--r--dbus/dbus-marshal-recursive-util.c36
-rw-r--r--dbus/dbus-marshal-validate-util.c4
-rw-r--r--dbus/dbus-memory.c59
-rw-r--r--dbus/dbus-mempool.c42
-rw-r--r--dbus/dbus-message-factory.c4
-rw-r--r--dbus/dbus-message-factory.h4
-rw-r--r--dbus/dbus-message-internal.h3
-rw-r--r--dbus/dbus-message-util.c249
-rw-r--r--dbus/dbus-message.c205
-rw-r--r--dbus/dbus-message.h12
-rw-r--r--dbus/dbus-misc.c2
-rw-r--r--dbus/dbus-misc.h4
-rw-r--r--dbus/dbus-nonce.c16
-rw-r--r--dbus/dbus-object-tree.c468
-rw-r--r--dbus/dbus-pending-call.c24
-rw-r--r--dbus/dbus-server-debug-pipe.c4
-rw-r--r--dbus/dbus-server-launchd.c3
-rw-r--r--dbus/dbus-server-socket.c7
-rw-r--r--dbus/dbus-server-unix.c38
-rw-r--r--dbus/dbus-server-win.c28
-rw-r--r--dbus/dbus-server.c36
-rw-r--r--dbus/dbus-sha.c4
-rw-r--r--dbus/dbus-shell.c12
-rw-r--r--dbus/dbus-signature.c2
-rw-r--r--dbus/dbus-socket-set-poll.c2
-rw-r--r--dbus/dbus-spawn-win.c47
-rw-r--r--dbus/dbus-spawn.c168
-rw-r--r--dbus/dbus-spawn.h1
-rw-r--r--dbus/dbus-string-util.c4
-rw-r--r--dbus/dbus-string.c61
-rw-r--r--dbus/dbus-string.h2
-rw-r--r--dbus/dbus-syntax.c8
-rw-r--r--dbus/dbus-sysdeps-pthread.c24
-rw-r--r--dbus/dbus-sysdeps-thread-win.c30
-rw-r--r--dbus/dbus-sysdeps-unix.c661
-rw-r--r--dbus/dbus-sysdeps-unix.h4
-rw-r--r--dbus/dbus-sysdeps-util-unix.c227
-rw-r--r--dbus/dbus-sysdeps-util-win.c214
-rw-r--r--dbus/dbus-sysdeps-util.c4
-rw-r--r--dbus/dbus-sysdeps-win.c602
-rw-r--r--dbus/dbus-sysdeps-win.h9
-rw-r--r--dbus/dbus-sysdeps-wince-glue.c2
-rw-r--r--dbus/dbus-sysdeps.c23
-rw-r--r--dbus/dbus-sysdeps.h34
-rw-r--r--dbus/dbus-test.c15
-rw-r--r--dbus/dbus-threads.c423
-rw-r--r--dbus/dbus-transport-protected.h2
-rw-r--r--dbus/dbus-transport-socket.c40
-rw-r--r--dbus/dbus-transport-unix.c2
-rw-r--r--dbus/dbus-transport-win.c35
-rw-r--r--dbus/dbus-transport.c50
-rw-r--r--dbus/dbus-transport.h3
-rw-r--r--dbus/dbus-types.h36
-rw-r--r--dbus/dbus-userdb-util.c33
-rw-r--r--dbus/dbus-userdb.c51
-rw-r--r--dbus/dbus-userdb.h2
-rw-r--r--dbus/dbus-valgrind-internal.h8
-rw-r--r--dbus/dbus-watch.c43
-rw-r--r--dbus/sd-daemon.c193
-rw-r--r--dbus/sd-daemon.h59
92 files changed, 3519 insertions, 1997 deletions
diff --git a/dbus/.gitignore b/dbus/.gitignore
index 34eace4d..fd91ccee 100644
--- a/dbus/.gitignore
+++ b/dbus/.gitignore
@@ -4,7 +4,7 @@ Makefile
Makefile.in
*.lo
*.la
-dbus-test
+test-dbus
*.bb
*.bbg
*.gcov
diff --git a/dbus/Makefile.am b/dbus/Makefile.am
index bb5cccaf..b2481073 100644
--- a/dbus/Makefile.am
+++ b/dbus/Makefile.am
@@ -12,6 +12,10 @@ AM_CPPFLAGS = \
-DDBUS_SESSION_CONFIG_FILE=\""$(configdir)/session.conf"\" \
$(NULL)
+# On Linux with glibc 2.17, sd-daemon.c support for POSIX message queues
+# results in an otherwise unnecessary dependency on librt. Disable it.
+AM_CPPFLAGS += -DSD_DAEMON_DISABLE_MQ
+
# if assertions are enabled, improve backtraces
AM_LDFLAGS = @R_DYNAMIC_LDFLAG@
@@ -35,7 +39,7 @@ dbus_res_ldflag = -Wl,$(dbus_res)
no_undefined = -no-undefined
export_symbols =
-libdbus_1_la_DEPENDENCIES = $(dbus_res)
+EXTRA_libdbus_1_la_DEPENDENCIES = $(dbus_res)
intllibs =
else
@@ -233,6 +237,8 @@ DBUS_SHARED_SOURCES= \
### should be underscore-prefixed but don't really need
### to be unless they move to DBUS_SHARED_SOURCES later)
DBUS_UTIL_SOURCES= \
+ dbus-asv-util.c \
+ dbus-asv-util.h \
dbus-auth-script.c \
dbus-auth-script.h \
dbus-auth-util.c \
@@ -291,22 +297,33 @@ libdbus_internal_la_CPPFLAGS = \
$(NULL)
libdbus_internal_la_LIBADD=$(LIBDBUS_LIBS) $(SYSTEMD_LIBS)
+if DBUS_WIN
+# This must be a separate convenience library, otherwise libtool notices
+# that libdbus-1 might contain C++, links it with g++ and links in libstdc++,
+# even on Unix where in fact it doesn't contain any C++. For Windows, where
+# this code is used, we don't actually need libstdc++.
+noinst_LTLIBRARIES += libdbus-init-win.la
+libdbus_init_win_la_SOURCES = dbus-init-win.cpp
+libdbus_1_la_LIBADD += libdbus-init-win.la
+libdbus_internal_la_LIBADD += libdbus-init-win.la
+endif
+
noinst_PROGRAMS =
-if DBUS_BUILD_TESTS
+if DBUS_ENABLE_EMBEDDED_TESTS
# We can't actually run this til we've reached test/
-noinst_PROGRAMS += dbus-test
+noinst_PROGRAMS += test-dbus
endif
-dbus_test_SOURCES= \
+test_dbus_SOURCES= \
dbus-test-main.c
-dbus_test_LDADD = libdbus-internal.la
+test_dbus_LDADD = libdbus-internal.la
## mop up the gcov files
clean-local:
/bin/rm *.bb *.bbg *.da *.gcov .libs/*.da .libs/*.bbg || true
update-systemd:
- curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c > sd-daemon.c
- curl http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h > sd-daemon.h
+ curl http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c > $(srcdir)/sd-daemon.c
+ curl http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h > $(srcdir)/sd-daemon.h
diff --git a/dbus/dbus-address.c b/dbus/dbus-address.c
index 90484dc1..c4cfbbe5 100644
--- a/dbus/dbus-address.c
+++ b/dbus/dbus-address.c
@@ -104,15 +104,15 @@ dbus_bool_t
_dbus_address_append_escaped (DBusString *escaped,
const DBusString *unescaped)
{
- const char *p;
- const char *end;
+ const unsigned char *p;
+ const unsigned char *end;
dbus_bool_t ret;
int orig_len;
ret = FALSE;
orig_len = _dbus_string_get_length (escaped);
- p = _dbus_string_get_const_data (unescaped);
+ p = (const unsigned char *) _dbus_string_get_const_data (unescaped);
end = p + _dbus_string_get_length (unescaped);
while (p != end)
{
@@ -648,7 +648,7 @@ dbus_address_unescape_value (const char *value,
/** @} */ /* End of public API */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -678,7 +678,9 @@ static const EscapeTest escape_tests[] = {
{ "Z", "Z" },
{ "a", "a" },
{ "i", "i" },
- { "z", "z" }
+ { "z", "z" },
+ /* Bug: https://bugs.freedesktop.org/show_bug.cgi?id=53499 */
+ { "%c3%b6", "\xc3\xb6" }
};
static const char* invalid_escaped_values[] = {
diff --git a/dbus/dbus-arch-deps.h.in b/dbus/dbus-arch-deps.h.in
index 45952cfb..dfc3589e 100644
--- a/dbus/dbus-arch-deps.h.in
+++ b/dbus/dbus-arch-deps.h.in
@@ -31,7 +31,7 @@
DBUS_BEGIN_DECLS
-#if @DBUS_HAVE_INT64@
+/* D-Bus no longer supports platforms with no 64-bit integer type. */
#define DBUS_HAVE_INT64 1
_DBUS_GNUC_EXTENSION typedef @DBUS_INT64_TYPE@ dbus_int64_t;
_DBUS_GNUC_EXTENSION typedef unsigned @DBUS_INT64_TYPE@ dbus_uint64_t;
@@ -39,12 +39,6 @@ _DBUS_GNUC_EXTENSION typedef unsigned @DBUS_INT64_TYPE@ dbus_uint64_t;
#define DBUS_INT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION @DBUS_INT64_CONSTANT@)
#define DBUS_UINT64_CONSTANT(val) (_DBUS_GNUC_EXTENSION @DBUS_UINT64_CONSTANT@)
-#else
-#undef DBUS_HAVE_INT64
-#undef DBUS_INT64_CONSTANT
-#undef DBUS_UINT64_CONSTANT
-#endif
-
typedef @DBUS_INT32_TYPE@ dbus_int32_t;
typedef unsigned @DBUS_INT32_TYPE@ dbus_uint32_t;
diff --git a/dbus/dbus-asv-util.c b/dbus/dbus-asv-util.c
new file mode 100644
index 00000000..583e41fa
--- /dev/null
+++ b/dbus/dbus-asv-util.c
@@ -0,0 +1,260 @@
+/* dbus-asv-util.c - utility functions for a{sv}
+ *
+ * Copyright © 2011-2012 Nokia Corporation
+ * Copyright © 2012-2013 Collabora Ltd.
+ *
+ * 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 <dbus/dbus.h>
+
+#include "dbus/dbus-asv-util.h"
+
+/**
+ * Convenience function to create a method-call reply whose type is a{sv}
+ * (map from string to variant).
+ *
+ * Append values with 0 or more sequences of _dbus_asv_open_entry(),
+ * appending a value to var_iter, and _dbus_asv_close_entry(),
+ * then close the a{sv} with _dbus_asv_close() or _dbus_asv_abandon().
+ *
+ * This must be paired with a call to _dbus_asv_close() or _dbus_asv_abandon().
+ *
+ * @param message a method call message
+ * @param iter an iterator which will be initialized to append to the message
+ * @param arr_iter an iterator which will be initialized to append to the array
+ * @returns a new message, or #NULL if not enough memory
+ */
+DBusMessage *
+_dbus_asv_new_method_return (DBusMessage *message,
+ DBusMessageIter *iter,
+ DBusMessageIter *arr_iter)
+{
+ DBusMessage *reply = dbus_message_new_method_return (message);
+
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append (reply, iter);
+
+ if (!dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}",
+ arr_iter))
+ {
+ dbus_message_unref (reply);
+ return NULL;
+ }
+
+ return reply;
+}
+
+/*
+ * Open a new entry in an a{sv} (map from string to variant).
+ *
+ * This must be paired with a call to either _dbus_asv_close_entry()
+ * or _dbus_asv_abandon_entry().
+ *
+ * If this function fails, the a{sv} must be abandoned, for instance
+ * with _dbus_asv_abandon().
+ *
+ * @param arr_iter the iterator which is appending to the array
+ * @param entry_iter will be initialized to append to the dict-entry
+ * @param key a UTF-8 key for the map
+ * @param type the type of the variant value, e.g. DBUS_TYPE_STRING_AS_STRING
+ * @param var_iter will be initialized to append (i.e. write) to the variant
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+static dbus_bool_t
+_dbus_asv_open_entry (DBusMessageIter *arr_iter,
+ DBusMessageIter *entry_iter,
+ const char *key,
+ const char *type,
+ DBusMessageIter *var_iter)
+{
+ if (!dbus_message_iter_open_container (arr_iter, DBUS_TYPE_DICT_ENTRY,
+ NULL, entry_iter))
+ return FALSE;
+
+ if (!dbus_message_iter_append_basic (entry_iter, DBUS_TYPE_STRING, &key))
+ {
+ dbus_message_iter_abandon_container (arr_iter, entry_iter);
+ return FALSE;
+ }
+
+ if (!dbus_message_iter_open_container (entry_iter, DBUS_TYPE_VARIANT,
+ type, var_iter))
+ {
+ dbus_message_iter_abandon_container (arr_iter, entry_iter);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Closes an a{sv} entry after successfully appending the value.
+ *
+ * If this function fails, the a{sv} must be abandoned, for instance
+ * with _dbus_asv_abandon().
+ *
+ * @param arr_iter the iterator which is appending to the array
+ * @param entry_iter the iterator appending to the dict-entry, will be closed
+ * @param var_iter the iterator appending to the variant, will be closed
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+static dbus_bool_t
+_dbus_asv_close_entry (DBusMessageIter *arr_iter,
+ DBusMessageIter *entry_iter,
+ DBusMessageIter *var_iter)
+{
+ if (!dbus_message_iter_close_container (entry_iter, var_iter))
+ {
+ dbus_message_iter_abandon_container (arr_iter, entry_iter);
+ return FALSE;
+ }
+
+ if (!dbus_message_iter_close_container (arr_iter, entry_iter))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Closes an a{sv} after successfully appending all values.
+ *
+ * If this function fails, you must abandon iter and whatever
+ * larger data structure (message, etc.) the a{sv} was embedded in.
+ *
+ * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
+ * @param arr_iter the iterator appending to the array, will be closed
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+dbus_bool_t
+_dbus_asv_close (DBusMessageIter *iter,
+ DBusMessageIter *arr_iter)
+{
+ return dbus_message_iter_close_container (iter, arr_iter);
+}
+
+/*
+ * Closes an a{sv} entry after unsuccessfully appending a value.
+ * You must also abandon the a{sv} itself (for instance with
+ * _dbus_asv_abandon()), and abandon whatever larger data structure
+ * the a{sv} was embedded in.
+ *
+ * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
+ * @param arr_iter the iterator appending to the array, will be closed
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+static void
+_dbus_asv_abandon_entry (DBusMessageIter *arr_iter,
+ DBusMessageIter *entry_iter,
+ DBusMessageIter *var_iter)
+{
+ dbus_message_iter_abandon_container (entry_iter, var_iter);
+ dbus_message_iter_abandon_container (arr_iter, entry_iter);
+}
+
+/**
+ * Closes an a{sv} after unsuccessfully appending a value.
+ *
+ * You must also abandon whatever larger data structure (message, etc.)
+ * the a{sv} was embedded in.
+ *
+ * @param iter the iterator which is appending to the message or other data structure containing the a{sv}
+ * @param arr_iter the iterator appending to the array, will be closed
+ */
+void
+_dbus_asv_abandon (DBusMessageIter *iter,
+ DBusMessageIter *arr_iter)
+{
+ dbus_message_iter_abandon_container (iter, arr_iter);
+}
+
+/**
+ * Create a new entry in an a{sv} (map from string to variant)
+ * with a 32-bit unsigned integer value.
+ *
+ * If this function fails, the a{sv} must be abandoned, for instance
+ * with _dbus_asv_abandon().
+ *
+ * @param arr_iter the iterator which is appending to the array
+ * @param key a UTF-8 key for the map
+ * @param value the value
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+dbus_bool_t
+_dbus_asv_add_uint32 (DBusMessageIter *arr_iter,
+ const char *key,
+ dbus_uint32_t value)
+{
+ DBusMessageIter entry_iter, var_iter;
+
+ if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key,
+ DBUS_TYPE_UINT32_AS_STRING, &var_iter))
+ return FALSE;
+
+ if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_UINT32,
+ &value))
+ {
+ _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
+ return FALSE;
+ }
+
+ if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Create a new entry in an a{sv} (map from string to variant)
+ * with a UTF-8 string value.
+ *
+ * If this function fails, the a{sv} must be abandoned, for instance
+ * with _dbus_asv_abandon().
+ *
+ * @param arr_iter the iterator which is appending to the array
+ * @param key a UTF-8 key for the map
+ * @param value the value
+ * @returns #TRUE on success, or #FALSE if not enough memory
+ */
+dbus_bool_t
+_dbus_asv_add_string (DBusMessageIter *arr_iter,
+ const char *key,
+ const char *value)
+{
+ DBusMessageIter entry_iter, var_iter;
+
+ if (!_dbus_asv_open_entry (arr_iter, &entry_iter, key,
+ DBUS_TYPE_STRING_AS_STRING, &var_iter))
+ return FALSE;
+
+ if (!dbus_message_iter_append_basic (&var_iter, DBUS_TYPE_STRING,
+ &value))
+ {
+ _dbus_asv_abandon_entry (arr_iter, &entry_iter, &var_iter);
+ return FALSE;
+ }
+
+ if (!_dbus_asv_close_entry (arr_iter, &entry_iter, &var_iter))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/dbus/dbus-asv-util.h b/dbus/dbus-asv-util.h
new file mode 100644
index 00000000..0337260a
--- /dev/null
+++ b/dbus/dbus-asv-util.h
@@ -0,0 +1,46 @@
+/* dbus-asv-util.h - utility functions for a{sv}
+ *
+ * Copyright © 2011-2012 Nokia Corporation
+ * Copyright © 2012-2013 Collabora Ltd.
+ *
+ * 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
+ */
+
+#ifndef DBUS_ASV_UTIL_H
+#define DBUS_ASV_UTIL_H
+
+#include <dbus/dbus-internals.h>
+
+DBUS_BEGIN_DECLS
+
+DBusMessage *_dbus_asv_new_method_return (DBusMessage *message,
+ DBusMessageIter *iter,
+ DBusMessageIter *arr_iter);
+dbus_bool_t _dbus_asv_close (DBusMessageIter *iter,
+ DBusMessageIter *arr_iter);
+void _dbus_asv_abandon (DBusMessageIter *iter,
+ DBusMessageIter *arr_iter);
+
+dbus_bool_t _dbus_asv_add_uint32 (DBusMessageIter *arr_iter,
+ const char *key,
+ dbus_uint32_t value);
+dbus_bool_t _dbus_asv_add_string (DBusMessageIter *arr_iter,
+ const char *key,
+ const char *value);
+
+#endif
diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c
index 6285e3ba..164743b0 100644
--- a/dbus/dbus-auth-script.c
+++ b/dbus/dbus-auth-script.c
@@ -22,7 +22,7 @@
*/
#include <config.h>
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-auth-script.h"
#include "dbus-auth.h"
@@ -223,7 +223,7 @@ auth_set_unix_credentials(DBusAuth *auth,
if (uid != DBUS_UID_UNSET)
_dbus_credentials_add_unix_uid (credentials, uid);
if (pid != DBUS_PID_UNSET)
- _dbus_credentials_add_unix_pid (credentials, pid);
+ _dbus_credentials_add_pid (credentials, pid);
_dbus_auth_set_credentials (auth, credentials);
@@ -584,11 +584,11 @@ _dbus_auth_script_run (const DBusString *filename)
{
_dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
_dbus_string_free (&to_send);
- _dbus_auth_return_buffer (auth, buffer, 0);
+ _dbus_auth_return_buffer (auth, buffer);
goto out;
}
- _dbus_auth_return_buffer (auth, buffer, _dbus_string_get_length (&to_send));
+ _dbus_auth_return_buffer (auth, buffer);
}
_dbus_string_free (&to_send);
@@ -800,4 +800,4 @@ _dbus_auth_script_run (const DBusString *filename)
}
/** @} */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-auth-util.c b/dbus/dbus-auth-util.c
index 776e8e27..e88d6696 100644
--- a/dbus/dbus-auth-util.c
+++ b/dbus/dbus-auth-util.c
@@ -33,7 +33,7 @@
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include "dbus-auth-script.h"
#include <stdio.h>
@@ -167,4 +167,4 @@ _dbus_auth_test (const char *test_data_dir)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
index d2c37a7a..6a07665f 100644
--- a/dbus/dbus-auth.c
+++ b/dbus/dbus-auth.c
@@ -2238,8 +2238,8 @@ process_command (DBusAuth *auth)
/**
* Creates a new auth conversation object for the server side.
- * See doc/dbus-sasl-profile.txt for full details on what
- * this object does.
+ * See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ * for full details on what this object does.
*
* @returns the new object or #NULL if no memory
*/
@@ -2284,8 +2284,8 @@ _dbus_auth_server_new (const DBusString *guid)
/**
* Creates a new auth conversation object for the client side.
- * See doc/dbus-sasl-profile.txt for full details on what
- * this object does.
+ * See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ * for full details on what this object does.
*
* @returns the new object or #NULL if no memory
*/
@@ -2533,12 +2533,10 @@ _dbus_auth_get_buffer (DBusAuth *auth,
*
* @param auth the auth conversation
* @param buffer the buffer being returned
- * @param bytes_read number of new bytes added
*/
void
_dbus_auth_return_buffer (DBusAuth *auth,
- DBusString *buffer,
- int bytes_read)
+ DBusString *buffer)
{
_dbus_assert (buffer == &auth->incoming);
_dbus_assert (auth->buffer_outstanding);
diff --git a/dbus/dbus-auth.h b/dbus/dbus-auth.h
index ae3f3647..ba1975f7 100644
--- a/dbus/dbus-auth.h
+++ b/dbus/dbus-auth.h
@@ -55,8 +55,7 @@ void _dbus_auth_bytes_sent (DBusAuth *auth,
void _dbus_auth_get_buffer (DBusAuth *auth,
DBusString **buffer);
void _dbus_auth_return_buffer (DBusAuth *auth,
- DBusString *buffer,
- int bytes_read);
+ DBusString *buffer);
void _dbus_auth_get_unused_bytes (DBusAuth *auth,
const DBusString **str);
void _dbus_auth_delete_unused_bytes (DBusAuth *auth);
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index fadc3a8b..0fd48311 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -28,6 +28,7 @@
#include "dbus-internals.h"
#include "dbus-message.h"
#include "dbus-marshal-validate.h"
+#include "dbus-misc.h"
#include "dbus-threads-internal.h"
#include "dbus-connection-internal.h"
#include "dbus-string.h"
@@ -95,19 +96,6 @@ static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
static dbus_bool_t initialized = FALSE;
-/**
- * Lock for globals in this file
- */
-_DBUS_DEFINE_GLOBAL_LOCK (bus);
-
-/**
- * Global lock covering all BusData on any connection. The bet is
- * that some lock contention is better than more memory
- * for a per-connection lock, but it's tough to imagine it mattering
- * either way.
- */
-_DBUS_DEFINE_GLOBAL_LOCK (bus_datas);
-
static void
addresses_shutdown_func (void *data)
{
@@ -192,12 +180,12 @@ init_session_address (void)
if (!retval)
return FALSE;
- /* The DBUS_SESSION_BUS_DEFAULT_ADDRESS should have really been named
- * DBUS_SESSION_BUS_FALLBACK_ADDRESS.
- */
+ /* We have a hard-coded (but compile-time-configurable) fallback address for
+ * the session bus. */
if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
bus_connection_addresses[DBUS_BUS_SESSION] =
- _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS);
+ _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
+
if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
return FALSE;
@@ -306,12 +294,6 @@ init_connections_unlocked (void)
* the above code will work right
*/
- if (!_dbus_setenv ("DBUS_ACTIVATION_ADDRESS", NULL))
- return FALSE;
-
- if (!_dbus_setenv ("DBUS_ACTIVATION_BUS_TYPE", NULL))
- return FALSE;
-
if (!_dbus_register_shutdown_func (addresses_shutdown_func,
NULL))
return FALSE;
@@ -330,7 +312,11 @@ bus_data_free (void *data)
if (bd->is_well_known)
{
int i;
- _DBUS_LOCK (bus);
+
+ if (!_DBUS_LOCK (bus))
+ _dbus_assert_not_reached ("global locks should have been initialized "
+ "when we attached bus data");
+
/* We may be stored in more than one slot */
/* This should now be impossible - these slots are supposed to
* be cleared on disconnect, so should not need to be cleared on
@@ -401,8 +387,13 @@ void
_dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
{
int i;
-
- _DBUS_LOCK (bus);
+
+ if (!_DBUS_LOCK (bus))
+ {
+ /* If it was in bus_connections, we would have initialized global locks
+ * when we added it. So, it can't be. */
+ return;
+ }
/* We are expecting to have the connection saved in only one of these
* slots, but someone could in a pathological case set system and session
@@ -436,7 +427,12 @@ internal_bus_get (DBusBusType type,
connection = NULL;
- _DBUS_LOCK (bus);
+ if (!_DBUS_LOCK (bus))
+ {
+ _DBUS_SET_OOM (error);
+ /* do not "goto out", that would try to unlock */
+ return NULL;
+ }
if (!init_connections_unlocked ())
{
@@ -506,8 +502,10 @@ internal_bus_get (DBusBusType type,
*/
dbus_connection_set_exit_on_disconnect (connection,
TRUE);
-
- _DBUS_LOCK (bus_datas);
+
+ if (!_DBUS_LOCK (bus_datas))
+ _dbus_assert_not_reached ("global locks were initialized already");
+
bd = ensure_bus_data (connection);
_dbus_assert (bd != NULL); /* it should have been created on
register, so OOM not possible */
@@ -554,7 +552,7 @@ out:
*
* @param type bus type
* @param error address where an error can be returned.
- * @returns a #DBusConnection with new ref
+ * @returns a #DBusConnection with new ref or #NULL on error
*/
DBusConnection *
dbus_bus_get (DBusBusType type,
@@ -660,7 +658,12 @@ dbus_bus_register (DBusConnection *connection,
message = NULL;
reply = NULL;
- _DBUS_LOCK (bus_datas);
+ if (!_DBUS_LOCK (bus_datas))
+ {
+ _DBUS_SET_OOM (error);
+ /* do not "goto out", that would try to unlock */
+ return FALSE;
+ }
bd = ensure_bus_data (connection);
if (bd == NULL)
@@ -769,8 +772,12 @@ dbus_bus_set_unique_name (DBusConnection *connection,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (unique_name != NULL, FALSE);
- _DBUS_LOCK (bus_datas);
-
+ if (!_DBUS_LOCK (bus_datas))
+ {
+ /* do not "goto out", that would try to unlock */
+ return FALSE;
+ }
+
bd = ensure_bus_data (connection);
if (bd == NULL)
goto out;
@@ -812,8 +819,13 @@ dbus_bus_get_unique_name (DBusConnection *connection)
_dbus_return_val_if_fail (connection != NULL, NULL);
- _DBUS_LOCK (bus_datas);
-
+ if (!_DBUS_LOCK (bus_datas))
+ {
+ /* We'd have initialized locks when we gave it its unique name, if it
+ * had one. Don't "goto out", that would try to unlock. */
+ return NULL;
+ }
+
bd = ensure_bus_data (connection);
if (bd == NULL)
goto out;
diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
index 3d37f188..2842f2f4 100644
--- a/dbus/dbus-connection-internal.h
+++ b/dbus/dbus-connection-internal.h
@@ -115,7 +115,7 @@ void _dbus_connection_get_stats (DBusConnection *connection,
dbus_uint32_t *out_peak_fds);
-/* if DBUS_BUILD_TESTS */
+/* if DBUS_ENABLE_EMBEDDED_TESTS */
const char* _dbus_connection_get_address (DBusConnection *connection);
/* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index ee33b6cc..f0b6871e 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -203,26 +203,19 @@
* @{
*/
-#ifdef DBUS_ENABLE_VERBOSE_MODE
static void
_dbus_connection_trace_ref (DBusConnection *connection,
int old_refcount,
int new_refcount,
const char *why)
{
+#ifdef DBUS_ENABLE_VERBOSE_MODE
static int enabled = -1;
_dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
why, "DBUS_CONNECTION_TRACE", &enabled);
-}
-#else
-#define _dbus_connection_trace_ref(c,o,n,w) \
- do \
- {\
- (void) (o); \
- (void) (n); \
- } while (0)
#endif
+}
/**
* Internal struct representing a message filter function
@@ -336,8 +329,8 @@ struct DBusConnection
#ifndef DBUS_DISABLE_CHECKS
unsigned int have_connection_lock : 1; /**< Used to check locking */
#endif
-
-#ifndef DBUS_DISABLE_CHECKS
+
+#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
int generation; /**< _dbus_current_generation that should correspond to this connection */
#endif
};
@@ -446,7 +439,7 @@ _dbus_connection_wakeup_mainloop (DBusConnection *connection)
(*connection->wakeup_main_function) (connection->wakeup_main_data);
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Gets the locks so we can examine them
*
@@ -490,9 +483,9 @@ _dbus_connection_queue_received_message_link (DBusConnection *connection,
DBusPendingCall *pending;
dbus_uint32_t reply_serial;
DBusMessage *message;
-
- _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
-
+
+ _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
+
_dbus_list_append_link (&connection->incoming_messages,
link);
message = link->data;
@@ -1354,7 +1347,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
connection->disconnected_message_arrived = FALSE;
connection->disconnected_message_processed = FALSE;
-#ifndef DBUS_DISABLE_CHECKS
+#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
connection->generation = _dbus_current_generation;
#endif
@@ -1531,7 +1524,7 @@ _dbus_connection_handle_watch (DBusWatch *watch,
return retval;
}
-_DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
+/* Protected by _DBUS_LOCK (shared_connections) */
static DBusHashTable *shared_connections = NULL;
static DBusList *shared_connections_no_guid = NULL;
@@ -1555,9 +1548,14 @@ static void
shared_connections_shutdown (void *data)
{
int n_entries;
-
- _DBUS_LOCK (shared_connections);
-
+
+ if (!_DBUS_LOCK (shared_connections))
+ {
+ /* We'd have initialized locks before adding anything, so there
+ * can't be anything there. */
+ return;
+ }
+
/* This is a little bit unpleasant... better ideas? */
while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
{
@@ -1571,7 +1569,8 @@ shared_connections_shutdown (void *data)
_DBUS_UNLOCK (shared_connections);
close_connection_on_shutdown (connection);
- _DBUS_LOCK (shared_connections);
+ if (!_DBUS_LOCK (shared_connections))
+ _dbus_assert_not_reached ("global locks were already initialized");
/* The connection should now be dead and not in our hash ... */
_dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
@@ -1590,7 +1589,8 @@ shared_connections_shutdown (void *data)
{
_DBUS_UNLOCK (shared_connections);
close_connection_on_shutdown (connection);
- _DBUS_LOCK (shared_connections);
+ if (!_DBUS_LOCK (shared_connections))
+ _dbus_assert_not_reached ("global locks were already initialized");
connection = _dbus_list_pop_first (&shared_connections_no_guid);
}
}
@@ -1607,8 +1607,13 @@ connection_lookup_shared (DBusAddressEntry *entry,
_dbus_verbose ("checking for existing connection\n");
*result = NULL;
-
- _DBUS_LOCK (shared_connections);
+
+ if (!_DBUS_LOCK (shared_connections))
+ {
+ /* If it was shared, we'd have initialized global locks when we put
+ * it in shared_connections. */
+ return FALSE;
+ }
if (shared_connections == NULL)
{
@@ -1706,7 +1711,8 @@ connection_record_shared_unlocked (DBusConnection *connection,
if (guid == NULL)
{
- _DBUS_LOCK (shared_connections);
+ if (!_DBUS_LOCK (shared_connections))
+ return FALSE;
if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
{
@@ -1733,8 +1739,14 @@ connection_record_shared_unlocked (DBusConnection *connection,
dbus_free (guid_key);
return FALSE;
}
-
- _DBUS_LOCK (shared_connections);
+
+ if (!_DBUS_LOCK (shared_connections))
+ {
+ dbus_free (guid_in_connection);
+ dbus_free (guid_key);
+ return FALSE;
+ }
+
_dbus_assert (shared_connections != NULL);
if (!_dbus_hash_table_insert_string (shared_connections,
@@ -1765,9 +1777,14 @@ connection_forget_shared_unlocked (DBusConnection *connection)
if (!connection->shareable)
return;
-
- _DBUS_LOCK (shared_connections);
-
+
+ if (!_DBUS_LOCK (shared_connections))
+ {
+ /* If it was shared, we'd have initialized global locks when we put
+ * it in the table; so it can't be there. */
+ return;
+ }
+
if (connection->server_guid != NULL)
{
_dbus_verbose ("dropping connection to %s out of the shared table\n",
@@ -2150,7 +2167,7 @@ _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
* relatively long time for memory, if they were only willing to block
* briefly then we retry for memory at a rapid rate.
*
- * @timeout_milliseconds the timeout requested for blocking
+ * @param timeout_milliseconds the timeout requested for blocking
*/
static void
_dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
@@ -2683,6 +2700,7 @@ _dbus_connection_last_unref (DBusConnection *connection)
dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
+ dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
_dbus_watch_list_free (connection->watches);
connection->watches = NULL;
@@ -2952,9 +2970,9 @@ dbus_connection_get_is_authenticated (DBusConnection *connection)
dbus_bool_t res;
_dbus_return_val_if_fail (connection != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- res = _dbus_transport_get_is_authenticated (connection->transport);
+ res = _dbus_transport_try_to_authenticate (connection->transport);
CONNECTION_UNLOCK (connection);
return res;
@@ -3938,7 +3956,7 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
link = _dbus_list_pop_first_link (&connection->incoming_messages);
connection->n_incoming -= 1;
- _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
+ _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
link->data,
dbus_message_type_to_string (dbus_message_get_type (link->data)),
dbus_message_get_path (link->data) ?
@@ -3951,6 +3969,7 @@ _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
dbus_message_get_member (link->data) :
"no member",
dbus_message_get_signature (link->data),
+ dbus_message_get_serial (link->data),
connection, connection->n_incoming);
_dbus_message_trace_ref (link->data, -1, -1,
@@ -5148,10 +5167,10 @@ dbus_connection_get_unix_user (DBusConnection *connection,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (uid != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_unix_user (connection->transport,
@@ -5184,10 +5203,10 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (pid != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_unix_process_id (connection->transport,
@@ -5205,7 +5224,8 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
* connection.
*
* @param connection the connection
- * @param data return location for audit data
+ * @param data return location for audit data
+ * @param data_size return location for length of audit data
* @returns #TRUE if audit data is filled in with a valid ucred pointer
*/
dbus_bool_t
@@ -5218,10 +5238,10 @@ dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (data != NULL, FALSE);
_dbus_return_val_if_fail (data_size != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_adt_audit_session_data (connection->transport,
@@ -5314,10 +5334,10 @@ dbus_connection_get_windows_user (DBusConnection *connection,
_dbus_return_val_if_fail (connection != NULL, FALSE);
_dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
-
+
CONNECTION_LOCK (connection);
- if (!_dbus_transport_get_is_authenticated (connection->transport))
+ if (!_dbus_transport_try_to_authenticate (connection->transport))
result = FALSE;
else
result = _dbus_transport_get_windows_user (connection->transport,
@@ -5435,7 +5455,7 @@ dbus_connection_set_route_peer_messages (DBusConnection *connection,
_dbus_return_if_fail (connection != NULL);
CONNECTION_LOCK (connection);
- connection->route_peer_messages = TRUE;
+ connection->route_peer_messages = value;
CONNECTION_UNLOCK (connection);
}
@@ -5852,8 +5872,8 @@ dbus_connection_list_registered (DBusConnection *connection,
return retval;
}
-static DBusDataSlotAllocator slot_allocator;
-_DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
+static DBusDataSlotAllocator slot_allocator =
+ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
/**
* Allocates an integer ID to be used for storing application-specific
@@ -5873,7 +5893,6 @@ dbus_bool_t
dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
{
return _dbus_data_slot_allocator_alloc (&slot_allocator,
- &_DBUS_LOCK_NAME (connection_slots),
slot_p);
}
@@ -5974,7 +5993,8 @@ dbus_connection_get_data (DBusConnection *connection,
void *res;
_dbus_return_val_if_fail (connection != NULL, NULL);
-
+ _dbus_return_val_if_fail (slot >= 0, NULL);
+
SLOTS_LOCK (connection);
res = _dbus_data_slot_list_get (&slot_allocator,
@@ -6043,7 +6063,7 @@ dbus_connection_get_max_message_size (DBusConnection *connection)
* result in disconnecting the connection.
*
* @param connection a #DBusConnection
- * @param size maximum message unix fds the connection can receive
+ * @param n maximum message unix fds the connection can receive
*/
void
dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
@@ -6141,7 +6161,7 @@ dbus_connection_get_max_received_size (DBusConnection *connection)
* The semantics are analogous to those of dbus_connection_set_max_received_size().
*
* @param connection the connection
- * @param size the maximum size in bytes of all outstanding messages
+ * @param n the maximum size in bytes of all outstanding messages
*/
void
dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
@@ -6258,7 +6278,7 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
return res;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Returns the address of the transport object of this connection
*
diff --git a/dbus/dbus-credentials-util.c b/dbus/dbus-credentials-util.c
index 02771966..d2d164f7 100644
--- a/dbus/dbus-credentials-util.c
+++ b/dbus/dbus-credentials-util.c
@@ -33,14 +33,14 @@
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
#include <string.h>
static DBusCredentials*
make_credentials(dbus_uid_t unix_uid,
- dbus_pid_t unix_pid,
+ dbus_pid_t pid,
const char *windows_sid)
{
DBusCredentials *credentials;
@@ -56,9 +56,9 @@ make_credentials(dbus_uid_t unix_uid,
}
}
- if (unix_pid != DBUS_PID_UNSET)
+ if (pid != DBUS_PID_UNSET)
{
- if (!_dbus_credentials_add_unix_pid (credentials, unix_pid))
+ if (!_dbus_credentials_add_pid (credentials, pid))
{
_dbus_credentials_unref (credentials);
return NULL;
@@ -102,7 +102,7 @@ _dbus_credentials_test (const char *test_data_dir)
_dbus_assert (_dbus_credentials_include (creds, DBUS_CREDENTIAL_WINDOWS_SID));
_dbus_assert (_dbus_credentials_get_unix_uid (creds) == 12);
- _dbus_assert (_dbus_credentials_get_unix_pid (creds) == 511);
+ _dbus_assert (_dbus_credentials_get_pid (creds) == 511);
_dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds), SAMPLE_SID) == 0);
_dbus_assert (!_dbus_credentials_are_empty (creds));
@@ -118,7 +118,7 @@ _dbus_credentials_test (const char *test_data_dir)
_dbus_assert (_dbus_credentials_include (creds2, DBUS_CREDENTIAL_WINDOWS_SID));
_dbus_assert (_dbus_credentials_get_unix_uid (creds2) == 12);
- _dbus_assert (_dbus_credentials_get_unix_pid (creds2) == 511);
+ _dbus_assert (_dbus_credentials_get_pid (creds2) == 511);
_dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds2), SAMPLE_SID) == 0);
_dbus_assert (_dbus_credentials_are_superset (creds, creds2));
@@ -192,7 +192,7 @@ _dbus_credentials_test (const char *test_data_dir)
_dbus_assert (!_dbus_credentials_include (creds, DBUS_CREDENTIAL_WINDOWS_SID));
_dbus_assert (_dbus_credentials_get_unix_uid (creds) == DBUS_UID_UNSET);
- _dbus_assert (_dbus_credentials_get_unix_pid (creds) == DBUS_PID_UNSET);
+ _dbus_assert (_dbus_credentials_get_pid (creds) == DBUS_PID_UNSET);
_dbus_assert (_dbus_credentials_get_windows_sid (creds) == NULL);
_dbus_assert (_dbus_credentials_are_empty (creds));
@@ -203,4 +203,4 @@ _dbus_credentials_test (const char *test_data_dir)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c
index ff69f3b0..7325125c 100644
--- a/dbus/dbus-credentials.c
+++ b/dbus/dbus-credentials.c
@@ -48,7 +48,7 @@
struct DBusCredentials {
int refcount;
dbus_uid_t unix_uid;
- dbus_pid_t unix_pid;
+ dbus_pid_t pid;
char *windows_sid;
void *adt_audit_data;
dbus_int32_t adt_audit_data_size;
@@ -77,7 +77,7 @@ _dbus_credentials_new (void)
creds->refcount = 1;
creds->unix_uid = DBUS_UID_UNSET;
- creds->unix_pid = DBUS_PID_UNSET;
+ creds->pid = DBUS_PID_UNSET;
creds->windows_sid = NULL;
creds->adt_audit_data = NULL;
creds->adt_audit_data_size = 0;
@@ -146,10 +146,10 @@ _dbus_credentials_unref (DBusCredentials *credentials)
* @returns #FALSE if no memory
*/
dbus_bool_t
-_dbus_credentials_add_unix_pid (DBusCredentials *credentials,
- dbus_pid_t pid)
+_dbus_credentials_add_pid (DBusCredentials *credentials,
+ dbus_pid_t pid)
{
- credentials->unix_pid = pid;
+ credentials->pid = pid;
return TRUE;
}
@@ -231,7 +231,7 @@ _dbus_credentials_include (DBusCredentials *credentials,
switch (type)
{
case DBUS_CREDENTIAL_UNIX_PROCESS_ID:
- return credentials->unix_pid != DBUS_PID_UNSET;
+ return credentials->pid != DBUS_PID_UNSET;
case DBUS_CREDENTIAL_UNIX_USER_ID:
return credentials->unix_uid != DBUS_UID_UNSET;
case DBUS_CREDENTIAL_WINDOWS_SID:
@@ -252,9 +252,9 @@ _dbus_credentials_include (DBusCredentials *credentials,
* @returns UNIX process ID
*/
dbus_pid_t
-_dbus_credentials_get_unix_pid (DBusCredentials *credentials)
+_dbus_credentials_get_pid (DBusCredentials *credentials)
{
- return credentials->unix_pid;
+ return credentials->pid;
}
/**
@@ -322,8 +322,8 @@ _dbus_credentials_are_superset (DBusCredentials *credentials,
DBusCredentials *possible_subset)
{
return
- (possible_subset->unix_pid == DBUS_PID_UNSET ||
- possible_subset->unix_pid == credentials->unix_pid) &&
+ (possible_subset->pid == DBUS_PID_UNSET ||
+ possible_subset->pid == credentials->pid) &&
(possible_subset->unix_uid == DBUS_UID_UNSET ||
possible_subset->unix_uid == credentials->unix_uid) &&
(possible_subset->windows_sid == NULL ||
@@ -345,7 +345,7 @@ dbus_bool_t
_dbus_credentials_are_empty (DBusCredentials *credentials)
{
return
- credentials->unix_pid == DBUS_PID_UNSET &&
+ credentials->pid == DBUS_PID_UNSET &&
credentials->unix_uid == DBUS_UID_UNSET &&
credentials->windows_sid == NULL &&
credentials->adt_audit_data == NULL;
@@ -410,9 +410,9 @@ _dbus_credentials_add_credential (DBusCredentials *credentials,
DBusCredentials *other_credentials)
{
if (which == DBUS_CREDENTIAL_UNIX_PROCESS_ID &&
- other_credentials->unix_pid != DBUS_PID_UNSET)
+ other_credentials->pid != DBUS_PID_UNSET)
{
- if (!_dbus_credentials_add_unix_pid (credentials, other_credentials->unix_pid))
+ if (!_dbus_credentials_add_pid (credentials, other_credentials->pid))
return FALSE;
}
else if (which == DBUS_CREDENTIAL_UNIX_USER_ID &&
@@ -445,7 +445,7 @@ _dbus_credentials_add_credential (DBusCredentials *credentials,
void
_dbus_credentials_clear (DBusCredentials *credentials)
{
- credentials->unix_pid = DBUS_PID_UNSET;
+ credentials->pid = DBUS_PID_UNSET;
credentials->unix_uid = DBUS_UID_UNSET;
dbus_free (credentials->windows_sid);
credentials->windows_sid = NULL;
@@ -523,9 +523,9 @@ _dbus_credentials_to_string_append (DBusCredentials *credentials,
goto oom;
join = TRUE;
}
- if (credentials->unix_pid != DBUS_PID_UNSET)
+ if (credentials->pid != DBUS_PID_UNSET)
{
- if (!_dbus_string_append_printf (string, "%spid=" DBUS_PID_FORMAT, join ? " " : "", credentials->unix_pid))
+ if (!_dbus_string_append_printf (string, "%spid=" DBUS_PID_FORMAT, join ? " " : "", credentials->pid))
goto oom;
join = TRUE;
}
diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h
index ef6124fd..abcc4bb3 100644
--- a/dbus/dbus-credentials.h
+++ b/dbus/dbus-credentials.h
@@ -41,7 +41,7 @@ DBusCredentials* _dbus_credentials_new_from_current_process (void);
DBusCredentials* _dbus_credentials_new (void);
void _dbus_credentials_ref (DBusCredentials *credentials);
void _dbus_credentials_unref (DBusCredentials *credentials);
-dbus_bool_t _dbus_credentials_add_unix_pid (DBusCredentials *credentials,
+dbus_bool_t _dbus_credentials_add_pid (DBusCredentials *credentials,
dbus_pid_t pid);
dbus_bool_t _dbus_credentials_add_unix_uid (DBusCredentials *credentials,
dbus_uid_t uid);
@@ -52,7 +52,7 @@ dbus_bool_t _dbus_credentials_add_adt_audit_data (DBusCredentials
dbus_int32_t size);
dbus_bool_t _dbus_credentials_include (DBusCredentials *credentials,
DBusCredentialType type);
-dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials);
+dbus_pid_t _dbus_credentials_get_pid (DBusCredentials *credentials);
dbus_uid_t _dbus_credentials_get_unix_uid (DBusCredentials *credentials);
const char* _dbus_credentials_get_windows_sid (DBusCredentials *credentials);
void * _dbus_credentials_get_adt_audit_data (DBusCredentials *credentials);
diff --git a/dbus/dbus-dataslot.c b/dbus/dbus-dataslot.c
index 0369612e..e37c9dd5 100644
--- a/dbus/dbus-dataslot.c
+++ b/dbus/dbus-dataslot.c
@@ -43,13 +43,14 @@
* @param allocator the allocator to initialize
*/
dbus_bool_t
-_dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator)
+_dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator,
+ DBusGlobalLock lock)
{
allocator->allocated_slots = NULL;
allocator->n_allocated_slots = 0;
allocator->n_used_slots = 0;
- allocator->lock_loc = NULL;
-
+ allocator->lock = lock;
+
return TRUE;
}
@@ -61,29 +62,17 @@ _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator)
* is allocated and stored at *slot_id_p.
*
* @param allocator the allocator
- * @param mutex_loc the location lock for this allocator
* @param slot_id_p address to fill with the slot ID
* @returns #TRUE on success
*/
dbus_bool_t
_dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
- DBusRMutex **mutex_loc,
dbus_int32_t *slot_id_p)
{
dbus_int32_t slot;
- _dbus_rmutex_lock (*mutex_loc);
-
- if (allocator->n_allocated_slots == 0)
- {
- _dbus_assert (allocator->lock_loc == NULL);
- allocator->lock_loc = mutex_loc;
- }
- else if (allocator->lock_loc != mutex_loc)
- {
- _dbus_warn_check_failed ("D-Bus threads were initialized after first using the D-Bus library. If your application does not directly initialize threads or use D-Bus, keep in mind that some library or plugin may have used D-Bus or initialized threads behind your back. You can often fix this problem by calling dbus_init_threads() or dbus_g_threads_init() early in your main() method, before D-Bus is used.\n");
- _dbus_assert_not_reached ("exiting");
- }
+ if (!_dbus_lock (allocator->lock))
+ return FALSE;
if (*slot_id_p >= 0)
{
@@ -146,7 +135,7 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots);
out:
- _dbus_rmutex_unlock (*(allocator->lock_loc));
+ _dbus_unlock (allocator->lock);
return slot >= 0;
}
@@ -165,8 +154,10 @@ void
_dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
dbus_int32_t *slot_id_p)
{
- _dbus_rmutex_lock (*(allocator->lock_loc));
-
+ if (!_dbus_lock (allocator->lock))
+ _dbus_assert_not_reached ("we should have initialized global locks "
+ "before we allocated this slot");
+
_dbus_assert (*slot_id_p < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[*slot_id_p].slot_id == *slot_id_p);
_dbus_assert (allocator->allocated_slots[*slot_id_p].refcount > 0);
@@ -175,7 +166,7 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
if (allocator->allocated_slots[*slot_id_p].refcount > 0)
{
- _dbus_rmutex_unlock (*(allocator->lock_loc));
+ _dbus_unlock (allocator->lock);
return;
}
@@ -190,19 +181,12 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
if (allocator->n_used_slots == 0)
{
- DBusRMutex **mutex_loc = allocator->lock_loc;
-
dbus_free (allocator->allocated_slots);
allocator->allocated_slots = NULL;
allocator->n_allocated_slots = 0;
- allocator->lock_loc = NULL;
-
- _dbus_rmutex_unlock (*mutex_loc);
- }
- else
- {
- _dbus_rmutex_unlock (*(allocator->lock_loc));
}
+
+ _dbus_unlock (allocator->lock);
}
/**
@@ -247,10 +231,13 @@ _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator,
* be e.g. realloc()ing allocated_slots. We avoid doing this if asserts
* are disabled, since then the asserts are empty.
*/
- _dbus_rmutex_lock (*(allocator->lock_loc));
+ if (!_dbus_lock (allocator->lock))
+ _dbus_assert_not_reached ("we should have initialized global locks "
+ "before we allocated this slot");
+
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
- _dbus_rmutex_unlock (*(allocator->lock_loc));
+ _dbus_unlock (allocator->lock);
#endif
if (slot >= list->n_slots)
@@ -304,11 +291,14 @@ _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator,
* be e.g. realloc()ing allocated_slots. We avoid doing this if asserts
* are disabled, since then the asserts are empty.
*/
- _dbus_rmutex_lock (*(allocator->lock_loc));
+ if (!_dbus_lock (allocator->lock))
+ _dbus_assert_not_reached ("we should have initialized global locks "
+ "before we allocated this slot");
+
_dbus_assert (slot >= 0);
_dbus_assert (slot < allocator->n_allocated_slots);
_dbus_assert (allocator->allocated_slots[slot].slot_id == slot);
- _dbus_rmutex_unlock (*(allocator->lock_loc));
+ _dbus_unlock (allocator->lock);
#endif
if (slot >= list->n_slots)
@@ -358,7 +348,7 @@ _dbus_data_slot_list_free (DBusDataSlotList *list)
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -384,17 +374,12 @@ _dbus_data_slot_test (void)
int i;
DBusFreeFunction old_free_func;
void *old_data;
- DBusRMutex *mutex;
-
- if (!_dbus_data_slot_allocator_init (&allocator))
+
+ if (!_dbus_data_slot_allocator_init (&allocator, _DBUS_LOCK_server_slots))
_dbus_assert_not_reached ("no memory for allocator");
_dbus_data_slot_list_init (&list);
- _dbus_rmutex_new_at_location (&mutex);
- if (mutex == NULL)
- _dbus_assert_not_reached ("failed to alloc mutex");
-
#define N_SLOTS 100
i = 0;
@@ -405,8 +390,8 @@ _dbus_data_slot_test (void)
* here.
*/
dbus_int32_t tmp = -1;
-
- _dbus_data_slot_allocator_alloc (&allocator, &mutex, &tmp);
+
+ _dbus_data_slot_allocator_alloc (&allocator, &tmp);
if (tmp != i)
_dbus_assert_not_reached ("did not allocate slots in numeric order\n");
@@ -471,9 +456,7 @@ _dbus_data_slot_test (void)
++i;
}
- _dbus_rmutex_free_at_location (&mutex);
-
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-dataslot.h b/dbus/dbus-dataslot.h
index 3d9d5edd..1e04fcbc 100644
--- a/dbus/dbus-dataslot.h
+++ b/dbus/dbus-dataslot.h
@@ -57,9 +57,11 @@ struct DBusDataSlotAllocator
DBusAllocatedSlot *allocated_slots; /**< Allocated slots */
int n_allocated_slots; /**< number of slots malloc'd */
int n_used_slots; /**< number of slots used */
- DBusRMutex **lock_loc; /**< location of thread lock */
+ DBusGlobalLock lock; /**< index of thread lock */
};
+#define _DBUS_DATA_SLOT_ALLOCATOR_INIT(x) { NULL, 0, 0, x }
+
/**
* Data structure that stores the actual user data set at a given
* slot.
@@ -70,9 +72,9 @@ struct DBusDataSlotList
int n_slots; /**< Slots we have storage for in data_slots */
};
-dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator);
+dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator,
+ DBusGlobalLock lock);
dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator,
- DBusRMutex **mutex_loc,
int *slot_id_p);
void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator,
int *slot_id_p);
diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c
index db3305b9..a0571a50 100644
--- a/dbus/dbus-errors.c
+++ b/dbus/dbus-errors.c
@@ -235,7 +235,7 @@ dbus_error_free (DBusError *error)
* must ensure the name and message are global data that won't be
* freed. You probably want dbus_set_error() instead, in most cases.
*
- * @param error the error.or #NULL
+ * @param error the error or #NULL
* @param name the error name (not copied!!!)
* @param message the error message (not copied!!!)
*/
@@ -379,7 +379,6 @@ dbus_set_error (DBusError *error,
message_from_error (name)))
{
_dbus_string_free (&str);
- va_end (args);
goto nomem;
}
}
diff --git a/dbus/dbus-hash.c b/dbus/dbus-hash.c
index c4c6f935..c80835aa 100644
--- a/dbus/dbus-hash.c
+++ b/dbus/dbus-hash.c
@@ -1401,7 +1401,7 @@ _dbus_hash_table_get_n_entries (DBusHashTable *table)
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -1828,4 +1828,4 @@ _dbus_hash_test (void)
return ret;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-init-win.cpp b/dbus/dbus-init-win.cpp
new file mode 100644
index 00000000..687f248c
--- /dev/null
+++ b/dbus/dbus-init-win.cpp
@@ -0,0 +1,52 @@
+/*
+ * dbus-init-win.cpp - once-per-process initialization
+ *
+ * Copyright © 2013 Intel Corporation
+ *
+ * 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>
+
+extern "C"
+{
+#include "dbus-sysdeps-win.h"
+}
+
+class DBusInternalInit
+ {
+ public:
+ DBusInternalInit ()
+ {
+ _dbus_threads_windows_init_global ();
+ }
+
+ void must_not_be_omitted ()
+ {
+ }
+ };
+
+static DBusInternalInit init;
+
+extern "C" void
+_dbus_threads_windows_ensure_ctor_linked ()
+{
+ /* Do nothing significant, just ensure that the global initializer gets
+ * linked in. */
+ init.must_not_be_omitted ();
+}
diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c
index 0e5d807e..e2482597 100644
--- a/dbus/dbus-internals.c
+++ b/dbus/dbus-internals.c
@@ -163,26 +163,11 @@
*/
/**
- * @def _DBUS_DEFINE_GLOBAL_LOCK
- *
- * Defines a global lock variable with the given name.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
- * @def _DBUS_DECLARE_GLOBAL_LOCK
- *
- * Expands to declaration of a global lock defined
- * with _DBUS_DEFINE_GLOBAL_LOCK.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
* @def _DBUS_LOCK
*
- * Locks a global lock
+ * Locks a global lock, initializing it first if necessary.
+ *
+ * @returns #FALSE if not enough memory
*/
/**
@@ -347,25 +332,22 @@ _dbus_verbose_init (void)
*/
static char *_dbus_file_path_extract_elements_from_tail(const char *file,int level)
{
- static int prefix = -1;
+ int prefix = 0;
+ char *p = (char *)file + strlen(file);
+ int i = 0;
- if (prefix == -1)
+ for (;p >= file;p--)
{
- char *p = (char *)file + strlen(file);
- int i = 0;
- prefix = 0;
- for (;p >= file;p--)
+ if (DBUS_IS_DIR_SEPARATOR(*p))
{
- if (DBUS_IS_DIR_SEPARATOR(*p))
+ if (++i >= level)
{
- if (++i >= level)
- {
- prefix = p-file+1;
- break;
- }
- }
- }
+ prefix = p-file+1;
+ break;
+ }
+ }
}
+
return (char *)file+prefix;
}
@@ -847,7 +829,7 @@ _dbus_read_uuid_file (const DBusString *filename,
}
}
-_DBUS_DEFINE_GLOBAL_LOCK (machine_uuid);
+/* Protected by _DBUS_LOCK (machine_uuid) */
static int machine_uuid_initialized_generation = 0;
static DBusGUID machine_uuid;
@@ -866,7 +848,9 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
{
dbus_bool_t ok;
- _DBUS_LOCK (machine_uuid);
+ if (!_DBUS_LOCK (machine_uuid))
+ return FALSE;
+
if (machine_uuid_initialized_generation != _dbus_current_generation)
{
DBusError error = DBUS_ERROR_INIT;
@@ -874,7 +858,7 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE,
&error))
{
-#ifndef DBUS_BUILD_TESTS
+#ifndef DBUS_ENABLE_EMBEDDED_TESTS
/* For the test suite, we may not be installed so just continue silently
* here. But in a production build, we want to be nice and loud about
* this.
@@ -953,7 +937,7 @@ _dbus_real_assert_not_reached (const char *explanation,
}
#endif /* DBUS_DISABLE_ASSERT */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static dbus_bool_t
run_failing_each_malloc (int n_mallocs,
const char *description,
@@ -1048,6 +1032,6 @@ _dbus_test_oom_handling (const char *description,
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/** @} */
diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h
index 8036a2ba..c5a3c9b8 100644
--- a/dbus/dbus-internals.h
+++ b/dbus/dbus-internals.h
@@ -35,10 +35,6 @@
DBUS_BEGIN_DECLS
-#ifndef DBUS_SESSION_BUS_DEFAULT_ADDRESS
-#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
-#endif
-
void _dbus_warn (const char *format,
...) _DBUS_GNUC_PRINTF (1, 2);
@@ -234,10 +230,8 @@ char** _dbus_dup_string_array (const char **array);
#define _DBUS_INT_MIN _DBUS_INT32_MIN
#define _DBUS_INT_MAX _DBUS_INT32_MAX
#define _DBUS_UINT_MAX _DBUS_UINT32_MAX
-#ifdef DBUS_HAVE_INT64
#define _DBUS_INT64_MAX DBUS_INT64_CONSTANT (0x7fffffffffffffff)
#define _DBUS_UINT64_MAX DBUS_UINT64_CONSTANT (0xffffffffffffffff)
-#endif
#define _DBUS_ONE_KILOBYTE 1024
#define _DBUS_ONE_MEGABYTE 1024 * _DBUS_ONE_KILOBYTE
#define _DBUS_ONE_HOUR_IN_MILLISECONDS (1000 * 60 * 60)
@@ -270,7 +264,7 @@ void _dbus_verbose_bytes_of_string (const DBusString *str,
extern const char *_dbus_no_memory_message;
#define _DBUS_SET_OOM(error) dbus_set_error_const ((error), DBUS_ERROR_NO_MEMORY, _dbus_no_memory_message)
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/* Memory debugging */
void _dbus_set_fail_alloc_counter (int until_next_fail);
int _dbus_get_fail_alloc_counter (void);
@@ -294,45 +288,46 @@ dbus_bool_t _dbus_test_oom_handling (const char *description,
#define _dbus_decrement_fail_alloc_counter() (FALSE)
#define _dbus_disable_mem_pools() (FALSE)
#define _dbus_get_malloc_blocks_outstanding (0)
-#endif /* !DBUS_BUILD_TESTS */
+#endif /* !DBUS_ENABLE_EMBEDDED_TESTS */
typedef void (* DBusShutdownFunction) (void *data);
-dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function,
- void *data);
+dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function,
+ void *data);
+dbus_bool_t _dbus_register_shutdown_func_unlocked (DBusShutdownFunction function,
+ void *data);
extern int _dbus_current_generation;
-/* Thread initializers */
-#define _DBUS_LOCK_NAME(name) _dbus_lock_##name
-#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusRMutex *_dbus_lock_##name
-#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusRMutex *_dbus_lock_##name
-#define _DBUS_LOCK(name) _dbus_rmutex_lock (_dbus_lock_##name)
-#define _DBUS_UNLOCK(name) _dbus_rmutex_unlock (_dbus_lock_##name)
-
-/* 1-5 */
-_DBUS_DECLARE_GLOBAL_LOCK (list);
-_DBUS_DECLARE_GLOBAL_LOCK (connection_slots);
-_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);
-_DBUS_DECLARE_GLOBAL_LOCK (server_slots);
-_DBUS_DECLARE_GLOBAL_LOCK (message_slots);
-/* 5-10 */
-_DBUS_DECLARE_GLOBAL_LOCK (bus);
-_DBUS_DECLARE_GLOBAL_LOCK (bus_datas);
-_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);
-_DBUS_DECLARE_GLOBAL_LOCK (system_users);
-_DBUS_DECLARE_GLOBAL_LOCK (message_cache);
-/* 10-14 */
-_DBUS_DECLARE_GLOBAL_LOCK (shared_connections);
-_DBUS_DECLARE_GLOBAL_LOCK (win_fds);
-_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);
-_DBUS_DECLARE_GLOBAL_LOCK (machine_uuid);
-
-#if !DBUS_USE_SYNC
-_DBUS_DECLARE_GLOBAL_LOCK (atomic);
-#define _DBUS_N_GLOBAL_LOCKS (15)
-#else
-#define _DBUS_N_GLOBAL_LOCKS (14)
-#endif
+/* The weird case convention is to avoid having to change all the callers,
+ * which would be quite a mega-patch. */
+typedef enum
+{
+ /* index 0-4 */
+ _DBUS_LOCK_list,
+ _DBUS_LOCK_connection_slots,
+ _DBUS_LOCK_pending_call_slots,
+ _DBUS_LOCK_server_slots,
+ _DBUS_LOCK_message_slots,
+ /* index 5-9 */
+ _DBUS_LOCK_bus,
+ _DBUS_LOCK_bus_datas,
+ _DBUS_LOCK_shutdown_funcs,
+ _DBUS_LOCK_system_users,
+ _DBUS_LOCK_message_cache,
+ /* index 10-12 */
+ _DBUS_LOCK_shared_connections,
+ _DBUS_LOCK_machine_uuid,
+ _DBUS_LOCK_sysdeps,
+
+ _DBUS_N_GLOBAL_LOCKS
+} DBusGlobalLock;
+
+dbus_bool_t _dbus_lock (DBusGlobalLock lock) _DBUS_GNUC_WARN_UNUSED_RESULT;
+void _dbus_unlock (DBusGlobalLock lock);
+
+#define _DBUS_LOCK_NAME(name) _DBUS_LOCK_##name
+#define _DBUS_LOCK(name) _dbus_lock (_DBUS_LOCK_##name)
+#define _DBUS_UNLOCK(name) _dbus_unlock (_DBUS_LOCK_##name)
dbus_bool_t _dbus_threads_init_debug (void);
diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c
index 23b9df5a..f0c64de3 100644
--- a/dbus/dbus-keyring.c
+++ b/dbus/dbus-keyring.c
@@ -80,7 +80,7 @@
* Maximum number of keys in the keyring before
* we just ignore the rest
*/
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#define MAX_KEYS_IN_FILE 10
#else
#define MAX_KEYS_IN_FILE 256
@@ -697,10 +697,10 @@ _dbus_keyring_unref (DBusKeyring *keyring)
/**
* Creates a new keyring that lives in the ~/.dbus-keyrings directory
- * of the given user credentials. If the credentials are #NULL or
- * empty, uses those of the current process.
+ * of the user represented by @p credentials. If the @p credentials are
+ * #NULL or empty, uses those of the current process.
*
- * @param username username to get keyring for, or #NULL
+ * @param credentials a set of credentials representing a user or #NULL
* @param context which keyring to get
* @param error return location for errors
* @returns the keyring or #NULL on error
@@ -717,6 +717,13 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
DBusCredentials *our_credentials;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to create DBus keyring when setuid");
+ return NULL;
+ }
keyring = NULL;
error_set = FALSE;
@@ -1016,7 +1023,7 @@ _dbus_keyring_get_hex_key (DBusKeyring *keyring,
/** @} */ /* end of exposed API */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -1149,5 +1156,5 @@ _dbus_keyring_test (void)
return FALSE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c
index 7e11cc8d..c4c1856f 100644
--- a/dbus/dbus-list.c
+++ b/dbus/dbus-list.c
@@ -35,8 +35,8 @@
* Types and functions related to DBusList.
*/
+/* Protected by _DBUS_LOCK (list) */
static DBusMemPool *list_pool;
-_DBUS_DEFINE_GLOBAL_LOCK (list);
/**
* @defgroup DBusListInternals Linked list implementation details
@@ -56,7 +56,8 @@ alloc_link (void *data)
{
DBusList *link;
- _DBUS_LOCK (list);
+ if (!_DBUS_LOCK (list))
+ return FALSE;
if (list_pool == NULL)
{
@@ -93,7 +94,10 @@ alloc_link (void *data)
static void
free_link (DBusList *link)
{
- _DBUS_LOCK (list);
+ if (!_DBUS_LOCK (list))
+ _dbus_assert_not_reached ("we should have initialized global locks "
+ "before we allocated a linked-list link");
+
if (_dbus_mem_pool_dealloc (list_pool, link))
{
_dbus_mem_pool_free (list_pool);
@@ -152,7 +156,14 @@ _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);
+ if (!_DBUS_LOCK (list))
+ {
+ *in_use_p = 0;
+ *in_free_list_p = 0;
+ *allocated_p = 0;
+ return;
+ }
+
_dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p);
_DBUS_UNLOCK (list);
}
@@ -777,7 +788,7 @@ _dbus_list_length_is_one (DBusList **list)
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
diff --git a/dbus/dbus-macros.h b/dbus/dbus-macros.h
index dcd3eebd..cae4100e 100644
--- a/dbus/dbus-macros.h
+++ b/dbus/dbus-macros.h
@@ -88,13 +88,21 @@
#define DBUS_ALLOC_SIZE2(x,y)
#endif
+#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define _DBUS_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define _DBUS_GNUC_WARN_UNUSED_RESULT
+#endif
+
/** @def _DBUS_GNUC_PRINTF
* used to tell gcc about printf format strings
*/
/** @def _DBUS_GNUC_NORETURN
* used to tell gcc about functions that never return, such as _dbus_abort()
*/
-
+/** @def _DBUS_GNUC_WARN_UNUSED_RESULT
+ * used to tell gcc about functions whose result must be used
+ */
/* Normally docs are in .c files, but there isn't a .c file for this. */
/**
diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c
index cef676a3..7ff9dc2c 100644
--- a/dbus/dbus-mainloop.c
+++ b/dbus/dbus-mainloop.c
@@ -34,27 +34,6 @@
#define MAINLOOP_SPEW 0
-#if MAINLOOP_SPEW
-#ifdef DBUS_ENABLE_VERBOSE_MODE
-static const char*
-watch_flags_to_string (int flags)
-{
- const char *watch_type;
-
- if ((flags & DBUS_WATCH_READABLE) &&
- (flags & DBUS_WATCH_WRITABLE))
- watch_type = "readwrite";
- else if (flags & DBUS_WATCH_READABLE)
- watch_type = "read";
- else if (flags & DBUS_WATCH_WRITABLE)
- watch_type = "write";
- else
- watch_type = "not read or write";
- return watch_type;
-}
-#endif /* DBUS_ENABLE_VERBOSE_MODE */
-#endif /* MAINLOOP_SPEW */
-
struct DBusLoop
{
int refcount;
@@ -675,7 +654,7 @@ _dbus_loop_iterate (DBusLoop *loop,
timeout = MIN (timeout, _dbus_get_oom_wait ());
#if MAINLOOP_SPEW
- _dbus_verbose (" polling on %d descriptors timeout %ld\n", n_fds, timeout);
+ _dbus_verbose (" polling on %d descriptors timeout %ld\n", _DBUS_N_ELEMENTS (ready_fds), timeout);
#endif
n_ready = _dbus_socket_set_poll (loop->socket_set, ready_fds,
@@ -922,7 +901,7 @@ _dbus_loop_quit (DBusLoop *loop)
int
_dbus_get_oom_wait (void)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/* make tests go fast */
return 0;
#else
diff --git a/dbus/dbus-marshal-basic.c b/dbus/dbus-marshal-basic.c
index 88b19f36..eafc2a9a 100644
--- a/dbus/dbus-marshal-basic.c
+++ b/dbus/dbus-marshal-basic.c
@@ -58,12 +58,10 @@ _DBUS_ASSERT_ALIGNMENT (dbus_bool_t, <=, 4);
_DBUS_STATIC_ASSERT (sizeof (double) == 8);
_DBUS_ASSERT_ALIGNMENT (double, <=, 8);
-#ifdef DBUS_HAVE_INT64
_DBUS_STATIC_ASSERT (sizeof (dbus_int64_t) == 8);
_DBUS_ASSERT_ALIGNMENT (dbus_int64_t, <=, 8);
_DBUS_STATIC_ASSERT (sizeof (dbus_uint64_t) == 8);
_DBUS_ASSERT_ALIGNMENT (dbus_uint64_t, <=, 8);
-#endif
_DBUS_STATIC_ASSERT (sizeof (DBusBasicValue) >= 8);
/* The alignment of a DBusBasicValue might conceivably be > 8 because of the
@@ -120,15 +118,10 @@ pack_8_octets (DBusBasicValue value,
{
_dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
-#ifdef DBUS_HAVE_INT64
if ((byte_order) == DBUS_LITTLE_ENDIAN)
*((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_LE (value.u64);
else
*((dbus_uint64_t*)(data)) = DBUS_UINT64_TO_BE (value.u64);
-#else
- *(DBus8ByteStruct*)data = value.eight;
- swap_8_octets ((DBusBasicValue*)data, byte_order);
-#endif
}
/**
@@ -146,65 +139,16 @@ _dbus_pack_uint32 (dbus_uint32_t value,
pack_4_octets (value, byte_order, data);
}
-#ifndef DBUS_HAVE_INT64
-/* from ORBit */
-static void
-swap_bytes (unsigned char *data,
- unsigned int len)
-{
- unsigned char *p1 = data;
- unsigned char *p2 = data + len - 1;
-
- while (p1 < p2)
- {
- unsigned char tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
-
- --p2;
- ++p1;
- }
-}
-#endif /* !DBUS_HAVE_INT64 */
-
static void
swap_8_octets (DBusBasicValue *value,
int byte_order)
{
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
{
-#ifdef DBUS_HAVE_INT64
value->u64 = DBUS_UINT64_SWAP_LE_BE (value->u64);
-#else
- swap_bytes (&value->bytes, 8);
-#endif
}
}
-#if 0
-static DBusBasicValue
-unpack_8_octets (int byte_order,
- const unsigned char *data)
-{
- DBusBasicValue r;
-
- _dbus_assert (_DBUS_ALIGN_ADDRESS (data, 8) == data);
- _dbus_assert (sizeof (r) == 8);
-
-#ifdef DBUS_HAVE_INT64
- if (byte_order == DBUS_LITTLE_ENDIAN)
- r.u64 = DBUS_UINT64_FROM_LE (*(dbus_uint64_t*)data);
- else
- r.u64 = DBUS_UINT64_FROM_BE (*(dbus_uint64_t*)data);
-#else
- r.eight = *(DBus8ByteStruct*)data;
- swap_8_octets (&r, byte_order);
-#endif
-
- return r;
-}
-#endif
-
#ifndef _dbus_unpack_uint16
/**
* Unpacks a 16 bit unsigned integer from a data pointer
@@ -601,15 +545,10 @@ _dbus_marshal_read_basic (const DBusString *str,
{
volatile dbus_uint64_t *vp = value;
pos = _DBUS_ALIGN_VALUE (pos, 8);
-#ifdef DBUS_HAVE_INT64
if (byte_order != DBUS_COMPILER_BYTE_ORDER)
*vp = DBUS_UINT64_SWAP_LE_BE (*(dbus_uint64_t*)(str_data + pos));
else
*vp = *(dbus_uint64_t*)(str_data + pos);
-#else
- *vp = *(DBus8ByteStruct*) (str_data + pos);
- swap_8_octets (vp, byte_order);
-#endif
pos += 8;
}
break;
@@ -965,11 +904,7 @@ _dbus_swap_array (unsigned char *data,
{
while (d != end)
{
-#ifdef DBUS_HAVE_INT64
*((dbus_uint64_t*)d) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)d));
-#else
- swap_8_bytes ((DBusBasicValue*) d);
-#endif
d += 8;
}
}
@@ -1501,7 +1436,7 @@ _dbus_first_type_in_signature_c_str (const char *str,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -1674,12 +1609,10 @@ _dbus_marshal_test (void)
unsigned char array1[5] = { 3, 4, 0, 1, 9 };
dbus_int16_t array2[3] = { 124, 457, 780 };
dbus_int32_t array4[3] = { 123, 456, 789 };
-#ifdef DBUS_HAVE_INT64
dbus_int64_t array8[3] = { DBUS_INT64_CONSTANT (0x123ffffffff),
DBUS_INT64_CONSTANT (0x456ffffffff),
DBUS_INT64_CONSTANT (0x789ffffffff) };
dbus_int64_t *v_ARRAY_INT64;
-#endif
unsigned char *v_ARRAY_BYTE;
dbus_int16_t *v_ARRAY_INT16;
dbus_uint16_t *v_ARRAY_UINT16;
@@ -1735,7 +1668,6 @@ _dbus_marshal_test (void)
MARSHAL_TEST (UINT32, DBUS_BIG_ENDIAN, 0x12345678);
MARSHAL_TEST (UINT32, DBUS_LITTLE_ENDIAN, 0x12345678);
-#ifdef DBUS_HAVE_INT64
/* Marshal signed integers */
MARSHAL_TEST (INT64, DBUS_BIG_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
MARSHAL_TEST (INT64, DBUS_LITTLE_ENDIAN, DBUS_INT64_CONSTANT (-0x123456789abc7));
@@ -1743,7 +1675,6 @@ _dbus_marshal_test (void)
/* Marshal unsigned integers */
MARSHAL_TEST (UINT64, DBUS_BIG_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
MARSHAL_TEST (UINT64, DBUS_LITTLE_ENDIAN, DBUS_UINT64_CONSTANT (0x123456789abc7));
-#endif /* DBUS_HAVE_INT64 */
/* Marshal byte */
MARSHAL_TEST (BYTE, DBUS_BIG_ENDIAN, 5);
@@ -1785,10 +1716,8 @@ _dbus_marshal_test (void)
MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_BIG_ENDIAN, array1);
MARSHAL_TEST_FIXED_ARRAY (BYTE, DBUS_LITTLE_ENDIAN, array1);
-#ifdef DBUS_HAVE_INT64
MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_BIG_ENDIAN, array8);
MARSHAL_TEST_FIXED_ARRAY (INT64, DBUS_LITTLE_ENDIAN, array8);
-#endif
#if 0
@@ -1796,7 +1725,6 @@ _dbus_marshal_test (void)
* FIXME restore the set/pack tests
*/
-#ifdef DBUS_HAVE_INT64
/* set/pack 64-bit integers */
_dbus_string_set_length (&str, 8);
@@ -1867,7 +1795,6 @@ _dbus_marshal_test (void)
_dbus_assert (DBUS_UINT64_CONSTANT (0x123456789abc7) ==
_dbus_unpack_uint64 (DBUS_BIG_ENDIAN,
_dbus_string_get_const_data (&str)));
-#endif /* DBUS_HAVE_INT64 */
/* set/pack 32-bit integers */
_dbus_string_set_length (&str, 4);
@@ -1992,4 +1919,4 @@ _dbus_marshal_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-marshal-basic.h b/dbus/dbus-marshal-basic.h
index 034fdaba..9df67cb8 100644
--- a/dbus/dbus-marshal-basic.h
+++ b/dbus/dbus-marshal-basic.h
@@ -57,8 +57,6 @@
#endif /* HAVE_BYTESWAP_H */
-#ifdef DBUS_HAVE_INT64
-
#ifdef HAVE_BYTESWAP_H
#define DBUS_UINT64_SWAP_LE_BE_CONSTANT(val) bswap_64(val)
#else /* HAVE_BYTESWAP_H */
@@ -80,7 +78,6 @@
(dbus_uint64_t) DBUS_UINT64_CONSTANT (0x00ff000000000000)) >> 40) | \
(((dbus_uint64_t) (val) & \
(dbus_uint64_t) DBUS_UINT64_CONSTANT (0xff00000000000000)) >> 56)))
-#endif /* DBUS_HAVE_INT64 */
#endif /* HAVE_BYTESWAP_H */
@@ -90,10 +87,8 @@
#define DBUS_UINT32_SWAP_LE_BE(val) (DBUS_UINT32_SWAP_LE_BE_CONSTANT (val))
#define DBUS_INT32_SWAP_LE_BE(val) ((dbus_int32_t)DBUS_UINT32_SWAP_LE_BE_CONSTANT (val))
-#ifdef DBUS_HAVE_INT64
-# define DBUS_UINT64_SWAP_LE_BE(val) (DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
-# define DBUS_INT64_SWAP_LE_BE(val) ((dbus_int64_t)DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
-#endif /* DBUS_HAVE_INT64 */
+#define DBUS_UINT64_SWAP_LE_BE(val) (DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
+#define DBUS_INT64_SWAP_LE_BE(val) ((dbus_int64_t)DBUS_UINT64_SWAP_LE_BE_CONSTANT (val))
#ifdef WORDS_BIGENDIAN
@@ -105,12 +100,10 @@
# define DBUS_UINT32_TO_BE(val) ((dbus_uint32_t) (val))
# define DBUS_INT32_TO_LE(val) (DBUS_INT32_SWAP_LE_BE (val))
# define DBUS_UINT32_TO_LE(val) (DBUS_UINT32_SWAP_LE_BE (val))
-# ifdef DBUS_HAVE_INT64
-# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) (val))
-# define DBUS_UINT64_TO_BE(val) ((dbus_uint64_t) (val))
-# define DBUS_INT64_TO_LE(val) (DBUS_INT64_SWAP_LE_BE (val))
-# define DBUS_UINT64_TO_LE(val) (DBUS_UINT64_SWAP_LE_BE (val))
-# endif /* DBUS_HAVE_INT64 */
+# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) (val))
+# define DBUS_UINT64_TO_BE(val) ((dbus_uint64_t) (val))
+# define DBUS_INT64_TO_LE(val) (DBUS_INT64_SWAP_LE_BE (val))
+# define DBUS_UINT64_TO_LE(val) (DBUS_UINT64_SWAP_LE_BE (val))
#else /* WORDS_BIGENDIAN */
@@ -122,12 +115,10 @@
# define DBUS_UINT32_TO_LE(val) ((dbus_uint32_t) (val))
# define DBUS_INT32_TO_BE(val) ((dbus_int32_t) DBUS_UINT32_SWAP_LE_BE (val))
# define DBUS_UINT32_TO_BE(val) (DBUS_UINT32_SWAP_LE_BE (val))
-# ifdef DBUS_HAVE_INT64
-# define DBUS_INT64_TO_LE(val) ((dbus_int64_t) (val))
-# define DBUS_UINT64_TO_LE(val) ((dbus_uint64_t) (val))
-# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) DBUS_UINT64_SWAP_LE_BE (val))
-# define DBUS_UINT64_TO_BE(val) (DBUS_UINT64_SWAP_LE_BE (val))
-# endif /* DBUS_HAVE_INT64 */
+# define DBUS_INT64_TO_LE(val) ((dbus_int64_t) (val))
+# define DBUS_UINT64_TO_LE(val) ((dbus_uint64_t) (val))
+# define DBUS_INT64_TO_BE(val) ((dbus_int64_t) DBUS_UINT64_SWAP_LE_BE (val))
+# define DBUS_UINT64_TO_BE(val) (DBUS_UINT64_SWAP_LE_BE (val))
#endif
/* The transformation is symmetric, so the FROM just maps to the TO. */
@@ -139,12 +130,10 @@
#define DBUS_UINT32_FROM_LE(val) (DBUS_UINT32_TO_LE (val))
#define DBUS_INT32_FROM_BE(val) (DBUS_INT32_TO_BE (val))
#define DBUS_UINT32_FROM_BE(val) (DBUS_UINT32_TO_BE (val))
-#ifdef DBUS_HAVE_INT64
-# define DBUS_INT64_FROM_LE(val) (DBUS_INT64_TO_LE (val))
-# define DBUS_UINT64_FROM_LE(val) (DBUS_UINT64_TO_LE (val))
-# define DBUS_INT64_FROM_BE(val) (DBUS_INT64_TO_BE (val))
-# define DBUS_UINT64_FROM_BE(val) (DBUS_UINT64_TO_BE (val))
-#endif /* DBUS_HAVE_INT64 */
+#define DBUS_INT64_FROM_LE(val) (DBUS_INT64_TO_LE (val))
+#define DBUS_UINT64_FROM_LE(val) (DBUS_UINT64_TO_LE (val))
+#define DBUS_INT64_FROM_BE(val) (DBUS_INT64_TO_BE (val))
+#define DBUS_UINT64_FROM_BE(val) (DBUS_UINT64_TO_BE (val))
#ifdef DBUS_DISABLE_ASSERT
#define _dbus_unpack_uint16(byte_order, data) \
diff --git a/dbus/dbus-marshal-byteswap-util.c b/dbus/dbus-marshal-byteswap-util.c
index edb74cad..57874859 100644
--- a/dbus/dbus-marshal-byteswap-util.c
+++ b/dbus/dbus-marshal-byteswap-util.c
@@ -23,7 +23,7 @@
#include <config.h>
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-marshal-byteswap.h"
#include "dbus-test.h"
#include <stdio.h>
@@ -102,4 +102,4 @@ _dbus_marshal_byteswap_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-marshal-byteswap.c b/dbus/dbus-marshal-byteswap.c
index 22d7e22b..e6711be6 100644
--- a/dbus/dbus-marshal-byteswap.c
+++ b/dbus/dbus-marshal-byteswap.c
@@ -73,11 +73,7 @@ byteswap_body_helper (DBusTypeReader *reader,
case DBUS_TYPE_DOUBLE:
{
p = _DBUS_ALIGN_ADDRESS (p, 8);
-#ifdef DBUS_HAVE_INT64
*((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
-#else
- _dbus_swap_array (p, 1, 8);
-#endif
p += 8;
}
break;
diff --git a/dbus/dbus-marshal-header.c b/dbus/dbus-marshal-header.c
index 88887a82..48151c62 100644
--- a/dbus/dbus-marshal-header.c
+++ b/dbus/dbus-marshal-header.c
@@ -276,6 +276,7 @@ _dbus_header_cache_known_nonexistent (DBusHeader *header,
* Writes a struct of { byte, variant } with the given basic type.
*
* @param writer the writer (should be ready to write a struct)
+ * @param field the header field
* @param type the type of the value
* @param value the value as for _dbus_marshal_set_basic()
* @returns #FALSE if no memory
@@ -336,6 +337,7 @@ write_basic_field (DBusTypeWriter *writer,
* Sets a struct of { byte, variant } with the given basic type.
*
* @param reader the reader (should be iterating over the array pointing at the field to set)
+ * @param field the header field
* @param type the type of the value
* @param value the value as for _dbus_marshal_set_basic()
* @param realign_root where to realign from
@@ -452,7 +454,6 @@ _dbus_header_reinit (DBusHeader *header)
* to make the header valid, you have to call _dbus_header_create().
*
* @param header header to initialize
- * @param byte_order byte order of the header
* @returns #FALSE if not enough memory
*/
dbus_bool_t
@@ -514,6 +515,7 @@ _dbus_header_copy (const DBusHeader *header,
* sense, and passing them in will trigger an assertion failure.
*
* @param header the header
+ * @param byte_order byte order of the header
* @param message_type the message type
* @param destination destination field or #NULL
* @param path path field or #NULL
diff --git a/dbus/dbus-marshal-recursive-util.c b/dbus/dbus-marshal-recursive-util.c
index 95124140..0e2b4201 100644
--- a/dbus/dbus-marshal-recursive-util.c
+++ b/dbus/dbus-marshal-recursive-util.c
@@ -23,7 +23,7 @@
#include <config.h>
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-marshal-recursive.h"
#include "dbus-marshal-basic.h"
@@ -34,13 +34,7 @@
static void
basic_value_zero (DBusBasicValue *value)
{
-
-#ifdef DBUS_HAVE_INT64
value->u64 = 0;
-#else
- value->eight.first32 = 0;
- value->eight.second32 = 0;
-#endif
}
static dbus_bool_t
@@ -56,12 +50,7 @@ basic_value_equal (int type,
}
else
{
-#ifdef DBUS_HAVE_INT64
return lhs->u64 == rhs->u64;
-#else
- return lhs->eight.first32 == rhs->eight.first32 &&
- lhs->eight.second32 == rhs->eight.second32;
-#endif
}
}
@@ -1785,10 +1774,13 @@ make_and_run_test_nodes (void)
start_next_test ("All values in one big toplevel %d iteration\n", 1);
{
TestTypeNode *nodes[N_VALUES];
+ TestTypeNode *node;
i = 0;
- while ((nodes[i] = value_generator (&i)))
- ;
+ while ((node = value_generator (&i)))
+ {
+ nodes[i - 1] = node;
+ }
run_test_nodes (nodes, N_VALUES);
@@ -2337,7 +2329,6 @@ int32_read_multi (TestTypeNode *node,
return TRUE;
}
-#ifdef DBUS_HAVE_INT64
static dbus_int64_t
int64_from_seed (int seed)
{
@@ -2351,7 +2342,6 @@ int64_from_seed (int seed)
return v;
}
-#endif
static dbus_bool_t
int64_write_value (TestTypeNode *node,
@@ -2359,7 +2349,6 @@ int64_write_value (TestTypeNode *node,
DBusTypeWriter *writer,
int seed)
{
-#ifdef DBUS_HAVE_INT64
/* also used for uint64 */
dbus_int64_t v;
@@ -2368,9 +2357,6 @@ int64_write_value (TestTypeNode *node,
return _dbus_type_writer_write_basic (writer,
node->klass->typecode,
&v);
-#else
- return TRUE;
-#endif
}
static dbus_bool_t
@@ -2378,7 +2364,6 @@ int64_read_value (TestTypeNode *node,
DBusTypeReader *reader,
int seed)
{
-#ifdef DBUS_HAVE_INT64
/* also used for uint64 */
dbus_int64_t v;
@@ -2390,9 +2375,6 @@ int64_read_value (TestTypeNode *node,
_dbus_assert (v == int64_from_seed (seed));
return TRUE;
-#else
- return TRUE;
-#endif
}
static dbus_bool_t
@@ -2401,7 +2383,6 @@ int64_set_value (TestTypeNode *node,
DBusTypeReader *realign_root,
int seed)
{
-#ifdef DBUS_HAVE_INT64
/* also used for uint64 */
dbus_int64_t v;
@@ -2410,9 +2391,6 @@ int64_set_value (TestTypeNode *node,
return _dbus_type_reader_set_basic (reader,
&v,
realign_root);
-#else
- return TRUE;
-#endif
}
#define MAX_SAMPLE_STRING_LEN 10
@@ -3574,4 +3552,4 @@ container_destroy (TestTypeNode *node)
#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-marshal-validate-util.c b/dbus/dbus-marshal-validate-util.c
index 81135bcf..d52cb6d8 100644
--- a/dbus/dbus-marshal-validate-util.c
+++ b/dbus/dbus-marshal-validate-util.c
@@ -22,7 +22,7 @@
*/
#include <config.h>
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -585,4 +585,4 @@ _dbus_marshal_validate_test (void)
#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c
index a033b540..22e80727 100644
--- a/dbus/dbus-memory.c
+++ b/dbus/dbus-memory.c
@@ -26,6 +26,7 @@
#include "dbus-internals.h"
#include "dbus-sysdeps.h"
#include "dbus-list.h"
+#include "dbus-threads.h"
#include <stdlib.h>
/**
@@ -96,7 +97,7 @@
* @{
*/
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static dbus_bool_t debug_initialized = FALSE;
static int fail_nth = -1;
static size_t fail_size = 0;
@@ -239,7 +240,7 @@ _dbus_get_fail_alloc_failures (void)
return n_failures_per_failure;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Called when about to alloc some memory; if
* it returns #TRUE, then the allocation should
@@ -293,7 +294,7 @@ _dbus_decrement_fail_alloc_counter (void)
return FALSE;
}
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/**
* Get the number of outstanding malloc()'d blocks.
@@ -459,7 +460,7 @@ set_guards (void *real_block,
void*
dbus_malloc (size_t bytes)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
_dbus_initialize_malloc_debug ();
if (_dbus_decrement_fail_alloc_counter ())
@@ -471,7 +472,7 @@ dbus_malloc (size_t bytes)
if (bytes == 0) /* some system mallocs handle this, some don't */
return NULL;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
else if (fail_size != 0 && bytes > fail_size)
return NULL;
else if (guards)
@@ -498,7 +499,7 @@ dbus_malloc (size_t bytes)
void *mem;
mem = malloc (bytes);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (mem)
{
_dbus_atomic_inc (&n_blocks_outstanding);
@@ -529,7 +530,7 @@ dbus_malloc (size_t bytes)
void*
dbus_malloc0 (size_t bytes)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
_dbus_initialize_malloc_debug ();
if (_dbus_decrement_fail_alloc_counter ())
@@ -542,7 +543,7 @@ dbus_malloc0 (size_t bytes)
if (bytes == 0)
return NULL;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
else if (fail_size != 0 && bytes > fail_size)
return NULL;
else if (guards)
@@ -570,7 +571,7 @@ dbus_malloc0 (size_t bytes)
void *mem;
mem = calloc (bytes, 1);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (mem)
{
_dbus_atomic_inc (&n_blocks_outstanding);
@@ -600,7 +601,7 @@ void*
dbus_realloc (void *memory,
size_t bytes)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
_dbus_initialize_malloc_debug ();
if (_dbus_decrement_fail_alloc_counter ())
@@ -616,7 +617,7 @@ dbus_realloc (void *memory,
dbus_free (memory);
return NULL;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
else if (fail_size != 0 && bytes > fail_size)
return NULL;
else if (guards)
@@ -676,7 +677,7 @@ dbus_realloc (void *memory,
void *mem;
mem = realloc (memory, bytes);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (mem == NULL && malloc_cannot_fail)
{
_dbus_warn ("out of memory: malloc (%ld)\n", (long) bytes);
@@ -699,7 +700,7 @@ dbus_realloc (void *memory,
void
dbus_free (void *memory)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (guards)
{
check_guards (memory, TRUE);
@@ -723,7 +724,7 @@ dbus_free (void *memory)
if (memory) /* we guarantee it's safe to free (NULL) */
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#ifdef DBUS_DISABLE_ASSERT
_dbus_atomic_dec (&n_blocks_outstanding);
#else
@@ -794,7 +795,7 @@ struct ShutdownClosure
void *data; /**< Data for function */
};
-_DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs);
+/* Protected by _DBUS_LOCK (shutdown_funcs) */
static ShutdownClosure *registered_globals = NULL;
/**
@@ -809,6 +810,20 @@ dbus_bool_t
_dbus_register_shutdown_func (DBusShutdownFunction func,
void *data)
{
+ dbus_bool_t ok;
+
+ if (!_DBUS_LOCK (shutdown_funcs))
+ return FALSE;
+
+ ok = _dbus_register_shutdown_func_unlocked (func, data);
+ _DBUS_UNLOCK (shutdown_funcs);
+ return ok;
+}
+
+dbus_bool_t
+_dbus_register_shutdown_func_unlocked (DBusShutdownFunction func,
+ void *data)
+{
ShutdownClosure *c;
c = dbus_new (ShutdownClosure, 1);
@@ -819,13 +834,9 @@ _dbus_register_shutdown_func (DBusShutdownFunction func,
c->func = func;
c->data = data;
- _DBUS_LOCK (shutdown_funcs);
-
c->next = registered_globals;
registered_globals = c;
- _DBUS_UNLOCK (shutdown_funcs);
-
return TRUE;
}
@@ -845,7 +856,7 @@ _dbus_register_shutdown_func (DBusShutdownFunction func,
* can be useful to free these internal data structures.
*
* dbus_shutdown() does NOT free memory that was returned
- * to the application. It only returns libdbus-internal
+ * to the application. It only frees libdbus-internal
* data structures.
*
* You MUST free all memory and release all reference counts
@@ -890,12 +901,18 @@ dbus_shutdown (void)
dbus_free (c);
}
+ /* We wrap this in the thread-initialization lock because
+ * dbus_threads_init() uses the current generation to tell whether
+ * we're initialized, so we need to make sure that un-initializing
+ * propagates into all threads. */
+ _dbus_threads_lock_platform_specific ();
_dbus_current_generation += 1;
+ _dbus_threads_unlock_platform_specific ();
}
/** @} */ /** End of public API docs block */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
/**
diff --git a/dbus/dbus-mempool.c b/dbus/dbus-mempool.c
index 33aabf9c..52466151 100644
--- a/dbus/dbus-mempool.c
+++ b/dbus/dbus-mempool.c
@@ -173,7 +173,7 @@ _dbus_mem_pool_new (int element_size,
_dbus_assert ((pool->block_size %
pool->element_size) == 0);
- VALGRIND_CREATE_MEMPOOL (pool, 0, zero_elements)
+ VALGRIND_CREATE_MEMPOOL (pool, 0, zero_elements);
return pool;
}
@@ -188,7 +188,7 @@ _dbus_mem_pool_free (DBusMemPool *pool)
{
DBusMemBlock *block;
- VALGRIND_DESTROY_MEMPOOL (pool)
+ VALGRIND_DESTROY_MEMPOOL (pool);
block = pool->blocks;
while (block != NULL)
@@ -213,7 +213,7 @@ _dbus_mem_pool_free (DBusMemPool *pool)
void*
_dbus_mem_pool_alloc (DBusMemPool *pool)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (_dbus_disable_mem_pools ())
{
DBusMemBlock *block;
@@ -241,7 +241,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
pool->allocated_elements += 1;
VALGRIND_MEMPOOL_ALLOC (pool, (void *) &block->elements[0],
- pool->element_size)
+ pool->element_size);
return (void*) &block->elements[0];
}
else
@@ -261,7 +261,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
pool->free_elements = pool->free_elements->next;
- VALGRIND_MEMPOOL_ALLOC (pool, element, pool->element_size)
+ VALGRIND_MEMPOOL_ALLOC (pool, element, pool->element_size);
if (pool->zero_elements)
memset (element, '\0', pool->element_size);
@@ -280,7 +280,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
/* Need a new block */
DBusMemBlock *block;
int alloc_size;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
int saved_counter;
#endif
@@ -294,7 +294,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING + pool->block_size;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/* We save/restore the counter, so that memory pools won't
* cause a given function to have different number of
* allocations on different invocations. i.e. when testing
@@ -310,7 +310,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
else
block = dbus_malloc (alloc_size);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
_dbus_set_fail_alloc_counter (saved_counter);
_dbus_assert (saved_counter == _dbus_get_fail_alloc_counter ());
#endif
@@ -329,7 +329,7 @@ _dbus_mem_pool_alloc (DBusMemPool *pool)
pool->allocated_elements += 1;
- VALGRIND_MEMPOOL_ALLOC (pool, element, pool->element_size)
+ VALGRIND_MEMPOOL_ALLOC (pool, element, pool->element_size);
return element;
}
}
@@ -347,9 +347,9 @@ dbus_bool_t
_dbus_mem_pool_dealloc (DBusMemPool *pool,
void *element)
{
- VALGRIND_MEMPOOL_FREE (pool, element)
+ VALGRIND_MEMPOOL_FREE (pool, element);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (_dbus_disable_mem_pools ())
{
DBusMemBlock *block;
@@ -393,7 +393,7 @@ _dbus_mem_pool_dealloc (DBusMemPool *pool,
freed = element;
/* used for internal mempool administration */
- VALGRIND_MAKE_MEM_UNDEFINED (freed, sizeof (freed));
+ VALGRIND_MAKE_MEM_UNDEFINED (freed, sizeof (*freed));
freed->next = pool->free_elements;
pool->free_elements = freed;
@@ -449,7 +449,7 @@ _dbus_mem_pool_get_stats (DBusMemPool *pool,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
#include <time.h>
@@ -459,8 +459,10 @@ time_for_size (int size)
{
int i;
int j;
+#ifdef DBUS_ENABLE_VERBOSE_MODE
clock_t start;
clock_t end;
+#endif
#define FREE_ARRAY_SIZE 512
#define N_ITERATIONS FREE_ARRAY_SIZE * 512
void *to_free[FREE_ARRAY_SIZE];
@@ -470,8 +472,10 @@ time_for_size (int size)
_dbus_verbose (" malloc\n");
+#ifdef DBUS_ENABLE_VERBOSE_MODE
start = clock ();
-
+#endif
+
i = 0;
j = 0;
while (i < N_ITERATIONS)
@@ -496,6 +500,7 @@ time_for_size (int size)
++i;
}
+#ifdef DBUS_ENABLE_VERBOSE_MODE
end = clock ();
_dbus_verbose (" created/destroyed %d elements in %g seconds\n",
@@ -506,6 +511,7 @@ time_for_size (int size)
_dbus_verbose (" mempools\n");
start = clock ();
+#endif
pool = _dbus_mem_pool_new (size, FALSE);
@@ -535,6 +541,7 @@ time_for_size (int size)
_dbus_mem_pool_free (pool);
+#ifdef DBUS_ENABLE_VERBOSE_MODE
end = clock ();
_dbus_verbose (" created/destroyed %d elements in %g seconds\n",
@@ -543,6 +550,7 @@ time_for_size (int size)
_dbus_verbose (" zeroed malloc\n");
start = clock ();
+#endif
i = 0;
j = 0;
@@ -568,6 +576,7 @@ time_for_size (int size)
++i;
}
+#ifdef DBUS_ENABLE_VERBOSE_MODE
end = clock ();
_dbus_verbose (" created/destroyed %d elements in %g seconds\n",
@@ -576,6 +585,7 @@ time_for_size (int size)
_dbus_verbose (" zeroed mempools\n");
start = clock ();
+#endif
pool = _dbus_mem_pool_new (size, TRUE);
@@ -605,10 +615,12 @@ time_for_size (int size)
_dbus_mem_pool_free (pool);
+#ifdef DBUS_ENABLE_VERBOSE_MODE
end = clock ();
_dbus_verbose (" created/destroyed %d elements in %g seconds\n",
N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC);
+#endif
}
/**
@@ -632,4 +644,4 @@ _dbus_mem_pool_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-message-factory.c b/dbus/dbus-message-factory.c
index efa4e029..b742e4c1 100644
--- a/dbus/dbus-message-factory.c
+++ b/dbus/dbus-message-factory.c
@@ -24,7 +24,7 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-message-factory.h"
#include "dbus-message-private.h"
#include "dbus-signature.h"
@@ -1302,4 +1302,4 @@ _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-message-factory.h b/dbus/dbus-message-factory.h
index b0747504..fd7a4764 100644
--- a/dbus/dbus-message-factory.h
+++ b/dbus/dbus-message-factory.h
@@ -24,7 +24,7 @@
#ifndef DBUS_MESSAGE_FACTORY_H
#define DBUS_MESSAGE_FACTORY_H
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include <dbus/dbus-string.h>
#include <dbus/dbus-marshal-basic.h>
@@ -56,6 +56,6 @@ dbus_bool_t _dbus_message_data_iter_get_and_next (DBusMessageDataIter *iter,
DBUS_END_DECLS
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
#endif /* DBUS_MESSAGE_FACTORY_H */
diff --git a/dbus/dbus-message-internal.h b/dbus/dbus-message-internal.h
index c1948732..5d6594e3 100644
--- a/dbus/dbus-message-internal.h
+++ b/dbus/dbus-message-internal.h
@@ -70,8 +70,7 @@ void _dbus_message_loader_unref (DBusMessageLoader
void _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
DBusString **buffer);
void _dbus_message_loader_return_buffer (DBusMessageLoader *loader,
- DBusString *buffer,
- int bytes_read);
+ DBusString *buffer);
dbus_bool_t _dbus_message_loader_get_unix_fds (DBusMessageLoader *loader,
int **fds,
diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c
index f7859520..f615af83 100644
--- a/dbus/dbus-message-util.c
+++ b/dbus/dbus-message-util.c
@@ -45,7 +45,7 @@
* @{
*/
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Reads arguments from a message iterator given a variable argument
* list. Only arguments of basic type and arrays of fixed-length
@@ -76,11 +76,11 @@ dbus_message_iter_get_args (DBusMessageIter *iter,
return retval;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include "dbus-message-factory.h"
#include <stdio.h>
@@ -493,7 +493,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data,
_dbus_message_loader_get_buffer (loader, &buffer);
_dbus_string_append_byte (buffer,
_dbus_string_get_byte (data, i));
- _dbus_message_loader_return_buffer (loader, buffer, 1);
+ _dbus_message_loader_return_buffer (loader, buffer);
}
if (!check_loader_results (loader, expected_validity))
@@ -512,7 +512,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data,
_dbus_message_loader_get_buffer (loader, &buffer);
_dbus_string_copy (data, 0, buffer,
_dbus_string_get_length (buffer));
- _dbus_message_loader_return_buffer (loader, buffer, 1);
+ _dbus_message_loader_return_buffer (loader, buffer);
}
if (!check_loader_results (loader, expected_validity))
@@ -536,7 +536,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data,
if ((i+1) < len)
_dbus_string_append_byte (buffer,
_dbus_string_get_byte (data, i+1));
- _dbus_message_loader_return_buffer (loader, buffer, 1);
+ _dbus_message_loader_return_buffer (loader, buffer);
}
if (!check_loader_results (loader, expected_validity))
@@ -754,10 +754,8 @@ message_iter_test (DBusMessage *message)
dbus_uint16_t v_UINT16;
dbus_int32_t v_INT32;
dbus_uint32_t v_UINT32;
-#ifdef DBUS_HAVE_INT64
dbus_int64_t v_INT64;
dbus_uint64_t v_UINT64;
-#endif
unsigned char v_BYTE;
dbus_bool_t v_BOOLEAN;
@@ -830,14 +828,12 @@ verify_test_message (DBusMessage *message)
int our_uint32_array_len;
dbus_int32_t *our_int32_array = (void*)0xdeadbeef;
int our_int32_array_len;
-#ifdef DBUS_HAVE_INT64
dbus_int64_t our_int64;
dbus_uint64_t our_uint64;
dbus_int64_t *our_uint64_array = (void*)0xdeadbeef;
int our_uint64_array_len;
const dbus_int64_t *our_int64_array = (void*)0xdeadbeef;
int our_int64_array_len;
-#endif
const double *our_double_array = (void*)0xdeadbeef;
int our_double_array_len;
const unsigned char *our_byte_array = (void*)0xdeadbeef;
@@ -854,10 +850,8 @@ verify_test_message (DBusMessage *message)
DBUS_TYPE_UINT16, &our_uint16,
DBUS_TYPE_INT32, &our_int,
DBUS_TYPE_UINT32, &our_uint,
-#ifdef DBUS_HAVE_INT64
DBUS_TYPE_INT64, &our_int64,
DBUS_TYPE_UINT64, &our_uint64,
-#endif
DBUS_TYPE_STRING, &our_str,
DBUS_TYPE_DOUBLE, &our_double,
DBUS_TYPE_BOOLEAN, &our_bool,
@@ -867,12 +861,10 @@ verify_test_message (DBusMessage *message)
&our_uint32_array, &our_uint32_array_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32,
&our_int32_array, &our_int32_array_len,
-#ifdef DBUS_HAVE_INT64
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64,
&our_uint64_array, &our_uint64_array_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
&our_int64_array, &our_int64_array_len,
-#endif
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
&our_double_array, &our_double_array_len,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
@@ -900,12 +892,10 @@ verify_test_message (DBusMessage *message)
if (our_uint != 0x12300042)
_dbus_assert_not_reached ("uints differ!");
-#ifdef DBUS_HAVE_INT64
if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
_dbus_assert_not_reached ("64-bit integers differ!");
if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
_dbus_assert_not_reached ("64-bit unsigned integers differ!");
-#endif
v_DOUBLE = 3.14159;
if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE))
@@ -937,7 +927,6 @@ verify_test_message (DBusMessage *message)
our_int32_array[3] != -0x45678123)
_dbus_assert_not_reached ("int array differs");
-#ifdef DBUS_HAVE_INT64
if (our_uint64_array_len != 4 ||
our_uint64_array[0] != 0x12345678 ||
our_uint64_array[1] != 0x23456781 ||
@@ -951,7 +940,6 @@ verify_test_message (DBusMessage *message)
our_int64_array[2] != 0x34567812 ||
our_int64_array[3] != -0x45678123)
_dbus_assert_not_reached ("int64 array differs");
-#endif /* DBUS_HAVE_INT64 */
if (our_double_array_len != 3)
_dbus_assert_not_reached ("double array had wrong length");
@@ -1003,6 +991,161 @@ verify_test_message (DBusMessage *message)
_dbus_assert_not_reached ("Didn't reach end of arguments");
}
+static void
+verify_test_message_args_ignored (DBusMessage *message)
+{
+ DBusMessageIter iter;
+ DBusError error = DBUS_ERROR_INIT;
+ dbus_uint32_t our_uint;
+ DBusInitialFDs *initial_fds;
+
+ initial_fds = _dbus_check_fdleaks_enter ();
+
+ /* parse with empty signature: "" */
+ dbus_message_iter_init (message, &iter);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_warn ("error: %s - %s\n", error.name,
+ (error.message != NULL) ? error.message : "no message");
+ }
+ else
+ {
+ _dbus_assert (!dbus_error_is_set (&error));
+ _dbus_verbose ("arguments ignored.\n");
+ }
+
+ /* parse with shorter signature: "u" */
+ dbus_message_iter_init (message, &iter);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_UINT32, &our_uint,
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_warn ("error: %s - %s\n", error.name,
+ (error.message != NULL) ? error.message : "no message");
+ }
+ else
+ {
+ _dbus_assert (!dbus_error_is_set (&error));
+ _dbus_verbose ("arguments ignored.\n");
+ }
+
+ _dbus_check_fdleaks_leave (initial_fds);
+}
+
+static void
+verify_test_message_memleak (DBusMessage *message)
+{
+ DBusMessageIter iter;
+ DBusError error = DBUS_ERROR_INIT;
+ dbus_uint32_t our_uint1;
+ dbus_uint32_t our_uint2;
+ dbus_uint32_t our_uint3;
+ char **our_string_array1;
+ int our_string_array_len1;
+ char **our_string_array2;
+ int our_string_array_len2;
+ int our_unix_fd1;
+ int our_unix_fd2;
+ DBusInitialFDs *initial_fds;
+
+ initial_fds = _dbus_check_fdleaks_enter ();
+
+ /* parse with wrong signature: "uashuu" */
+ dbus_error_free (&error);
+ dbus_message_iter_init (message, &iter);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_UINT32, &our_uint1,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &our_string_array1, &our_string_array_len1,
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &our_unix_fd1,
+#endif
+ DBUS_TYPE_UINT32, &our_uint2,
+ DBUS_TYPE_UINT32, &our_uint3,
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_verbose ("expected error: %s - %s\n", error.name,
+ (error.message != NULL) ? error.message : "no message");
+ /* ensure array of string and unix fd not leaked */
+ _dbus_assert (our_string_array1 == NULL);
+#ifdef HAVE_UNIX_FD_PASSING
+ _dbus_assert (our_unix_fd1 == -1);
+#endif
+ }
+ else
+ {
+ _dbus_warn ("error: parse with wrong signature: 'uashuu'.\n");
+ }
+
+ /* parse with wrong signature: "uashuashu" */
+ dbus_message_iter_init (message, &iter);
+ dbus_error_free (&error);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_UINT32, &our_uint1,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &our_string_array1, &our_string_array_len1,
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &our_unix_fd1,
+#endif
+ DBUS_TYPE_UINT32, &our_uint2,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &our_string_array2, &our_string_array_len2,
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &our_unix_fd2,
+#endif
+ DBUS_TYPE_UINT32, &our_uint3,
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_verbose ("expected error: %s - %s\n", error.name,
+ (error.message != NULL) ? error.message : "no message");
+ /* ensure array of string and unix fd not leaked */
+ _dbus_assert (our_string_array1 == NULL);
+ _dbus_assert (our_string_array2 == NULL);
+#ifdef HAVE_UNIX_FD_PASSING
+ _dbus_assert (our_unix_fd1 == -1);
+ _dbus_assert (our_unix_fd2 == -1);
+#endif
+ }
+ else
+ {
+ _dbus_warn ("error: parse with wrong signature: 'uashuashu'.\n");
+ }
+
+ /* parse with correct signature: "uashuash" */
+ dbus_message_iter_init (message, &iter);
+ dbus_error_free (&error);
+ if (!dbus_message_iter_get_args (&iter, &error,
+ DBUS_TYPE_UINT32, &our_uint1,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &our_string_array1, &our_string_array_len1,
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &our_unix_fd1,
+#endif
+ DBUS_TYPE_UINT32, &our_uint2,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &our_string_array2, &our_string_array_len2,
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &our_unix_fd2,
+#endif
+ DBUS_TYPE_INVALID))
+ {
+ _dbus_warn ("error: %s - %s\n", error.name,
+ (error.message != NULL) ? error.message : "no message");
+ _dbus_assert_not_reached ("Could not get arguments");
+ }
+ else
+ {
+ dbus_free_string_array (our_string_array1);
+ dbus_free_string_array (our_string_array2);
+#ifdef HAVE_UNIX_FD_PASSING
+ _dbus_close (our_unix_fd1, &error);
+ _dbus_close (our_unix_fd2, &error);
+#endif
+ }
+ _dbus_check_fdleaks_leave (initial_fds);
+}
+
/**
* @ingroup DBusMessageInternals
* Unit test for DBusMessage.
@@ -1025,16 +1168,16 @@ _dbus_message_test (const char *test_data_dir)
{ 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array;
const dbus_int32_t *v_ARRAY_INT32 = our_int32_array;
-#ifdef DBUS_HAVE_INT64
const dbus_uint64_t our_uint64_array[] =
{ 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
const dbus_int64_t our_int64_array[] =
{ 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array;
const dbus_int64_t *v_ARRAY_INT64 = our_int64_array;
-#endif
const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
+ const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" };
const char **v_ARRAY_STRING = our_string_array;
+ const char **v1_ARRAY_STRING = our_string_array1;
const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
const double *v_ARRAY_DOUBLE = our_double_array;
const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
@@ -1049,16 +1192,16 @@ _dbus_message_test (const char *test_data_dir)
dbus_uint16_t v_UINT16;
dbus_int32_t v_INT32;
dbus_uint32_t v_UINT32;
-#ifdef DBUS_HAVE_INT64
+ dbus_uint32_t v1_UINT32;
dbus_int64_t v_INT64;
dbus_uint64_t v_UINT64;
-#endif
unsigned char v_BYTE;
unsigned char v2_BYTE;
dbus_bool_t v_BOOLEAN;
DBusMessageIter iter, array_iter, struct_iter;
#ifdef HAVE_UNIX_FD_PASSING
int v_UNIX_FD;
+ int v1_UNIX_FD;
#endif
char **decomposed;
DBusInitialFDs *initial_fds;
@@ -1201,10 +1344,8 @@ _dbus_message_test (const char *test_data_dir)
v_UINT16 = 0x123;
v_INT32 = -0x12345678;
v_UINT32 = 0x12300042;
-#ifdef DBUS_HAVE_INT64
v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);
v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd);
-#endif
v_STRING = "Test string";
v_DOUBLE = 3.14159;
v_BOOLEAN = TRUE;
@@ -1212,6 +1353,7 @@ _dbus_message_test (const char *test_data_dir)
v2_BYTE = 24;
#ifdef HAVE_UNIX_FD_PASSING
v_UNIX_FD = 1;
+ v1_UNIX_FD = 2;
#endif
dbus_message_append_args (message,
@@ -1219,10 +1361,8 @@ _dbus_message_test (const char *test_data_dir)
DBUS_TYPE_UINT16, &v_UINT16,
DBUS_TYPE_INT32, &v_INT32,
DBUS_TYPE_UINT32, &v_UINT32,
-#ifdef DBUS_HAVE_INT64
DBUS_TYPE_INT64, &v_INT64,
DBUS_TYPE_UINT64, &v_UINT64,
-#endif
DBUS_TYPE_STRING, &v_STRING,
DBUS_TYPE_DOUBLE, &v_DOUBLE,
DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
@@ -1232,12 +1372,10 @@ _dbus_message_test (const char *test_data_dir)
_DBUS_N_ELEMENTS (our_uint32_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32,
_DBUS_N_ELEMENTS (our_int32_array),
-#ifdef DBUS_HAVE_INT64
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64,
_DBUS_N_ELEMENTS (our_uint64_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64,
_DBUS_N_ELEMENTS (our_int64_array),
-#endif
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE,
_DBUS_N_ELEMENTS (our_double_array),
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE,
@@ -1254,10 +1392,8 @@ _dbus_message_test (const char *test_data_dir)
sig[i++] = DBUS_TYPE_UINT16;
sig[i++] = DBUS_TYPE_INT32;
sig[i++] = DBUS_TYPE_UINT32;
-#ifdef DBUS_HAVE_INT64
sig[i++] = DBUS_TYPE_INT64;
sig[i++] = DBUS_TYPE_UINT64;
-#endif
sig[i++] = DBUS_TYPE_STRING;
sig[i++] = DBUS_TYPE_DOUBLE;
sig[i++] = DBUS_TYPE_BOOLEAN;
@@ -1267,12 +1403,10 @@ _dbus_message_test (const char *test_data_dir)
sig[i++] = DBUS_TYPE_UINT32;
sig[i++] = DBUS_TYPE_ARRAY;
sig[i++] = DBUS_TYPE_INT32;
-#ifdef DBUS_HAVE_INT64
sig[i++] = DBUS_TYPE_ARRAY;
sig[i++] = DBUS_TYPE_UINT64;
sig[i++] = DBUS_TYPE_ARRAY;
sig[i++] = DBUS_TYPE_INT64;
-#endif
sig[i++] = DBUS_TYPE_ARRAY;
sig[i++] = DBUS_TYPE_DOUBLE;
sig[i++] = DBUS_TYPE_ARRAY;
@@ -1353,7 +1487,7 @@ _dbus_message_test (const char *test_data_dir)
_dbus_message_loader_get_buffer (loader, &buffer);
_dbus_string_append_byte (buffer, data[i]);
- _dbus_message_loader_return_buffer (loader, buffer, 1);
+ _dbus_message_loader_return_buffer (loader, buffer);
}
/* Write the body data one byte at a time */
@@ -1364,7 +1498,7 @@ _dbus_message_test (const char *test_data_dir)
_dbus_message_loader_get_buffer (loader, &buffer);
_dbus_string_append_byte (buffer, data[i]);
- _dbus_message_loader_return_buffer (loader, buffer, 1);
+ _dbus_message_loader_return_buffer (loader, buffer);
}
#ifdef HAVE_UNIX_FD_PASSING
@@ -1489,6 +1623,51 @@ _dbus_message_test (const char *test_data_dir)
dbus_message_unref (message);
+ /* Check we should not leak array of string or unix fd, fd.o#21259 */
+ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
+ "/org/freedesktop/TestPath",
+ "Foo.TestInterface",
+ "Method");
+
+ /* signature "uashuash" */
+ dbus_message_append_args (message,
+ DBUS_TYPE_UINT32, &v_UINT32,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
+ _DBUS_N_ELEMENTS (our_string_array),
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
+#endif
+ DBUS_TYPE_UINT32, &v1_UINT32,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING,
+ _DBUS_N_ELEMENTS (our_string_array1),
+#ifdef HAVE_UNIX_FD_PASSING
+ DBUS_TYPE_UNIX_FD, &v1_UNIX_FD,
+#endif
+
+ DBUS_TYPE_INVALID);
+
+ i = 0;
+ sig[i++] = DBUS_TYPE_UINT32;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_STRING;
+#ifdef HAVE_UNIX_FD_PASSING
+ sig[i++] = DBUS_TYPE_UNIX_FD;
+#endif
+ sig[i++] = DBUS_TYPE_UINT32;
+ sig[i++] = DBUS_TYPE_ARRAY;
+ sig[i++] = DBUS_TYPE_STRING;
+#ifdef HAVE_UNIX_FD_PASSING
+ sig[i++] = DBUS_TYPE_UNIX_FD;
+#endif
+ sig[i++] = DBUS_TYPE_INVALID;
+
+ _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
+
+ verify_test_message_args_ignored (message);
+ verify_test_message_memleak (message);
+
+ dbus_message_unref (message);
+
/* Load all the sample messages from the message factory */
{
DBusMessageDataIter diter;
@@ -1542,4 +1721,4 @@ _dbus_message_test (const char *test_data_dir)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index f48977ca..2c30482c 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -56,7 +56,7 @@ static void dbus_message_finalize (DBusMessage *message);
* @{
*/
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static dbus_bool_t
_dbus_enable_message_cache (void)
{
@@ -462,7 +462,7 @@ set_or_delete_string_field (DBusMessage *message,
/** Avoid caching too many messages */
#define MAX_MESSAGE_CACHE_SIZE 5
-_DBUS_DEFINE_GLOBAL_LOCK (message_cache);
+/* Protected by _DBUS_LOCK (message_cache) */
static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
static int message_cache_count = 0;
static dbus_bool_t message_cache_shutdown_registered = FALSE;
@@ -472,7 +472,9 @@ dbus_message_cache_shutdown (void *data)
{
int i;
- _DBUS_LOCK (message_cache);
+ if (!_DBUS_LOCK (message_cache))
+ _dbus_assert_not_reached ("we would have initialized global locks "
+ "before registering a shutdown function");
i = 0;
while (i < MAX_MESSAGE_CACHE_SIZE)
@@ -504,7 +506,12 @@ dbus_message_get_cached (void)
message = NULL;
- _DBUS_LOCK (message_cache);
+ if (!_DBUS_LOCK (message_cache))
+ {
+ /* we'd have initialized global locks before caching anything,
+ * so there can't be anything in the cache */
+ return NULL;
+ }
_dbus_assert (message_cache_count >= 0);
@@ -616,7 +623,13 @@ dbus_message_cache_or_finalize (DBusMessage *message)
was_cached = FALSE;
- _DBUS_LOCK (message_cache);
+ if (!_DBUS_LOCK (message_cache))
+ {
+ /* The only way to get a non-null message goes through
+ * dbus_message_get_cached() which takes the lock. */
+ _dbus_assert_not_reached ("we would have initialized global locks "
+ "the first time we constructed a message");
+ }
if (!message_cache_shutdown_registered)
{
@@ -672,7 +685,7 @@ dbus_message_cache_or_finalize (DBusMessage *message)
dbus_message_finalize (message);
}
-#ifndef DBUS_DISABLE_CHECKS
+#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
static dbus_bool_t
_dbus_message_iter_check (DBusMessageRealIter *iter)
{
@@ -720,15 +733,13 @@ _dbus_message_iter_check (DBusMessageRealIter *iter)
return TRUE;
}
-#endif /* DBUS_DISABLE_CHECKS */
+#endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
/**
* Implementation of the varargs arg-getting functions.
* dbus_message_get_args() is the place to go for complete
* documentation.
*
- * @todo This may leak memory and file descriptors if parsing fails. See #21259
- *
* @see dbus_message_get_args
* @param iter the message iter
* @param error error to be filled in
@@ -743,8 +754,9 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
va_list var_args)
{
DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
- int spec_type, msg_type, i;
+ int spec_type, msg_type, i, j;
dbus_bool_t retval;
+ va_list copy_args;
_dbus_assert (_dbus_message_iter_check (real));
@@ -753,12 +765,17 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
spec_type = first_arg_type;
i = 0;
+ /* copy var_args first, then we can do another iteration over it to
+ * free memory and close unix fds if parse failed at some point.
+ */
+ DBUS_VA_COPY (copy_args, var_args);
+
while (spec_type != DBUS_TYPE_INVALID)
{
msg_type = dbus_message_iter_get_arg_type (iter);
if (msg_type != spec_type)
- {
+ {
dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
"Argument %d is specified to be of type \"%s\", but "
"is actually of type \"%s\"\n", i,
@@ -766,7 +783,7 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
_dbus_type_to_string (msg_type));
goto out;
- }
+ }
if (spec_type == DBUS_TYPE_UNIX_FD)
{
@@ -879,30 +896,30 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
/* Now go through and dup each string */
_dbus_type_reader_recurse (&real->u.reader, &array);
- i = 0;
- while (i < n_elements)
+ j = 0;
+ while (j < n_elements)
{
const char *s;
_dbus_type_reader_read_basic (&array,
(void *) &s);
- str_array[i] = _dbus_strdup (s);
- if (str_array[i] == NULL)
+ str_array[j] = _dbus_strdup (s);
+ if (str_array[j] == NULL)
{
dbus_free_string_array (str_array);
_DBUS_SET_OOM (error);
goto out;
}
- ++i;
+ ++j;
if (!_dbus_type_reader_next (&array))
- _dbus_assert (i == n_elements);
+ _dbus_assert (j == n_elements);
}
_dbus_assert (_dbus_type_reader_get_current_type (&array) == DBUS_TYPE_INVALID);
- _dbus_assert (i == n_elements);
- _dbus_assert (str_array[i] == NULL);
+ _dbus_assert (j == n_elements);
+ _dbus_assert (str_array[j] == NULL);
*str_array_p = str_array;
*n_elements_p = n_elements;
@@ -925,6 +942,9 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
}
#endif
+ /* how many arguments already handled */
+ i++;
+
spec_type = va_arg (var_args, int);
if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
{
@@ -932,14 +952,71 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
"Message has only %d arguments, but more were expected", i);
goto out;
}
-
- i++;
}
retval = TRUE;
out:
+ /* there may memory or unix fd leak in the above iteration if parse failed.
+ * so we have another iteration over copy_args to free memory and close
+ * unix fds.
+ */
+ if (!retval)
+ {
+ spec_type = first_arg_type;
+ j = 0;
+ while (j < i)
+ {
+ if (spec_type == DBUS_TYPE_UNIX_FD)
+ {
+#ifdef HAVE_UNIX_FD_PASSING
+ int *pfd;
+
+ pfd = va_arg (copy_args, int *);
+ _dbus_assert(pfd);
+ if (*pfd >= 0)
+ {
+ _dbus_close (*pfd, NULL);
+ *pfd = -1;
+ }
+#endif
+ }
+ else if (dbus_type_is_basic (spec_type))
+ {
+ /* move the index forward */
+ va_arg (copy_args, DBusBasicValue *);
+ }
+ else if (spec_type == DBUS_TYPE_ARRAY)
+ {
+ int spec_element_type;
+
+ spec_element_type = va_arg (copy_args, int);
+ if (dbus_type_is_fixed (spec_element_type))
+ {
+ /* move the index forward */
+ va_arg (copy_args, const DBusBasicValue **);
+ va_arg (copy_args, int *);
+ }
+ else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
+ {
+ char ***str_array_p;
+
+ str_array_p = va_arg (copy_args, char ***);
+ /* move the index forward */
+ va_arg (copy_args, int *);
+ _dbus_assert (str_array_p != NULL);
+ dbus_free_string_array (*str_array_p);
+ *str_array_p = NULL;
+ }
+ }
+
+ spec_type = va_arg (copy_args, int);
+ j++;
+ }
+ }
+
+ va_end (copy_args);
return retval;
}
@@ -1202,7 +1279,7 @@ dbus_message_new (int message_type)
*
* @param destination name that the message should be sent to or #NULL
* @param path object path the message should be sent to
- * @param interface interface to invoke method on, or #NULL
+ * @param iface interface to invoke method on, or #NULL
* @param method method to invoke
*
* @returns a new DBusMessage, free with dbus_message_unref()
@@ -1210,7 +1287,7 @@ dbus_message_new (int message_type)
DBusMessage*
dbus_message_new_method_call (const char *destination,
const char *path,
- const char *interface,
+ const char *iface,
const char *method)
{
DBusMessage *message;
@@ -1220,8 +1297,8 @@ dbus_message_new_method_call (const char *destination,
_dbus_return_val_if_fail (destination == NULL ||
_dbus_check_is_valid_bus_name (destination), NULL);
_dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
- _dbus_return_val_if_fail (interface == NULL ||
- _dbus_check_is_valid_interface (interface), NULL);
+ _dbus_return_val_if_fail (iface == NULL ||
+ _dbus_check_is_valid_interface (iface), NULL);
_dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
message = dbus_message_new_empty_header ();
@@ -1231,7 +1308,7 @@ dbus_message_new_method_call (const char *destination,
if (!_dbus_header_create (&message->header,
DBUS_COMPILER_BYTE_ORDER,
DBUS_MESSAGE_TYPE_METHOD_CALL,
- destination, path, interface, method, NULL))
+ destination, path, iface, method, NULL))
{
dbus_message_unref (message);
return NULL;
@@ -1294,22 +1371,22 @@ dbus_message_new_method_return (DBusMessage *method_call)
* specification defines the syntax of these fields).
*
* @param path the path to the object emitting the signal
- * @param interface the interface the signal is emitted from
+ * @param iface the interface the signal is emitted from
* @param name name of the signal
* @returns a new DBusMessage, free with dbus_message_unref()
*/
DBusMessage*
dbus_message_new_signal (const char *path,
- const char *interface,
+ const char *iface,
const char *name)
{
DBusMessage *message;
_dbus_return_val_if_fail (path != NULL, NULL);
- _dbus_return_val_if_fail (interface != NULL, NULL);
+ _dbus_return_val_if_fail (iface != NULL, NULL);
_dbus_return_val_if_fail (name != NULL, NULL);
_dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
- _dbus_return_val_if_fail (_dbus_check_is_valid_interface (interface), NULL);
+ _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
_dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
message = dbus_message_new_empty_header ();
@@ -1319,7 +1396,7 @@ dbus_message_new_signal (const char *path,
if (!_dbus_header_create (&message->header,
DBUS_COMPILER_BYTE_ORDER,
DBUS_MESSAGE_TYPE_SIGNAL,
- NULL, path, interface, name, NULL))
+ NULL, path, iface, name, NULL))
{
dbus_message_unref (message);
return NULL;
@@ -3069,23 +3146,23 @@ dbus_message_get_path_decomposed (DBusMessage *message,
* in the D-Bus specification.
*
* @param message the message
- * @param interface the interface or #NULL to unset
+ * @param iface the interface or #NULL to unset
* @returns #FALSE if not enough memory
*/
dbus_bool_t
dbus_message_set_interface (DBusMessage *message,
- const char *interface)
+ const char *iface)
{
_dbus_return_val_if_fail (message != NULL, FALSE);
_dbus_return_val_if_fail (!message->locked, FALSE);
- _dbus_return_val_if_fail (interface == NULL ||
- _dbus_check_is_valid_interface (interface),
+ _dbus_return_val_if_fail (iface == NULL ||
+ _dbus_check_is_valid_interface (iface),
FALSE);
return set_or_delete_string_field (message,
DBUS_HEADER_FIELD_INTERFACE,
DBUS_TYPE_STRING,
- interface);
+ iface);
}
/**
@@ -3120,28 +3197,28 @@ dbus_message_get_interface (DBusMessage *message)
* Checks if the message has an interface
*
* @param message the message
- * @param interface the interface name
+ * @param iface the interface name
* @returns #TRUE if the interface field in the header matches
*/
dbus_bool_t
dbus_message_has_interface (DBusMessage *message,
- const char *interface)
+ const char *iface)
{
const char *msg_interface;
msg_interface = dbus_message_get_interface (message);
if (msg_interface == NULL)
{
- if (interface == NULL)
+ if (iface == NULL)
return TRUE;
else
return FALSE;
}
- if (interface == NULL)
+ if (iface == NULL)
return FALSE;
- if (strcmp (msg_interface, interface) == 0)
+ if (strcmp (msg_interface, iface) == 0)
return TRUE;
return FALSE;
@@ -3474,13 +3551,13 @@ dbus_message_get_signature (DBusMessage *message)
static dbus_bool_t
_dbus_message_has_type_interface_member (DBusMessage *message,
int type,
- const char *interface,
+ const char *iface,
const char *member)
{
const char *n;
_dbus_assert (message != NULL);
- _dbus_assert (interface != NULL);
+ _dbus_assert (iface != NULL);
_dbus_assert (member != NULL);
if (dbus_message_get_type (message) != type)
@@ -3496,7 +3573,7 @@ _dbus_message_has_type_interface_member (DBusMessage *message,
{
n = dbus_message_get_interface (message);
- if (n == NULL || strcmp (n, interface) == 0)
+ if (n == NULL || strcmp (n, iface) == 0)
return TRUE;
}
@@ -3512,18 +3589,18 @@ _dbus_message_has_type_interface_member (DBusMessage *message,
* protocol allows method callers to leave out the interface name.
*
* @param message the message
- * @param interface the name to check (must not be #NULL)
+ * @param iface the name to check (must not be #NULL)
* @param method the name to check (must not be #NULL)
*
* @returns #TRUE if the message is the specified method call
*/
dbus_bool_t
dbus_message_is_method_call (DBusMessage *message,
- const char *interface,
+ const char *iface,
const char *method)
{
_dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (interface != NULL, FALSE);
+ _dbus_return_val_if_fail (iface != NULL, FALSE);
_dbus_return_val_if_fail (method != NULL, FALSE);
/* don't check that interface/method are valid since it would be
* expensive, and not catch many common errors
@@ -3531,7 +3608,7 @@ dbus_message_is_method_call (DBusMessage *message,
return _dbus_message_has_type_interface_member (message,
DBUS_MESSAGE_TYPE_METHOD_CALL,
- interface, method);
+ iface, method);
}
/**
@@ -3540,18 +3617,18 @@ dbus_message_is_method_call (DBusMessage *message,
* has a different interface or member field, returns #FALSE.
*
* @param message the message
- * @param interface the name to check (must not be #NULL)
+ * @param iface the name to check (must not be #NULL)
* @param signal_name the name to check (must not be #NULL)
*
* @returns #TRUE if the message is the specified signal
*/
dbus_bool_t
dbus_message_is_signal (DBusMessage *message,
- const char *interface,
+ const char *iface,
const char *signal_name)
{
_dbus_return_val_if_fail (message != NULL, FALSE);
- _dbus_return_val_if_fail (interface != NULL, FALSE);
+ _dbus_return_val_if_fail (iface != NULL, FALSE);
_dbus_return_val_if_fail (signal_name != NULL, FALSE);
/* don't check that interface/name are valid since it would be
* expensive, and not catch many common errors
@@ -3559,7 +3636,7 @@ dbus_message_is_signal (DBusMessage *message,
return _dbus_message_has_type_interface_member (message,
DBUS_MESSAGE_TYPE_SIGNAL,
- interface, signal_name);
+ iface, signal_name);
}
/**
@@ -3799,7 +3876,7 @@ _dbus_message_loader_new (void)
SCM_RIGHTS works we need to preallocate an fd array of the maximum
number of unix fds we want to receive in advance. A
try-and-reallocate loop is not possible. */
- loader->max_message_unix_fds = 1024;
+ loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
if (!_dbus_string_init (&loader->data))
{
@@ -3896,12 +3973,10 @@ _dbus_message_loader_get_buffer (DBusMessageLoader *loader,
*
* @param loader the loader.
* @param buffer the buffer.
- * @param bytes_read number of bytes that were read into the buffer.
*/
void
_dbus_message_loader_return_buffer (DBusMessageLoader *loader,
- DBusString *buffer,
- int bytes_read)
+ DBusString *buffer)
{
_dbus_assert (loader->buffer_outstanding);
_dbus_assert (buffer == &loader->data);
@@ -3965,7 +4040,7 @@ _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
*
* @param loader the message loader.
* @param fds the array fds were read into
- * @param max_n_fds how many fds were read
+ * @param n_fds how many fds were read
*/
void
@@ -4393,7 +4468,7 @@ _dbus_message_loader_get_max_message_size (DBusMessageLoader *loader)
* Sets the maximum unix fds per message we allow.
*
* @param loader the loader
- * @param size the max number of unix fds in a message
+ * @param n the max number of unix fds in a message
*/
void
_dbus_message_loader_set_max_message_unix_fds (DBusMessageLoader *loader,
@@ -4420,8 +4495,8 @@ _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader)
return loader->max_message_unix_fds;
}
-static DBusDataSlotAllocator slot_allocator;
-_DBUS_DEFINE_GLOBAL_LOCK (message_slots);
+static DBusDataSlotAllocator slot_allocator =
+ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
/**
* Allocates an integer ID to be used for storing application-specific
@@ -4441,7 +4516,6 @@ dbus_bool_t
dbus_message_allocate_data_slot (dbus_int32_t *slot_p)
{
return _dbus_data_slot_allocator_alloc (&slot_allocator,
- &_DBUS_LOCK_NAME (message_slots),
slot_p);
}
@@ -4737,7 +4811,7 @@ dbus_message_demarshal (const char *str,
_dbus_message_loader_get_buffer (loader, &buffer);
_dbus_string_append_len (buffer, str, len);
- _dbus_message_loader_return_buffer (loader, buffer, len);
+ _dbus_message_loader_return_buffer (loader, buffer);
if (!_dbus_message_loader_queue_messages (loader))
goto fail_oom;
@@ -4772,9 +4846,8 @@ dbus_message_demarshal (const char *str,
* Generally, this function is only useful for encapsulating D-Bus messages in
* a different protocol.
*
- * @param str data to be marshalled
- * @param len the length of str
- * @param error the location to save errors to
+ * @param buf data to be marshalled
+ * @param len the length of @p buf
* @returns -1 if there was no valid data to be demarshalled, 0 if there wasn't enough data to determine how much should be demarshalled. Otherwise returns the number of bytes to be demarshalled
*
*/
diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h
index 55388ac1..01b7344e 100644
--- a/dbus/dbus-message.h
+++ b/dbus/dbus-message.h
@@ -71,13 +71,13 @@ DBusMessage* dbus_message_new (int message_type);
DBUS_EXPORT
DBusMessage* dbus_message_new_method_call (const char *bus_name,
const char *path,
- const char *interface,
+ const char *iface,
const char *method);
DBUS_EXPORT
DBusMessage* dbus_message_new_method_return (DBusMessage *method_call);
DBUS_EXPORT
DBusMessage* dbus_message_new_signal (const char *path,
- const char *interface,
+ const char *iface,
const char *name);
DBUS_EXPORT
DBusMessage* dbus_message_new_error (DBusMessage *reply_to,
@@ -108,12 +108,12 @@ dbus_bool_t dbus_message_has_path (DBusMessage *message,
const char *object_path);
DBUS_EXPORT
dbus_bool_t dbus_message_set_interface (DBusMessage *message,
- const char *interface);
+ const char *iface);
DBUS_EXPORT
const char* dbus_message_get_interface (DBusMessage *message);
DBUS_EXPORT
dbus_bool_t dbus_message_has_interface (DBusMessage *message,
- const char *interface);
+ const char *iface);
DBUS_EXPORT
dbus_bool_t dbus_message_set_member (DBusMessage *message,
const char *member);
@@ -149,11 +149,11 @@ DBUS_EXPORT
dbus_bool_t dbus_message_get_no_reply (DBusMessage *message);
DBUS_EXPORT
dbus_bool_t dbus_message_is_method_call (DBusMessage *message,
- const char *interface,
+ const char *iface,
const char *method);
DBUS_EXPORT
dbus_bool_t dbus_message_is_signal (DBusMessage *message,
- const char *interface,
+ const char *iface,
const char *signal_name);
DBUS_EXPORT
dbus_bool_t dbus_message_is_error (DBusMessage *message,
diff --git a/dbus/dbus-misc.c b/dbus/dbus-misc.c
index b1610133..6ca30f24 100644
--- a/dbus/dbus-misc.c
+++ b/dbus/dbus-misc.c
@@ -173,7 +173,7 @@ dbus_get_version (int *major_version_p,
/** @} */ /* End of public API */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#ifndef DOXYGEN_SHOULD_SKIP_THIS
diff --git a/dbus/dbus-misc.h b/dbus/dbus-misc.h
index 3504bcaa..6e72d9ed 100644
--- a/dbus/dbus-misc.h
+++ b/dbus/dbus-misc.h
@@ -44,6 +44,10 @@ void dbus_get_version (int *major_version_p,
int *minor_version_p,
int *micro_version_p);
+DBUS_EXPORT
+dbus_bool_t dbus_setenv (const char *variable,
+ const char *value);
+
/** @} */
DBUS_END_DECLS
diff --git a/dbus/dbus-nonce.c b/dbus/dbus-nonce.c
index e74c2dd5..37f30f00 100644
--- a/dbus/dbus-nonce.c
+++ b/dbus/dbus-nonce.c
@@ -113,7 +113,15 @@ _dbus_read_nonce (const DBusString *fname, DBusString *nonce, DBusError* error)
fp = fopen (_dbus_string_get_const_data (fname), "rb");
if (!fp)
- return FALSE;
+ {
+ dbus_set_error (error,
+ _dbus_error_from_system_errno (),
+ "Failed to open %s for read: %s",
+ _dbus_string_get_const_data (fname),
+ _dbus_strerror_from_errno ());
+ return FALSE;
+ }
+
nread = fread (buffer, 1, sizeof buffer - 1, fp);
fclose (fp);
if (!nread)
@@ -240,6 +248,7 @@ do_noncefile_create (DBusNonceFile *noncefile,
dbus_bool_t use_subdir)
{
DBusString randomStr;
+ const char *tmp;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -257,8 +266,11 @@ do_noncefile_create (DBusNonceFile *noncefile,
goto on_error;
}
+ tmp = _dbus_get_tmpdir ();
+
if (!_dbus_string_init (&noncefile->dir)
- || !_dbus_string_append (&noncefile->dir, _dbus_get_tmpdir()))
+ || tmp == NULL
+ || !_dbus_string_append (&noncefile->dir, tmp))
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto on_error;
diff --git a/dbus/dbus-object-tree.c b/dbus/dbus-object-tree.c
index 172c9d95..d256018e 100644
--- a/dbus/dbus-object-tree.c
+++ b/dbus/dbus-object-tree.c
@@ -434,6 +434,185 @@ _dbus_object_tree_register (DBusObjectTree *tree,
}
/**
+ * Attempts to unregister the given subtree. If the subtree is registered,
+ * stores its unregister function and user data for later use and returns
+ * #TRUE. If subtree is not registered, simply returns #FALSE. Does not free
+ * subtree or remove it from the object tree.
+ *
+ * @param subtree the subtree to unregister
+ * @param unregister_function_out stores subtree's unregister_function
+ * @param user_data_out stores subtree's user_data
+ * @return #FALSE if the subtree was not registered, #TRUE on success
+ */
+static dbus_bool_t
+unregister_subtree (DBusObjectSubtree *subtree,
+ DBusObjectPathUnregisterFunction *unregister_function_out,
+ void **user_data_out)
+{
+ _dbus_assert (subtree != NULL);
+ _dbus_assert (unregister_function_out != NULL);
+ _dbus_assert (user_data_out != NULL);
+
+ /* Confirm subtree is registered */
+ if (subtree->message_function != NULL)
+ {
+ subtree->message_function = NULL;
+
+ *unregister_function_out = subtree->unregister_function;
+ *user_data_out = subtree->user_data;
+
+ subtree->unregister_function = NULL;
+ subtree->user_data = NULL;
+
+ return TRUE;
+ }
+ else
+ {
+ /* Assert that this unregistered subtree is either the root node or has
+ children, otherwise we have a dangling path which should never
+ happen */
+ _dbus_assert (subtree->parent == NULL || subtree->n_subtrees > 0);
+
+ /* The subtree is not registered */
+ return FALSE;
+ }
+}
+
+/**
+ * Attempts to remove a child subtree from its parent. If removal is
+ * successful, also frees the child. Returns #TRUE on success, #FALSE
+ * otherwise. A #FALSE return value tells unregister_and_free_path_recurse to
+ * stop attempting to remove ancestors, i.e., that no ancestors of the
+ * specified child are eligible for removal.
+ *
+ * @param parent parent from which to remove child
+ * @param child_index parent->subtrees index of child to remove
+ * @return #TRUE if removal and free succeed, #FALSE otherwise
+ */
+static dbus_bool_t
+attempt_child_removal (DBusObjectSubtree *parent,
+ int child_index)
+{
+ /* Candidate for removal */
+ DBusObjectSubtree* candidate;
+
+ _dbus_assert (parent != NULL);
+ _dbus_assert (child_index >= 0 && child_index < parent->n_subtrees);
+
+ candidate = parent->subtrees[child_index];
+ _dbus_assert (candidate != NULL);
+
+ if (candidate->n_subtrees == 0 && candidate->message_function == NULL)
+ {
+ /* The candidate node is childless and is not a registered
+ path, so... */
+
+ /* ... remove it from its parent... */
+ /* Assumes a 0-byte memmove is OK */
+ memmove (&parent->subtrees[child_index],
+ &parent->subtrees[child_index + 1],
+ (parent->n_subtrees - child_index - 1)
+ * sizeof (parent->subtrees[0]));
+ parent->n_subtrees -= 1;
+
+ /* ... and free it */
+ candidate->parent = NULL;
+ _dbus_object_subtree_unref (candidate);
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Searches the object tree for a registered subtree node at the given path.
+ * If a registered node is found, it is removed from the tree and freed, and
+ * TRUE is returned. If a registered subtree node is not found at the given
+ * path, the tree is not modified and FALSE is returned.
+ *
+ * The found node's unregister_function and user_data are returned in the
+ * corresponding _out arguments. The caller should define these variables and
+ * pass their addresses as arguments.
+ *
+ * Likewise, the caller should define and set to TRUE a boolean variable, then
+ * pass its address as the continue_removal_attempts argument.
+ *
+ * Once a matching registered node is found, removed and freed, the recursive
+ * return path is traversed. Along the way, eligible ancestor nodes are
+ * removed and freed. An ancestor node is eligible for removal if and only if
+ * 1) it has no children, i.e., it has become childless and 2) it is not itself
+ * a registered handler.
+ *
+ * For example, suppose /A/B and /A/C are registered paths, and that these are
+ * the only paths in the tree. If B is removed and freed, C is still reachable
+ * through A, so A cannot be removed and freed. If C is subsequently removed
+ * and freed, then A becomes a childless node and it becomes eligible for
+ * removal, and will be removed and freed.
+ *
+ * Similarly, suppose /A is a registered path, and /A/B is also a registered
+ * path, and that these are the only paths in the tree. If B is removed and
+ * freed, then even though A has become childless, it can't be freed because it
+ * refers to a path that is still registered.
+ *
+ * @param subtree subtree from which to start the search, root for initial call
+ * @param path path to subtree (same as _dbus_object_tree_unregister_and_unlock)
+ * @param continue_removal_attempts pointer to a bool, #TRUE for initial call
+ * @param unregister_function_out returns the found node's unregister_function
+ * @param user_data_out returns the found node's user_data
+ * @returns #TRUE if a registered node was found at path, #FALSE otherwise
+ */
+static dbus_bool_t
+unregister_and_free_path_recurse
+(DBusObjectSubtree *subtree,
+ const char **path,
+ dbus_bool_t *continue_removal_attempts,
+ DBusObjectPathUnregisterFunction *unregister_function_out,
+ void **user_data_out)
+{
+ int i, j;
+
+ _dbus_assert (continue_removal_attempts != NULL);
+ _dbus_assert (*continue_removal_attempts);
+ _dbus_assert (unregister_function_out != NULL);
+ _dbus_assert (user_data_out != NULL);
+
+ if (path[0] == NULL)
+ return unregister_subtree (subtree, unregister_function_out, user_data_out);
+
+ i = 0;
+ j = subtree->n_subtrees;
+ while (i < j)
+ {
+ int k, v;
+
+ k = (i + j) / 2;
+ v = strcmp (path[0], subtree->subtrees[k]->name);
+
+ if (v == 0)
+ {
+ dbus_bool_t freed;
+ freed = unregister_and_free_path_recurse (subtree->subtrees[k],
+ &path[1],
+ continue_removal_attempts,
+ unregister_function_out,
+ user_data_out);
+ if (freed && *continue_removal_attempts)
+ *continue_removal_attempts = attempt_child_removal (subtree, k);
+ return freed;
+ }
+ else if (v < 0)
+ {
+ j = k;
+ }
+ else
+ {
+ i = k + 1;
+ }
+ }
+ return FALSE;
+}
+
+/**
* Unregisters an object subtree that was registered with the
* same path.
*
@@ -444,66 +623,42 @@ void
_dbus_object_tree_unregister_and_unlock (DBusObjectTree *tree,
const char **path)
{
- int i;
- DBusObjectSubtree *subtree;
+ dbus_bool_t found_subtree;
+ dbus_bool_t continue_removal_attempts;
DBusObjectPathUnregisterFunction unregister_function;
void *user_data;
DBusConnection *connection;
+ _dbus_assert (tree != NULL);
_dbus_assert (path != NULL);
+ continue_removal_attempts = TRUE;
unregister_function = NULL;
user_data = NULL;
- subtree = find_subtree (tree, path, &i);
+ found_subtree = unregister_and_free_path_recurse (tree->root,
+ path,
+ &continue_removal_attempts,
+ &unregister_function,
+ &user_data);
#ifndef DBUS_DISABLE_CHECKS
- if (subtree == NULL)
+ if (found_subtree == FALSE)
{
_dbus_warn ("Attempted to unregister path (path[0] = %s path[1] = %s) which isn't registered\n",
path[0] ? path[0] : "null",
- path[1] ? path[1] : "null");
+ (path[0] && path[1]) ? path[1] : "null");
goto unlock;
}
#else
- _dbus_assert (subtree != NULL);
+ _dbus_assert (found_subtree == TRUE);
#endif
- _dbus_assert (subtree->parent == NULL ||
- (i >= 0 && subtree->parent->subtrees[i] == subtree));
-
- subtree->message_function = NULL;
-
- unregister_function = subtree->unregister_function;
- user_data = subtree->user_data;
-
- subtree->unregister_function = NULL;
- subtree->user_data = NULL;
-
- /* If we have no subtrees of our own, remove from
- * our parent (FIXME could also be more aggressive
- * and remove our parent if it becomes empty)
- */
- if (subtree->parent && subtree->n_subtrees == 0)
- {
- /* assumes a 0-byte memmove is OK */
- memmove (&subtree->parent->subtrees[i],
- &subtree->parent->subtrees[i+1],
- (subtree->parent->n_subtrees - i - 1) *
- sizeof (subtree->parent->subtrees[0]));
- subtree->parent->n_subtrees -= 1;
-
- subtree->parent = NULL;
-
- _dbus_object_subtree_unref (subtree);
- }
- subtree = NULL;
-
unlock:
connection = tree->connection;
/* Unlock and call application code */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (connection)
#endif
{
@@ -515,7 +670,7 @@ unlock:
if (unregister_function)
(* unregister_function) (connection, user_data);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (connection)
#endif
dbus_connection_unref (connection);
@@ -638,7 +793,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree,
DBUS_INTERFACE_INTROSPECTABLE,
"Introspect"))
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -653,7 +808,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree,
if (!_dbus_string_init (&xml))
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -698,7 +853,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree,
if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &v_STRING))
goto out;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -711,7 +866,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree,
result = DBUS_HANDLER_RESULT_HANDLED;
out:
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -741,6 +896,7 @@ handle_default_introspect_and_unlock (DBusObjectTree *tree,
*
* @param tree the global object tree
* @param message the message to dispatch
+ * @param found_object return location for the object
* @returns whether message was handled successfully
*/
DBusHandlerResult
@@ -762,7 +918,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
path = NULL;
if (!dbus_message_get_path_decomposed (message, &path))
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -777,7 +933,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
if (path == NULL)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -846,7 +1002,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
_dbus_verbose (" (invoking a handler)\n");
#endif
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -863,7 +1019,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
message,
user_data);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
_dbus_connection_lock (tree->connection);
@@ -886,7 +1042,7 @@ _dbus_object_tree_dispatch_and_unlock (DBusObjectTree *tree,
}
else
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -1057,7 +1213,7 @@ _dbus_object_tree_list_registered_and_unlock (DBusObjectTree *tree,
parent_path,
child_entries);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (tree->connection)
#endif
{
@@ -1214,7 +1370,7 @@ flatten_path (const char **path)
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -1507,6 +1663,17 @@ run_decompose_tests (void)
return TRUE;
}
+static DBusObjectSubtree*
+find_subtree_registered_or_unregistered (DBusObjectTree *tree,
+ const char **path)
+{
+#if VERBOSE_FIND
+ _dbus_verbose ("Looking for exact subtree, registered or unregistered\n");
+#endif
+
+ return find_subtree_recurse (tree->root, path, FALSE, NULL, NULL);
+}
+
static dbus_bool_t
object_tree_test_iteration (void *data)
{
@@ -1519,6 +1686,13 @@ object_tree_test_iteration (void *data)
const char *path6[] = { "blah", "boof", NULL };
const char *path7[] = { "blah", "boof", "this", "is", "really", "long", NULL };
const char *path8[] = { "childless", NULL };
+ const char *path9[] = { "blah", "a", NULL };
+ const char *path10[] = { "blah", "b", NULL };
+ const char *path11[] = { "blah", "c", NULL };
+ const char *path12[] = { "blah", "a", "d", NULL };
+ const char *path13[] = { "blah", "b", "d", NULL };
+ const char *path14[] = { "blah", "c", "d", NULL };
+ DBusObjectPathVTable test_vtable = { NULL, test_message_function, NULL };
DBusObjectTree *tree;
TreeTestData tree_test_data[9];
int i;
@@ -1889,6 +2063,200 @@ object_tree_test_iteration (void *data)
++i;
}
+ /* Test removal of newly-childless unregistered nodes */
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
+ goto out;
+
+ _dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ /* Test that unregistered parents cannot be freed out from under their
+ children */
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
+ goto out;
+
+ _dbus_assert (!find_subtree (tree, path1, NULL));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+#if 0
+ /* This triggers the "Attempted to unregister path ..." warning message */
+ _dbus_object_tree_unregister_and_unlock (tree, path1);
+#endif
+ _dbus_assert (find_subtree (tree, path2, NULL));
+ _dbus_assert (!find_subtree (tree, path1, NULL));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_assert (!find_subtree (tree, path2, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ /* Test that registered parents cannot be freed out from under their
+ children, and that if they are unregistered before their children, they
+ are still freed when their children are unregistered */
+ if (!do_register (tree, path1, TRUE, 1, tree_test_data))
+ goto out;
+ if (!do_register (tree, path2, TRUE, 2, tree_test_data))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path1, NULL));
+ _dbus_assert (find_subtree (tree, path2, NULL));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path1);
+ _dbus_assert (!find_subtree (tree, path1, NULL));
+ _dbus_assert (find_subtree (tree, path2, NULL));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_assert (!find_subtree (tree, path1, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (!find_subtree (tree, path2, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ /* Test with NULL unregister_function and user_data */
+ if (!_dbus_object_tree_register (tree, TRUE, path2,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (_dbus_object_tree_get_user_data_unlocked (tree, path2) == NULL);
+ _dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_assert (!find_subtree (tree, path2, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ /* Test freeing a long path */
+ if (!do_register (tree, path3, TRUE, 3, tree_test_data))
+ goto out;
+
+ _dbus_object_tree_unregister_and_unlock (tree, path3);
+ _dbus_assert (!find_subtree (tree, path3, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path0));
+
+ /* Test freeing multiple children from the same path */
+ if (!do_register (tree, path3, TRUE, 3, tree_test_data))
+ goto out;
+ if (!do_register (tree, path4, TRUE, 4, tree_test_data))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path3, NULL));
+ _dbus_assert (find_subtree (tree, path4, NULL));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path3);
+ _dbus_assert (!find_subtree (tree, path3, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
+ _dbus_assert (find_subtree (tree, path4, NULL));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path4));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path1));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path4);
+ _dbus_assert (!find_subtree (tree, path4, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path4));
+ _dbus_assert (!find_subtree (tree, path3, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path3));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path2));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path1));
+
+ /* Test subtree removal */
+ if (!_dbus_object_tree_register (tree, TRUE, path12,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path12, NULL));
+
+ if (!_dbus_object_tree_register (tree, TRUE, path13,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path13, NULL));
+
+ if (!_dbus_object_tree_register (tree, TRUE, path14,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path14, NULL));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path12);
+
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
+ _dbus_assert (find_subtree (tree, path13, NULL));
+ _dbus_assert (find_subtree (tree, path14, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
+
+ if (!_dbus_object_tree_register (tree, TRUE, path12,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path12, NULL));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path13);
+
+ _dbus_assert (find_subtree (tree, path12, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
+ _dbus_assert (find_subtree (tree, path14, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
+
+ if (!_dbus_object_tree_register (tree, TRUE, path13,
+ &test_vtable,
+ NULL,
+ NULL))
+ goto out;
+
+ _dbus_assert (find_subtree (tree, path13, NULL));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path14);
+
+ _dbus_assert (find_subtree (tree, path12, NULL));
+ _dbus_assert (find_subtree (tree, path13, NULL));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path14));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path11));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path12);
+
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path12));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path9));
+ _dbus_assert (find_subtree_registered_or_unregistered (tree, path5));
+
+ _dbus_object_tree_unregister_and_unlock (tree, path13);
+
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path13));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path10));
+ _dbus_assert (!find_subtree_registered_or_unregistered (tree, path5));
+
+#if 0
+ /* Test attempting to unregister non-existent paths. These trigger
+ "Attempted to unregister path ..." warning messages */
+ _dbus_object_tree_unregister_and_unlock (tree, path0);
+ _dbus_object_tree_unregister_and_unlock (tree, path1);
+ _dbus_object_tree_unregister_and_unlock (tree, path2);
+ _dbus_object_tree_unregister_and_unlock (tree, path3);
+ _dbus_object_tree_unregister_and_unlock (tree, path4);
+#endif
+
/* Register it all again, and test dispatch */
if (!do_register (tree, path0, TRUE, 0, tree_test_data))
@@ -1962,4 +2330,4 @@ _dbus_object_tree_test (void)
#endif /* !DOXYGEN_SHOULD_SKIP_THIS */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c
index 8a9d2f49..be534105 100644
--- a/dbus/dbus-pending-call.c
+++ b/dbus/dbus-pending-call.c
@@ -79,26 +79,19 @@ struct DBusPendingCall
unsigned int timeout_added : 1; /**< Have added the timeout */
};
-#ifdef DBUS_ENABLE_VERBOSE_MODE
static void
_dbus_pending_call_trace_ref (DBusPendingCall *pending_call,
int old_refcount,
int new_refcount,
const char *why)
{
+#ifdef DBUS_ENABLE_VERBOSE_MODE
static int enabled = -1;
_dbus_trace_ref ("DBusPendingCall", pending_call, old_refcount,
new_refcount, why, "DBUS_PENDING_CALL_TRACE", &enabled);
-}
-#else
-#define _dbus_pending_call_trace_ref(p, o, n, w) \
- do \
- {\
- (void) (o); \
- (void) (n); \
- } while (0)
#endif
+}
static dbus_int32_t notify_user_data_slot = -1;
@@ -489,8 +482,8 @@ _dbus_pending_call_get_completed_unlocked (DBusPendingCall *pending)
return pending->completed;
}
-static DBusDataSlotAllocator slot_allocator;
-_DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots);
+static DBusDataSlotAllocator slot_allocator =
+ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (pending_call_slots));
/**
* Stores a pointer on a #DBusPendingCall, along
@@ -631,6 +624,8 @@ dbus_pending_call_set_notify (DBusPendingCall *pending,
void *user_data,
DBusFreeFunction free_user_data)
{
+ dbus_bool_t ret = FALSE;
+
_dbus_return_val_if_fail (pending != NULL, FALSE);
CONNECTION_LOCK (pending->connection);
@@ -638,13 +633,15 @@ dbus_pending_call_set_notify (DBusPendingCall *pending,
/* could invoke application code! */
if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot,
user_data, free_user_data))
- return FALSE;
+ goto out;
pending->function = function;
+ ret = TRUE;
+out:
CONNECTION_UNLOCK (pending->connection);
- return TRUE;
+ return ret;
}
/**
@@ -764,7 +761,6 @@ dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p)
_dbus_return_val_if_fail (slot_p != NULL, FALSE);
return _dbus_data_slot_allocator_alloc (&slot_allocator,
- &_DBUS_LOCK_NAME (pending_call_slots),
slot_p);
}
diff --git a/dbus/dbus-server-debug-pipe.c b/dbus/dbus-server-debug-pipe.c
index 419db5c5..8f5ff5fb 100644
--- a/dbus/dbus-server-debug-pipe.c
+++ b/dbus/dbus-server-debug-pipe.c
@@ -31,7 +31,7 @@
#include "dbus-string.h"
#include "dbus-protocol.h"
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* @defgroup DBusServerDebugPipe DBusServerDebugPipe
@@ -427,5 +427,5 @@ _dbus_transport_open_debug_pipe (DBusAddressEntry *entry,
/** @} */
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-server-launchd.c b/dbus/dbus-server-launchd.c
index db4673c5..9832875e 100644
--- a/dbus/dbus-server-launchd.c
+++ b/dbus/dbus-server-launchd.c
@@ -40,6 +40,7 @@
#include <launch.h>
#include <errno.h>
+#include "dbus-misc.h"
#include "dbus-server-socket.h"
/* put other private launchd functions here */
@@ -176,7 +177,7 @@ _dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
else
{
display = launch_data_get_string(environment_param);
- _dbus_setenv ("DISPLAY", display);
+ dbus_setenv ("DISPLAY", display);
}
}
}
diff --git a/dbus/dbus-server-socket.c b/dbus/dbus-server-socket.c
index ae4b602e..060a919e 100644
--- a/dbus/dbus-server-socket.c
+++ b/dbus/dbus-server-socket.c
@@ -101,7 +101,7 @@ handle_new_client_fd_and_unlock (DBusServer *server,
return TRUE;
}
- transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, FALSE);
+ transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, NULL);
if (transport == NULL)
{
_dbus_close_socket (client_fd, NULL);
@@ -478,7 +478,10 @@ _dbus_server_new_for_tcp_socket (const char *host,
if (server == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- goto failed_4;
+ if (noncefile != NULL)
+ goto failed_4;
+ else
+ goto failed_2;
}
_dbus_string_free (&port_str);
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index 130f66ec..d9952404 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -149,7 +149,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
}
else if (strcmp (method, "systemd") == 0)
{
- int n, *fds;
+ int i, n, *fds;
DBusString address;
n = _dbus_listen_systemd_sockets (&fds, error);
@@ -159,27 +159,39 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
}
- _dbus_string_init_const (&address, "systemd:");
+ if (!_dbus_string_init (&address))
+ goto systemd_oom;
- *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL);
- if (*server_p == NULL)
+ for (i = 0; i < n; i++)
{
- int i;
-
- for (i = 0; i < n; i++)
+ if (i > 0)
{
- _dbus_close_socket (fds[i], NULL);
+ if (!_dbus_string_append (&address, ";"))
+ goto systemd_oom;
}
- dbus_free (fds);
-
- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
- return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ if (!_dbus_append_address_from_socket (fds[i], &address, error))
+ goto systemd_err;
}
+ *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL);
+ if (*server_p == NULL)
+ goto systemd_oom;
+
dbus_free (fds);
return DBUS_SERVER_LISTEN_OK;
- }
+ systemd_oom:
+ _DBUS_SET_OOM (error);
+ systemd_err:
+ for (i = 0; i < n; i++)
+ {
+ _dbus_close_socket (fds[i], NULL);
+ }
+ dbus_free (fds);
+ _dbus_string_free (&address);
+
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
#ifdef DBUS_ENABLE_LAUNCHD
else if (strcmp (method, "launchd") == 0)
{
diff --git a/dbus/dbus-server-win.c b/dbus/dbus-server-win.c
index bf1c896c..bb6da483 100644
--- a/dbus/dbus-server-win.c
+++ b/dbus/dbus-server-win.c
@@ -57,33 +57,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
method = dbus_address_entry_get_method (entry);
- if (strcmp (method, "nonce-tcp") == 0)
- {
- const char *host;
- const char *port;
- const char *bind;
- const char *family;
-
- host = dbus_address_entry_get_value (entry, "host");
- bind = dbus_address_entry_get_value (entry, "bind");
- port = dbus_address_entry_get_value (entry, "port");
- family = dbus_address_entry_get_value (entry, "family");
-
- *server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
- family, error, TRUE);
-
- if (*server_p)
- {
- _DBUS_ASSERT_ERROR_IS_CLEAR(error);
- return DBUS_SERVER_LISTEN_OK;
- }
- else
- {
- _DBUS_ASSERT_ERROR_IS_SET(error);
- return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
- }
- }
- else if (strcmp (method, "autolaunch") == 0)
+ if (strcmp (method, "autolaunch") == 0)
{
const char *host = "localhost";
const char *bind = "localhost";
diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c
index b62c2b40..19d8590c 100644
--- a/dbus/dbus-server.c
+++ b/dbus/dbus-server.c
@@ -26,7 +26,7 @@
#include "dbus-server-unix.h"
#include "dbus-server-socket.h"
#include "dbus-string.h"
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-server-debug-pipe.h"
#endif
#include "dbus-address.h"
@@ -529,7 +529,7 @@ static const struct {
} listen_funcs[] = {
{ _dbus_server_listen_socket }
, { _dbus_server_listen_platform_specific }
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
, { _dbus_server_listen_debug_pipe }
#endif
};
@@ -699,13 +699,11 @@ dbus_server_ref (DBusServer *server)
_dbus_return_val_if_fail (server != NULL, NULL);
- /* can't get the refcount without a side-effect */
old_refcount = _dbus_atomic_inc (&server->refcount);
#ifndef DBUS_DISABLE_CHECKS
if (_DBUS_UNLIKELY (old_refcount <= 0))
{
- /* undo side-effect first */
_dbus_atomic_dec (&server->refcount);
_dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
_DBUS_FUNCTION_NAME, "old_refcount > 0",
@@ -736,13 +734,18 @@ dbus_server_unref (DBusServer *server)
_dbus_return_if_fail (server != NULL);
- /* can't get the refcount without a side-effect */
old_refcount = _dbus_atomic_dec (&server->refcount);
#ifndef DBUS_DISABLE_CHECKS
if (_DBUS_UNLIKELY (old_refcount <= 0))
{
- /* undo side-effect first */
+ /* undo side-effect first
+ * please do not try to simplify the code here by using
+ * _dbus_atomic_get(), why we don't use it is
+ * because it issues another atomic operation even though
+ * DBUS_DISABLE_CHECKS defined.
+ * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68303
+ */
_dbus_atomic_inc (&server->refcount);
_dbus_warn_check_failed (_dbus_return_if_fail_warning_format,
_DBUS_FUNCTION_NAME, "old_refcount > 0",
@@ -777,16 +780,7 @@ dbus_server_disconnect (DBusServer *server)
{
_dbus_return_if_fail (server != NULL);
-#ifdef DBUS_DISABLE_CHECKS
- _dbus_atomic_inc (&server->refcount);
-#else
- {
- dbus_int32_t old_refcount = _dbus_atomic_inc (&server->refcount);
-
- _dbus_return_if_fail (old_refcount > 0);
- }
-#endif
-
+ dbus_server_ref (server);
SERVER_LOCK (server);
_dbus_assert (server->vtable->disconnect != NULL);
@@ -1071,9 +1065,8 @@ dbus_server_set_auth_mechanisms (DBusServer *server,
return TRUE;
}
-
-static DBusDataSlotAllocator slot_allocator;
-_DBUS_DEFINE_GLOBAL_LOCK (server_slots);
+static DBusDataSlotAllocator slot_allocator =
+ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (server_slots));
/**
* Allocates an integer ID to be used for storing application-specific
@@ -1093,7 +1086,6 @@ dbus_bool_t
dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
{
return _dbus_data_slot_allocator_alloc (&slot_allocator,
- (DBusRMutex **)&_DBUS_LOCK_NAME (server_slots),
slot_p);
}
@@ -1190,7 +1182,7 @@ dbus_server_get_data (DBusServer *server,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <string.h>
@@ -1246,4 +1238,4 @@ _dbus_server_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-sha.c b/dbus/dbus-sha.c
index d1827522..febfba20 100644
--- a/dbus/dbus-sha.c
+++ b/dbus/dbus-sha.c
@@ -511,7 +511,7 @@ _dbus_sha_compute (const DBusString *data,
/** @} */ /* end of exported functions */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -966,4 +966,4 @@ _dbus_sha_test (const char *test_data_dir)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-shell.c b/dbus/dbus-shell.c
index 111d39df..2384961c 100644
--- a/dbus/dbus-shell.c
+++ b/dbus/dbus-shell.c
@@ -150,7 +150,7 @@ unquote_string_inplace (char* str, char** end)
* through literally instead of being expanded). This function is
* guaranteed to succeed if applied to the result of
* _dbus_shell_quote(). If it fails, it returns %NULL.
- * The @quoted_string need not actually contain quoted or
+ * The @p quoted_string need not actually contain quoted or
* escaped text; _dbus_shell_unquote() simply goes through the string and
* unquotes/unescapes anything that the shell would. Both single and
* double quotes are handled, as are escapes including escaped
@@ -163,7 +163,7 @@ unquote_string_inplace (char* str, char** end)
* be escaped with backslash. Otherwise double quotes preserve things
* literally.
*
- * @quoted_string: shell-quoted string
+ * @param quoted_string shell-quoted string
**/
char*
_dbus_shell_unquote (const char *quoted_string)
@@ -544,10 +544,10 @@ tokenize_command_line (const char *command_line, DBusError *error)
* does contain such expansions, they are passed through
* literally. Free the returned vector with dbus_free_string_array().
*
- * @command_line: command line to parse
- * @argcp: return location for number of args
- * @argvp: return location for array of args
- * @error: error information
+ * @param command_line command line to parse
+ * @param argcp return location for number of args
+ * @param argvp return location for array of args
+ * @param error error information
**/
dbus_bool_t
_dbus_shell_parse_argv (const char *command_line,
diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c
index c130de5b..8a4701c9 100644
--- a/dbus/dbus-signature.c
+++ b/dbus/dbus-signature.c
@@ -410,7 +410,7 @@ dbus_type_is_valid (int typecode)
/** @} */ /* end of DBusSignature group */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* @ingroup DBusSignatureInternals
diff --git a/dbus/dbus-socket-set-poll.c b/dbus/dbus-socket-set-poll.c
index 65a1fd23..e322a3b4 100644
--- a/dbus/dbus-socket-set-poll.c
+++ b/dbus/dbus-socket-set-poll.c
@@ -44,7 +44,7 @@ typedef struct {
#define MINIMUM_SIZE 8
/* If we're in the regression tests, force reallocation to happen sooner */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#define DEFAULT_SIZE_HINT 1
#else
#define DEFAULT_SIZE_HINT MINIMUM_SIZE
diff --git a/dbus/dbus-spawn-win.c b/dbus/dbus-spawn-win.c
index 3dae4f38..7da7a431 100644
--- a/dbus/dbus-spawn-win.c
+++ b/dbus/dbus-spawn-win.c
@@ -63,12 +63,12 @@ struct DBusBabysitter
int refcount;
HANDLE start_sync_event;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
HANDLE end_sync_event;
#endif
- char *executable;
+ char *log_name;
DBusSpawnChildSetupFunc child_setup;
void *user_data;
@@ -109,7 +109,7 @@ _dbus_babysitter_new (void)
return NULL;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
sitter->end_sync_event = CreateEvent (NULL, FALSE, FALSE, NULL);
if (sitter->end_sync_event == NULL)
{
@@ -250,7 +250,7 @@ _dbus_babysitter_unref (DBusBabysitter *sitter)
sitter->start_sync_event = NULL;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (sitter->end_sync_event != NULL)
{
CloseHandle (sitter->end_sync_event);
@@ -258,7 +258,7 @@ _dbus_babysitter_unref (DBusBabysitter *sitter)
}
#endif
- dbus_free (sitter->executable);
+ dbus_free (sitter->log_name);
dbus_free (sitter);
}
@@ -337,7 +337,7 @@ _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
char *emsg = _dbus_win_error_string (sitter->spawn_errno);
dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
"Failed to execute program %s: %s",
- sitter->executable, emsg);
+ sitter->log_name, emsg);
_dbus_win_free_error_string (emsg);
}
else if (sitter->have_child_status)
@@ -345,14 +345,14 @@ _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
PING();
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
"Process %s exited with status %d",
- sitter->executable, sitter->child_status);
+ sitter->log_name, sitter->child_status);
}
else
{
PING();
dbus_set_error (error, DBUS_ERROR_FAILED,
"Process %s exited, status unknown",
- sitter->executable);
+ sitter->log_name);
}
PING();
}
@@ -593,10 +593,10 @@ babysitter (void *parameter)
(*sitter->child_setup) (sitter->user_data);
}
- _dbus_verbose ("babysitter: spawning %s\n", sitter->executable);
+ _dbus_verbose ("babysitter: spawning %s\n", sitter->log_name);
PING();
- sitter->child_handle = spawn_program (sitter->executable,
+ sitter->child_handle = spawn_program (sitter->log_name,
sitter->argv, sitter->envp);
PING();
@@ -628,7 +628,7 @@ babysitter (void *parameter)
sitter->child_handle = NULL;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
SetEvent (sitter->end_sync_event);
#endif
@@ -642,6 +642,7 @@ babysitter (void *parameter)
dbus_bool_t
_dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
+ const char *log_name,
char **argv,
char **envp,
DBusSpawnChildSetupFunc child_setup,
@@ -653,6 +654,7 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
DWORD sitter_thread_id;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ _dbus_assert (argv[0] != NULL);
*sitter_p = NULL;
@@ -667,8 +669,17 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
sitter->child_setup = child_setup;
sitter->user_data = user_data;
- sitter->executable = _dbus_strdup (argv[0]);
- if (sitter->executable == NULL)
+ sitter->log_name = _dbus_strdup (log_name);
+ if (sitter->log_name == NULL && log_name != NULL)
+ {
+ _DBUS_SET_OOM (error);
+ goto out0;
+ }
+
+ if (sitter->log_name == NULL)
+ sitter->log_name = _dbus_strdup (argv[0]);
+
+ if (sitter->log_name == NULL)
{
_DBUS_SET_OOM (error);
goto out0;
@@ -753,7 +764,7 @@ _dbus_babysitter_set_result_function (DBusBabysitter *sitter,
sitter->finished_data = user_data;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static char *
get_test_exec (const char *exe,
@@ -804,7 +815,7 @@ check_spawn_nonexistent (void *data)
/*** Test launching nonexistent binary */
argv[0] = "/this/does/not/exist/32542sdgafgafdg";
- if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent", argv, NULL,
NULL, NULL,
&error))
{
@@ -857,7 +868,7 @@ check_spawn_segfault (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv, NULL,
NULL, NULL,
&error))
{
@@ -912,7 +923,7 @@ check_spawn_exit (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv, NULL,
NULL, NULL,
&error))
{
@@ -967,7 +978,7 @@ check_spawn_and_kill (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv, NULL,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv, NULL,
NULL, NULL,
&error))
{
diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c
index ef00801c..b95cad6e 100644
--- a/dbus/dbus-spawn.c
+++ b/dbus/dbus-spawn.c
@@ -38,6 +38,12 @@
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
+#ifdef HAVE_SYSTEMD
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+#include <systemd/sd-journal.h>
+#endif
extern char **environ;
@@ -174,6 +180,48 @@ read_pid (int fd,
* and the grandchild. The grandchild is our spawned process. The intermediate
* child is a babysitter process; it keeps track of when the grandchild
* exits/crashes, and reaps the grandchild.
+ *
+ * We automatically reap the babysitter process, killing it if necessary,
+ * when the DBusBabysitter's refcount goes to zero.
+ *
+ * Processes:
+ *
+ * main process
+ * | fork() A
+ * \- babysitter
+ * | fork () B
+ * \- grandchild --> exec --> spawned process
+ *
+ * IPC:
+ * child_err_report_pipe
+ * /-----------<---------<--------------\
+ * | ^
+ * v |
+ * main process babysitter grandchild
+ * ^ ^
+ * v v
+ * \-------<->-------/
+ * babysitter_pipe
+ *
+ * child_err_report_pipe is genuinely a pipe.
+ * The READ_END (also called error_pipe_from_child) is used in the main
+ * process. The WRITE_END (also called child_err_report_fd) is used in
+ * the grandchild process.
+ *
+ * On failure, the grandchild process sends CHILD_EXEC_FAILED + errno.
+ * On success, the pipe just closes (because it's close-on-exec) without
+ * sending any bytes.
+ *
+ * babysitter_pipe is mis-named: it's really a bidirectional socketpair.
+ * The [0] end (also called socket_to_babysitter) is used in the main
+ * process, the [1] end (also called parent_pipe) is used in the babysitter.
+ *
+ * If the fork() labelled B in the diagram above fails, the babysitter sends
+ * CHILD_FORK_FAILED + errno.
+ * On success, the babysitter sends CHILD_PID + the grandchild's pid.
+ * On SIGCHLD, the babysitter sends CHILD_EXITED + the exit status.
+ * The main process doesn't explicitly send anything, but when it exits,
+ * the babysitter gets POLLHUP or POLLERR.
*/
/* Messages from children to parents */
@@ -192,7 +240,8 @@ struct DBusBabysitter
{
int refcount; /**< Reference count */
- char *executable; /**< executable name to use in error messages */
+ char *log_name; /**< the name under which to log messages about this
+ process being spawned */
int socket_to_babysitter; /**< Connection to the babysitter process */
int error_pipe_from_child; /**< Connection to the process that does the exec() */
@@ -308,15 +357,18 @@ _dbus_babysitter_unref (DBusBabysitter *sitter)
if (ret == 0)
kill (sitter->sitter_pid, SIGKILL);
- again:
if (ret == 0)
- ret = waitpid (sitter->sitter_pid, &status, 0);
+ {
+ do
+ {
+ ret = waitpid (sitter->sitter_pid, &status, 0);
+ }
+ while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
+ }
if (ret < 0)
{
- if (errno == EINTR)
- goto again;
- else if (errno == ECHILD)
+ if (errno == ECHILD)
_dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
else
_dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",
@@ -343,7 +395,7 @@ _dbus_babysitter_unref (DBusBabysitter *sitter)
if (sitter->watches)
_dbus_watch_list_free (sitter->watches);
- dbus_free (sitter->executable);
+ dbus_free (sitter->log_name);
dbus_free (sitter);
}
@@ -698,34 +750,34 @@ _dbus_babysitter_set_child_exit_error (DBusBabysitter *sitter,
{
dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
"Failed to execute program %s: %s",
- sitter->executable, _dbus_strerror (sitter->errnum));
+ sitter->log_name, _dbus_strerror (sitter->errnum));
}
else if (sitter->have_fork_errnum)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
"Failed to fork a new process %s: %s",
- sitter->executable, _dbus_strerror (sitter->errnum));
+ sitter->log_name, _dbus_strerror (sitter->errnum));
}
else if (sitter->have_child_status)
{
if (WIFEXITED (sitter->status))
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
"Process %s exited with status %d",
- sitter->executable, WEXITSTATUS (sitter->status));
+ sitter->log_name, WEXITSTATUS (sitter->status));
else if (WIFSIGNALED (sitter->status))
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
"Process %s received signal %d",
- sitter->executable, WTERMSIG (sitter->status));
+ sitter->log_name, WTERMSIG (sitter->status));
else
dbus_set_error (error, DBUS_ERROR_FAILED,
"Process %s exited abnormally",
- sitter->executable);
+ sitter->log_name);
}
else
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Process %s exited, reason unknown",
- sitter->executable);
+ sitter->log_name);
}
}
@@ -807,9 +859,14 @@ handle_watch (DBusWatch *watch,
#define WRITE_END 1
-/* Avoids a danger in threaded situations (calling close()
- * on a file descriptor twice, and another thread has
- * re-opened it since the first close)
+/* Avoids a danger in re-entrant situations (calling close()
+ * on a file descriptor twice, and another module has
+ * re-opened it since the first close).
+ *
+ * This previously claimed to be relevant for threaded situations, but by
+ * trivial inspection, it is not thread-safe. It doesn't actually
+ * matter, since this module is only used in the -util variant of the
+ * library, which is only used in single-threaded situations.
*/
static int
close_and_invalidate (int *fd)
@@ -936,7 +993,7 @@ do_exec (int child_err_report_fd,
DBusSpawnChildSetupFunc child_setup,
void *user_data)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
int i, max_open;
#endif
@@ -947,7 +1004,7 @@ do_exec (int child_err_report_fd,
if (child_setup)
(* child_setup) (user_data);
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
max_open = sysconf (_SC_OPEN_MAX);
for (i = 3; i < max_open; i++)
@@ -1115,8 +1172,7 @@ babysit (pid_t grandchild_pid,
}
/**
- * Spawns a new process. The executable name and argv[0]
- * are the same, both are provided in argv[0]. The child_setup
+ * Spawns a new process. The child_setup
* function is passed the given user_data and is run in the child
* just before calling exec().
*
@@ -1126,8 +1182,9 @@ babysit (pid_t grandchild_pid,
* If sitter_p is #NULL, no babysitter is kept.
*
* @param sitter_p return location for babysitter or #NULL
+ * @param log_name the name under which to log messages about this process being spawned
* @param argv the executable and arguments
- * @param env the environment (not used on unix yet)
+ * @param env the environment, or #NULL to copy the parent's
* @param child_setup function to call in child pre-exec()
* @param user_data user data for setup function
* @param error error object to be filled in if function fails
@@ -1135,6 +1192,7 @@ babysit (pid_t grandchild_pid,
*/
dbus_bool_t
_dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
+ const char *log_name,
char **argv,
char **env,
DBusSpawnChildSetupFunc child_setup,
@@ -1145,8 +1203,13 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
int child_err_report_pipe[2] = { -1, -1 };
int babysitter_pipe[2] = { -1, -1 };
pid_t pid;
+#ifdef HAVE_SYSTEMD
+ int fd_out = -1;
+ int fd_err = -1;
+#endif
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ _dbus_assert (argv[0] != NULL);
if (sitter_p != NULL)
*sitter_p = NULL;
@@ -1160,8 +1223,17 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
return FALSE;
}
- sitter->executable = _dbus_strdup (argv[0]);
- if (sitter->executable == NULL)
+ sitter->log_name = _dbus_strdup (log_name);
+ if (sitter->log_name == NULL && log_name != NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto cleanup_and_fail;
+ }
+
+ if (sitter->log_name == NULL)
+ sitter->log_name = _dbus_strdup (argv[0]);
+
+ if (sitter->log_name == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
goto cleanup_and_fail;
@@ -1221,7 +1293,16 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
}
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
-
+
+#ifdef HAVE_SYSTEMD
+ /* This may fail, but it's not critical.
+ * In particular, if we were compiled with journald support but are now
+ * running on a non-systemd system, this is going to fail, so we
+ * have to cope gracefully. */
+ fd_out = sd_journal_stream_fd (sitter->log_name, LOG_INFO, FALSE);
+ fd_err = sd_journal_stream_fd (sitter->log_name, LOG_WARNING, FALSE);
+#endif
+
pid = fork ();
if (pid < 0)
@@ -1256,7 +1337,21 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
_dbus_assert_not_reached ("Got to code after write_err_and_exit()");
}
else if (grandchild_pid == 0)
- {
+ {
+ /* Go back to ignoring SIGPIPE, since it's evil
+ */
+ signal (SIGPIPE, SIG_IGN);
+
+ close_and_invalidate (&babysitter_pipe[1]);
+#ifdef HAVE_SYSTEMD
+ /* log to systemd journal if possible */
+ if (fd_out >= 0)
+ dup2 (fd_out, STDOUT_FILENO);
+ if (fd_err >= 0)
+ dup2 (fd_err, STDERR_FILENO);
+ close_and_invalidate (&fd_out);
+ close_and_invalidate (&fd_err);
+#endif
do_exec (child_err_report_pipe[WRITE_END],
argv,
env,
@@ -1265,6 +1360,11 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
}
else
{
+ close_and_invalidate (&child_err_report_pipe[WRITE_END]);
+#ifdef HAVE_SYSTEMD
+ close_and_invalidate (&fd_out);
+ close_and_invalidate (&fd_err);
+#endif
babysit (grandchild_pid, babysitter_pipe[1]);
_dbus_assert_not_reached ("Got to code after babysit()");
}
@@ -1274,6 +1374,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
/* Close the uncared-about ends of the pipes */
close_and_invalidate (&child_err_report_pipe[WRITE_END]);
close_and_invalidate (&babysitter_pipe[1]);
+#ifdef HAVE_SYSTEMD
+ close_and_invalidate (&fd_out);
+ close_and_invalidate (&fd_err);
+#endif
sitter->socket_to_babysitter = babysitter_pipe[0];
babysitter_pipe[0] = -1;
@@ -1303,6 +1407,10 @@ _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
close_and_invalidate (&child_err_report_pipe[WRITE_END]);
close_and_invalidate (&babysitter_pipe[0]);
close_and_invalidate (&babysitter_pipe[1]);
+#ifdef HAVE_SYSTEMD
+ close_and_invalidate (&fd_out);
+ close_and_invalidate (&fd_err);
+#endif
if (sitter != NULL)
_dbus_babysitter_unref (sitter);
@@ -1321,7 +1429,7 @@ _dbus_babysitter_set_result_function (DBusBabysitter *sitter,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static char *
get_test_exec (const char *exe,
@@ -1364,7 +1472,7 @@ check_spawn_nonexistent (void *data)
/*** Test launching nonexistent binary */
argv[0] = "/this/does/not/exist/32542sdgafgafdg";
- if (_dbus_spawn_async_with_babysitter (&sitter, argv,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent", argv,
NULL, NULL, NULL,
&error))
{
@@ -1413,7 +1521,7 @@ check_spawn_segfault (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv,
NULL, NULL, NULL,
&error))
{
@@ -1464,7 +1572,7 @@ check_spawn_exit (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv,
NULL, NULL, NULL,
&error))
{
@@ -1515,7 +1623,7 @@ check_spawn_and_kill (void *data)
return TRUE;
}
- if (_dbus_spawn_async_with_babysitter (&sitter, argv,
+ if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv,
NULL, NULL, NULL,
&error))
{
diff --git a/dbus/dbus-spawn.h b/dbus/dbus-spawn.h
index a8814fb9..e6baae97 100644
--- a/dbus/dbus-spawn.h
+++ b/dbus/dbus-spawn.h
@@ -39,6 +39,7 @@ typedef void (* DBusBabysitterFinishedFunc) (DBusBabysitter *sitter,
void *user_data);
dbus_bool_t _dbus_spawn_async_with_babysitter (DBusBabysitter **sitter_p,
+ const char *log_name,
char **argv,
char **env,
DBusSpawnChildSetupFunc child_setup,
diff --git a/dbus/dbus-string-util.c b/dbus/dbus-string-util.c
index 922580da..3babc053 100644
--- a/dbus/dbus-string-util.c
+++ b/dbus/dbus-string-util.c
@@ -115,7 +115,7 @@ _dbus_string_find_byte_backward (const DBusString *str,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-test.h"
#include <stdio.h>
@@ -935,4 +935,4 @@ _dbus_string_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c
index f2726eee..006e4560 100644
--- a/dbus/dbus-string.c
+++ b/dbus/dbus-string.c
@@ -246,6 +246,14 @@ _dbus_string_free (DBusString *str)
if (real->constant)
return;
+
+ /* so it's safe if @p str returned by a failed
+ * _dbus_string_init call
+ * Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65959
+ */
+ if (real->str == NULL)
+ return;
+
dbus_free (real->str - real->align_offset);
real->invalid = TRUE;
@@ -277,9 +285,9 @@ compact (DBusRealString *real,
return TRUE;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/* Not using this feature at the moment,
- * so marked DBUS_BUILD_TESTS-only
+ * so marked DBUS_ENABLE_EMBEDDED_TESTS-only
*/
/**
* Locks a string such that any attempts to change the string will
@@ -303,7 +311,7 @@ _dbus_string_lock (DBusString *str)
#define MAX_WASTE 48
compact (real, MAX_WASTE);
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
static dbus_bool_t
reallocate_for_length (DBusRealString *real,
@@ -327,14 +335,11 @@ reallocate_for_length (DBusRealString *real,
* disable asserts to profile, you don't get this destroyer
* of profiles.
*/
-#ifdef DBUS_DISABLE_ASSERT
-#else
-#ifdef DBUS_BUILD_TESTS
+#if defined (DBUS_ENABLE_EMBEDDED_TESTS) && !defined (DBUS_DISABLE_ASSERT)
new_allocated = 0; /* ensure a realloc every time so that we go
* through all malloc failure codepaths
*/
-#endif /* DBUS_BUILD_TESTS */
-#endif /* !DBUS_DISABLE_ASSERT */
+#endif
/* But be sure we always alloc at least space for the new length */
new_allocated = MAX (new_allocated,
@@ -949,29 +954,9 @@ _dbus_string_append (DBusString *str,
#define ASSIGN_4_OCTETS(p, octets) \
*((dbus_uint32_t*)(p)) = *((dbus_uint32_t*)(octets));
-#ifdef DBUS_HAVE_INT64
/** assign 8 bytes from one string to another */
#define ASSIGN_8_OCTETS(p, octets) \
*((dbus_uint64_t*)(p)) = *((dbus_uint64_t*)(octets));
-#else
-/** assign 8 bytes from one string to another */
-#define ASSIGN_8_OCTETS(p, octets) \
-do { \
- unsigned char *b; \
- \
- b = p; \
- \
- *b++ = octets[0]; \
- *b++ = octets[1]; \
- *b++ = octets[2]; \
- *b++ = octets[3]; \
- *b++ = octets[4]; \
- *b++ = octets[5]; \
- *b++ = octets[6]; \
- *b++ = octets[7]; \
- _dbus_assert (b == p + 8); \
-} while (0)
-#endif /* DBUS_HAVE_INT64 */
/**
* Inserts 2 bytes aligned on a 2 byte boundary
@@ -985,7 +970,7 @@ do { \
dbus_bool_t
_dbus_string_insert_2_aligned (DBusString *str,
int insert_at,
- const unsigned char octets[4])
+ const unsigned char octets[2])
{
DBUS_STRING_PREAMBLE (str);
@@ -1593,19 +1578,11 @@ _dbus_string_split_on_byte (DBusString *source,
*
* The second check covers surrogate pairs (category Cs).
*
- * The last two checks cover "Noncharacter": defined as:
- * "A code point that is permanently reserved for
- * internal use, and that should never be interchanged. In
- * Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF
- * (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF."
- *
* @param Char the character
*/
#define UNICODE_VALID(Char) \
((Char) < 0x110000 && \
- (((Char) & 0xFFFFF800) != 0xD800) && \
- ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \
- ((Char) & 0xFFFE) != 0xFFFE)
+ (((Char) & 0xFFFFF800) != 0xD800))
/**
* Finds the given substring in the string,
@@ -1920,7 +1897,7 @@ _dbus_string_skip_white_reverse (const DBusString *str,
* @todo owen correctly notes that this is a stupid function (it was
* written purely for test code,
* e.g. dbus-message-builder.c). Probably should be enforced as test
- * code only with ifdef DBUS_BUILD_TESTS
+ * code only with ifdef DBUS_ENABLE_EMBEDDED_TESTS
*
* @param source the source string
* @param dest the destination string (contents are replaced)
@@ -1964,7 +1941,7 @@ _dbus_string_pop_line (DBusString *source,
return TRUE;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Deletes up to and including the first blank space
* in the string.
@@ -1983,7 +1960,7 @@ _dbus_string_delete_first_word (DBusString *str)
}
#endif
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Deletes any leading blanks in the string
*
@@ -2244,7 +2221,7 @@ _dbus_string_starts_with_c_str (const DBusString *a,
*/
dbus_bool_t
_dbus_string_append_byte_as_hex (DBusString *str,
- int byte)
+ unsigned char byte)
{
const char hexdigits[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
diff --git a/dbus/dbus-string.h b/dbus/dbus-string.h
index ec52400a..2ebdf56f 100644
--- a/dbus/dbus-string.h
+++ b/dbus/dbus-string.h
@@ -263,7 +263,7 @@ void _dbus_string_delete_first_word (DBusString *str);
void _dbus_string_delete_leading_blanks (DBusString *str);
void _dbus_string_chop_white (DBusString *str);
dbus_bool_t _dbus_string_append_byte_as_hex (DBusString *str,
- int byte);
+ unsigned char byte);
dbus_bool_t _dbus_string_hex_encode (const DBusString *source,
int start,
DBusString *dest,
diff --git a/dbus/dbus-syntax.c b/dbus/dbus-syntax.c
index 47922875..7ef659cb 100644
--- a/dbus/dbus-syntax.c
+++ b/dbus/dbus-syntax.c
@@ -93,7 +93,7 @@ dbus_validate_path (const char *path,
* is also checked, since it assumes that the string ends at the first zero
* byte according to normal C conventions.
*
- * @param path a potentially invalid interface name, which must not be #NULL
+ * @param name a potentially invalid interface name, which must not be #NULL
* @param error error return
* @returns #TRUE if name is valid
*/
@@ -140,7 +140,7 @@ dbus_validate_interface (const char *name,
* is also checked, since it assumes that the string ends at the first zero
* byte according to normal C conventions.
*
- * @param path a potentially invalid member name, which must not be #NULL
+ * @param name a potentially invalid member name, which must not be #NULL
* @param error error return
* @returns #TRUE if name is valid
*/
@@ -187,7 +187,7 @@ dbus_validate_member (const char *name,
* is also checked, since it assumes that the string ends at the first zero
* byte according to normal C conventions.
*
- * @param path a potentially invalid error name, which must not be #NULL
+ * @param name a potentially invalid error name, which must not be #NULL
* @param error error return
* @returns #TRUE if name is valid
*/
@@ -234,7 +234,7 @@ dbus_validate_error_name (const char *name,
* is also checked, since it assumes that the string ends at the first zero
* byte according to normal C conventions.
*
- * @param path a potentially invalid bus name, which must not be #NULL
+ * @param name a potentially invalid bus name, which must not be #NULL
* @param error error return
* @returns #TRUE if name is valid
*/
diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c
index c9ec9e5b..1300ec35 100644
--- a/dbus/dbus-sysdeps-pthread.c
+++ b/dbus/dbus-sysdeps-pthread.c
@@ -36,12 +36,14 @@
#include <config.h>
+#ifdef HAVE_MONOTONIC_CLOCK
/* Whether we have a "monotonic" clock; i.e. a clock not affected by
* changes in system time.
* This is initialized once in check_monotonic_clock below.
* https://bugs.freedesktop.org/show_bug.cgi?id=18121
*/
static dbus_bool_t have_monotonic_clock = 0;
+#endif
struct DBusRMutex {
pthread_mutex_t lock; /**< the lock */
@@ -275,6 +277,26 @@ check_monotonic_clock (void)
dbus_bool_t
_dbus_threads_init_platform_specific (void)
{
+ /* These have static variables, and we need to handle both the case
+ * where dbus_threads_init() has been called and when it hasn't;
+ * so initialize them before any threads are allowed to enter.
+ */
check_monotonic_clock ();
- return dbus_threads_init (NULL);
+ (void) _dbus_check_setuid ();
+
+ return TRUE;
+}
+
+static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void
+_dbus_threads_lock_platform_specific (void)
+{
+ pthread_mutex_lock (&init_mutex);
+}
+
+void
+_dbus_threads_unlock_platform_specific (void)
+{
+ pthread_mutex_unlock (&init_mutex);
}
diff --git a/dbus/dbus-sysdeps-thread-win.c b/dbus/dbus-sysdeps-thread-win.c
index e30e7b87..0887a549 100644
--- a/dbus/dbus-sysdeps-thread-win.c
+++ b/dbus/dbus-sysdeps-thread-win.c
@@ -30,6 +30,21 @@
#include <windows.h>
+static dbus_bool_t global_init_done = FALSE;
+static CRITICAL_SECTION init_lock;
+
+/* Called from C++ code in dbus-init-win.cpp. */
+void
+_dbus_threads_windows_init_global (void)
+{
+ /* this ensures that the object that acts as our global constructor
+ * actually gets linked in when we're linked statically */
+ _dbus_threads_windows_ensure_ctor_linked ();
+
+ InitializeCriticalSection (&init_lock);
+ global_init_done = TRUE;
+}
+
struct DBusCondVar {
DBusList *list; /**< list thread-local-stored events waiting on the cond variable */
CRITICAL_SECTION lock; /**< lock protecting the list */
@@ -269,6 +284,19 @@ _dbus_threads_init_platform_specific (void)
return FALSE;
}
- return dbus_threads_init (NULL);
+ return TRUE;
+}
+
+void
+_dbus_threads_lock_platform_specific (void)
+{
+ _dbus_assert (global_init_done);
+ EnterCriticalSection (&init_lock);
}
+void
+_dbus_threads_unlock_platform_specific (void)
+{
+ _dbus_assert (global_init_done);
+ LeaveCriticalSection (&init_lock);
+}
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index cef8bd31..ae42f56e 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -55,6 +55,7 @@
#include <netinet/in.h>
#include <netdb.h>
#include <grp.h>
+#include <arpa/inet.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
@@ -71,6 +72,9 @@
#ifdef HAVE_GETPEERUCRED
#include <ucred.h>
#endif
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
#ifdef HAVE_ADT
#include <bsm/adt.h>
@@ -78,6 +82,10 @@
#include "sd-daemon.h"
+#if !DBUS_USE_SYNC
+#include <pthread.h>
+#endif
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -136,7 +144,7 @@ _dbus_open_socket (int *fd_p,
cloexec_done = *fd_p >= 0;
/* Check if kernel seems to be too old to know SOCK_CLOEXEC */
- if (*fd_p < 0 && errno == EINVAL)
+ if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
{
*fd_p = socket (domain, type, protocol);
@@ -733,7 +741,7 @@ _dbus_write_two (int fd,
}
#else /* HAVE_WRITEV */
{
- int ret1;
+ int ret1, ret2;
ret1 = _dbus_write (fd, buffer1, start1, len1);
if (ret1 == len1 && buffer2 != NULL)
@@ -884,16 +892,24 @@ _dbus_connect_exec (const char *path,
{
int fds[2];
pid_t pid;
+ int retval;
+ dbus_bool_t cloexec_done = 0;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
_dbus_verbose ("connecting to process %s\n", path);
- if (socketpair (AF_UNIX, SOCK_STREAM
#ifdef SOCK_CLOEXEC
- |SOCK_CLOEXEC
+ retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
+ cloexec_done = (retval >= 0);
+
+ if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
- , 0, fds) < 0)
+ {
+ retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
+ }
+
+ if (retval < 0)
{
dbus_set_error (error,
_dbus_error_from_errno (errno),
@@ -902,8 +918,11 @@ _dbus_connect_exec (const char *path,
return -1;
}
- _dbus_fd_set_close_on_exec (fds[0]);
- _dbus_fd_set_close_on_exec (fds[1]);
+ if (!cloexec_done)
+ {
+ _dbus_fd_set_close_on_exec (fds[0]);
+ _dbus_fd_set_close_on_exec (fds[1]);
+ }
pid = fork ();
if (pid < 0)
@@ -956,39 +975,6 @@ _dbus_connect_exec (const char *path,
}
/**
- * Enables or disables the reception of credentials on the given socket during
- * the next message transmission. This is only effective if the #LOCAL_CREDS
- * system feature exists, in which case the other side of the connection does
- * not have to do anything special to send the credentials.
- *
- * @param fd socket on which to change the #LOCAL_CREDS flag.
- * @param on whether to enable or disable the #LOCAL_CREDS flag.
- */
-static dbus_bool_t
-_dbus_set_local_creds (int fd, dbus_bool_t on)
-{
- dbus_bool_t retval = TRUE;
-
-#if defined(HAVE_CMSGCRED)
- /* NOOP just to make sure only one codepath is used
- * and to prefer CMSGCRED
- */
-#elif defined(LOCAL_CREDS)
- int val = on ? 1 : 0;
- if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
- {
- _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
- retval = FALSE;
- }
- else
- _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
- on ? "enabled" : "disabled", fd);
-#endif
-
- return retval;
-}
-
-/**
* Creates a socket and binds it to the given path,
* then listens on the socket. The socket is
* set to be nonblocking.
@@ -1013,7 +999,6 @@ _dbus_listen_unix_socket (const char *path,
int listen_fd;
struct sockaddr_un addr;
size_t path_len;
- unsigned int reuseaddr;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
@@ -1088,13 +1073,6 @@ _dbus_listen_unix_socket (const char *path,
strncpy (addr.sun_path, path, path_len);
}
- reuseaddr = 1;
- if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
- {
- _dbus_warn ("Failed to set socket option\"%s\": %s",
- path, _dbus_strerror (errno));
- }
-
if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
{
dbus_set_error (error, _dbus_error_from_errno (errno),
@@ -1113,15 +1091,6 @@ _dbus_listen_unix_socket (const char *path,
return -1;
}
- if (!_dbus_set_local_creds (listen_fd, TRUE))
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
- path, _dbus_strerror (errno));
- close (listen_fd);
- return -1;
- }
-
if (!_dbus_set_fd_nonblocking (listen_fd, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
@@ -1145,7 +1114,7 @@ _dbus_listen_unix_socket (const char *path,
*
* This will set FD_CLOEXEC for the sockets returned.
*
- * @oaram fds the file descriptors
+ * @param fds the file descriptors
* @param error return location for errors
* @returns the number of file descriptors
*/
@@ -1207,14 +1176,6 @@ _dbus_listen_systemd_sockets (int **fds,
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
{
- if (!_dbus_set_local_creds (fd, TRUE))
- {
- dbus_set_error (error, _dbus_error_from_errno (errno),
- "Failed to enable LOCAL_CREDS on systemd socket: %s",
- _dbus_strerror (errno));
- goto fail;
- }
-
if (!_dbus_set_fd_nonblocking (fd, error))
{
_DBUS_ASSERT_ERROR_IS_SET (error);
@@ -1603,13 +1564,19 @@ write_credentials_byte (int server_fd,
|MSG_NOSIGNAL
#endif
);
-#else
- bytes_written = send (server_fd, buf, 1, 0
-#if HAVE_DECL_MSG_NOSIGNAL
- |MSG_NOSIGNAL
+
+ /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
+ * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
+ * only allows that on AF_UNIX. Try just doing a send() instead. */
+ if (bytes_written < 0 && errno == EINVAL)
#endif
- );
+ {
+ bytes_written = send (server_fd, buf, 1, 0
+#if HAVE_DECL_MSG_NOSIGNAL
+ |MSG_NOSIGNAL
#endif
+ );
+ }
if (bytes_written < 0 && errno == EINTR)
goto again;
@@ -1673,12 +1640,6 @@ _dbus_read_credentials_socket (int client_fd,
struct cmsghdr hdr;
char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
} cmsg;
-
-#elif defined(LOCAL_CREDS)
- struct {
- struct cmsghdr hdr;
- struct sockcred cred;
- } cmsg;
#endif
uid_read = DBUS_UID_UNSET;
@@ -1696,12 +1657,6 @@ _dbus_read_credentials_socket (int client_fd,
_dbus_credentials_clear (credentials);
- /* Systems supporting LOCAL_CREDS are configured to have this feature
- * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
- * the connection. Therefore, the received message must carry the
- * credentials information without doing anything special.
- */
-
iov.iov_base = &buf;
iov.iov_len = 1;
@@ -1709,7 +1664,7 @@ _dbus_read_credentials_socket (int client_fd,
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
-#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
+#if defined(HAVE_CMSGCRED)
_DBUS_ZERO(cmsg);
msg.msg_control = (caddr_t) &cmsg;
msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
@@ -1749,20 +1704,18 @@ _dbus_read_credentials_socket (int client_fd,
return FALSE;
}
-#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
- if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
- || cmsg.hdr.cmsg_type != SCM_CREDS)
- {
- dbus_set_error (error, DBUS_ERROR_FAILED,
- "Message from recvmsg() was not SCM_CREDS");
- return FALSE;
- }
-#endif
-
_dbus_verbose ("read credentials byte\n");
{
#ifdef SO_PEERCRED
+ /* Supported by at least Linux and OpenBSD, with minor differences.
+ *
+ * This mechanism passes the process ID through and does not require
+ * the peer's cooperation, so we prefer it over all others. Notably,
+ * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
+ * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
+ * because this is much less fragile.
+ */
#ifdef __OpenBSD__
struct sockpeercred cr;
#else
@@ -1782,29 +1735,36 @@ _dbus_read_credentials_socket (int client_fd,
cr_len, (int) sizeof (cr), _dbus_strerror (errno));
}
#elif defined(HAVE_CMSGCRED)
+ /* We only check for HAVE_CMSGCRED, but we're really assuming that the
+ * presence of that struct implies SCM_CREDS. Supported by at least
+ * FreeBSD and DragonflyBSD.
+ *
+ * This mechanism requires the peer to help us (it has to send us a
+ * SCM_CREDS message) but it does pass the process ID through,
+ * which makes it better than getpeereid().
+ */
struct cmsgcred *cred;
+ struct cmsghdr *cmsgp;
- cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
- pid_read = cred->cmcred_pid;
- uid_read = cred->cmcred_euid;
-#elif defined(LOCAL_CREDS)
- pid_read = DBUS_PID_UNSET;
- uid_read = cmsg.cred.sc_uid;
- /* Since we have already got the credentials from this socket, we can
- * disable its LOCAL_CREDS flag if it was ever set. */
- _dbus_set_local_creds (client_fd, FALSE);
-#elif defined(HAVE_GETPEEREID)
- uid_t euid;
- gid_t egid;
- if (getpeereid (client_fd, &euid, &egid) == 0)
+ for (cmsgp = CMSG_FIRSTHDR (&msg);
+ cmsgp != NULL;
+ cmsgp = CMSG_NXTHDR (&msg, cmsgp))
{
- uid_read = euid;
- }
- else
- {
- _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
+ if (cmsgp->cmsg_type == SCM_CREDS &&
+ cmsgp->cmsg_level == SOL_SOCKET &&
+ cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
+ {
+ cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
+ pid_read = cred->cmcred_pid;
+ uid_read = cred->cmcred_euid;
+ break;
+ }
}
+
#elif defined(HAVE_GETPEERUCRED)
+ /* Supported in at least Solaris >= 10. It should probably be higher
+ * up this list, because it carries the pid and we use this code path
+ * for audit data. */
ucred_t * ucred = NULL;
if (getpeerucred (client_fd, &ucred) == 0)
{
@@ -1848,7 +1808,54 @@ _dbus_read_credentials_socket (int client_fd,
}
if (ucred != NULL)
ucred_free (ucred);
-#else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
+
+ /* ----------------------------------------------------------------
+ * When adding new mechanisms, please add them above this point
+ * if they support passing the process ID through, or below if not.
+ * ---------------------------------------------------------------- */
+
+#elif defined(HAVE_GETPEEREID)
+ /* getpeereid() originates from D.J. Bernstein and is fairly
+ * widely-supported. According to a web search, it might be present in
+ * any/all of:
+ *
+ * - AIX?
+ * - Blackberry?
+ * - Cygwin
+ * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
+ * - Mac OS X
+ * - Minix 3.1.8+
+ * - MirBSD?
+ * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
+ * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
+ * - QNX?
+ */
+ uid_t euid;
+ gid_t egid;
+ if (getpeereid (client_fd, &euid, &egid) == 0)
+ {
+ uid_read = euid;
+ }
+ else
+ {
+ _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
+ }
+#else /* no supported mechanism */
+
+#warning Socket credentials not supported on this Unix OS
+#warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
+
+ /* Please add other operating systems known to support at least one of
+ * the mechanisms above to this list, keeping alphabetical order.
+ * Everything not in this list is best-effort.
+ */
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+ defined(__linux__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+# error Credentials passing not working on this OS is a regression!
+#endif
+
_dbus_verbose ("Socket credentials not supported on this OS\n");
#endif
}
@@ -1862,7 +1869,7 @@ _dbus_read_credentials_socket (int client_fd,
if (pid_read != DBUS_PID_UNSET)
{
- if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
+ if (!_dbus_credentials_add_pid (credentials, pid_read))
{
_DBUS_SET_OOM (error);
return FALSE;
@@ -1934,11 +1941,15 @@ _dbus_accept (int listen_fd)
retry:
#ifdef HAVE_ACCEPT4
- /* We assume that if accept4 is available SOCK_CLOEXEC is too */
+ /*
+ * At compile-time, we assume that if accept4() is available in
+ * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
+ * not necessarily true that either is supported by the running kernel.
+ */
client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
cloexec_done = client_fd >= 0;
- if (client_fd < 0 && errno == ENOSYS)
+ if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
#endif
{
client_fd = accept (listen_fd, &addr, &addrlen);
@@ -1988,6 +1999,16 @@ _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
return FALSE;
}
+ if (sb.st_uid != geteuid ())
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "%s directory is owned by user %lu, not %lu",
+ directory,
+ (unsigned long) sb.st_uid,
+ (unsigned long) geteuid ());
+ return FALSE;
+ }
+
if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
(S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
{
@@ -2317,7 +2338,7 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
_dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
_dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
- if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
+ if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
return FALSE;
if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
return FALSE;
@@ -2424,7 +2445,12 @@ _dbus_parse_uid (const DBusString *uid_str,
}
#if !DBUS_USE_SYNC
-_DBUS_DEFINE_GLOBAL_LOCK (atomic);
+/* To be thread-safe by default on platforms that don't necessarily have
+ * atomic operations (notably Debian armel, which is armv4t), we must
+ * use a mutex that can be initialized statically, like this.
+ * GLib >= 2.32 uses a similar system.
+ */
+static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
/**
@@ -2440,10 +2466,12 @@ _dbus_atomic_inc (DBusAtomic *atomic)
return __sync_add_and_fetch(&atomic->value, 1)-1;
#else
dbus_int32_t res;
- _DBUS_LOCK (atomic);
+
+ pthread_mutex_lock (&atomic_mutex);
res = atomic->value;
atomic->value += 1;
- _DBUS_UNLOCK (atomic);
+ pthread_mutex_unlock (&atomic_mutex);
+
return res;
#endif
}
@@ -2462,10 +2490,11 @@ _dbus_atomic_dec (DBusAtomic *atomic)
#else
dbus_int32_t res;
- _DBUS_LOCK (atomic);
+ pthread_mutex_lock (&atomic_mutex);
res = atomic->value;
atomic->value -= 1;
- _DBUS_UNLOCK (atomic);
+ pthread_mutex_unlock (&atomic_mutex);
+
return res;
#endif
}
@@ -2486,9 +2515,10 @@ _dbus_atomic_get (DBusAtomic *atomic)
#else
dbus_int32_t res;
- _DBUS_LOCK (atomic);
+ pthread_mutex_lock (&atomic_mutex);
res = atomic->value;
- _DBUS_UNLOCK (atomic);
+ pthread_mutex_unlock (&atomic_mutex);
+
return res;
#endif
}
@@ -2912,6 +2942,7 @@ _dbus_close (int fd,
* (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
*
* @param fd the file descriptor to duplicate
+ * @param error address of error location.
* @returns duplicated file descriptor
* */
int
@@ -3052,7 +3083,7 @@ _dbus_full_duplex_pipe (int *fd1,
retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
cloexec_done = retval >= 0;
- if (retval < 0 && errno == EINVAL)
+ if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
#endif
{
retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
@@ -3118,8 +3149,11 @@ _dbus_printf_string_upper_bound (const char *format,
char static_buf[1024];
int bufsize = sizeof (static_buf);
int len;
+ va_list args_copy;
- len = vsnprintf (static_buf, bufsize, format, args);
+ DBUS_VA_COPY (args_copy, args);
+ len = vsnprintf (static_buf, bufsize, format, args_copy);
+ va_end (args_copy);
/* If vsnprintf() returned non-negative, then either the string fits in
* static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
@@ -3135,8 +3169,12 @@ _dbus_printf_string_upper_bound (const char *format,
* or the real length could be coincidentally the same. Which is it?
* If vsnprintf returns the truncated length, we'll go to the slow
* path. */
- if (vsnprintf (static_buf, 1, format, args) == 1)
+ DBUS_VA_COPY (args_copy, args);
+
+ if (vsnprintf (static_buf, 1, format, args_copy) == 1)
len = -1;
+
+ va_end (args_copy);
}
/* If vsnprintf() returned negative, we have to do more work.
@@ -3152,7 +3190,10 @@ _dbus_printf_string_upper_bound (const char *format,
if (buf == NULL)
return -1;
- len = vsnprintf (buf, bufsize, format, args);
+ DBUS_VA_COPY (args_copy, args);
+ len = vsnprintf (buf, bufsize, format, args_copy);
+ va_end (args_copy);
+
dbus_free (buf);
/* If the reported length is exactly the buffer size, round up to the
@@ -3169,13 +3210,17 @@ _dbus_printf_string_upper_bound (const char *format,
* Gets the temporary files directory by inspecting the environment variables
* TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
*
- * @returns location of temp directory
+ * @returns location of temp directory, or #NULL if no memory for locking
*/
const char*
_dbus_get_tmpdir(void)
{
+ /* Protected by _DBUS_LOCK_sysdeps */
static const char* tmpdir = NULL;
+ if (!_DBUS_LOCK (sysdeps))
+ return NULL;
+
if (tmpdir == NULL)
{
/* TMPDIR is what glibc uses, then
@@ -3198,11 +3243,14 @@ _dbus_get_tmpdir(void)
tmpdir = "/tmp";
}
+ _DBUS_UNLOCK (sysdeps);
+
_dbus_assert(tmpdir != NULL);
return tmpdir;
}
+#if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
/**
* Execute a subprocess, returning up to 1024 bytes of output
* into @p result.
@@ -3299,15 +3347,12 @@ _read_subprocess_line_argv (const char *progpath,
/* set-up stdXXX */
close (result_pipe[READ_END]);
close (errors_pipe[READ_END]);
- close (0); /* close stdin */
- close (1); /* close stdout */
- close (2); /* close stderr */
- if (dup2 (fd, 0) == -1)
+ if (dup2 (fd, 0) == -1) /* setup stdin */
_exit (1);
- if (dup2 (result_pipe[WRITE_END], 1) == -1)
+ if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
_exit (1);
- if (dup2 (errors_pipe[WRITE_END], 2) == -1)
+ if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
_exit (1);
_dbus_close_all ();
@@ -3407,6 +3452,7 @@ _read_subprocess_line_argv (const char *progpath,
return retval;
}
+#endif
/**
* Returns the address of a new session bus.
@@ -3415,6 +3461,7 @@ _read_subprocess_line_argv (const char *progpath,
* address. If a failure happens, returns #FALSE and
* sets an error in @p error.
*
+ * @param scope scope of autolaunch (Windows only)
* @param address a DBusString where the address can be stored
* @param error a DBusError to store the error in case of failure
* @returns #TRUE on success, #FALSE if an error happened
@@ -3429,11 +3476,18 @@ _dbus_get_autolaunch_address (const char *scope,
* but that's done elsewhere, and if it worked, this function wouldn't
* be called.) */
const char *display;
- static char *argv[6];
+ char *argv[6];
int i;
DBusString uuid;
dbus_bool_t retval;
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to autolaunch when setuid");
+ return FALSE;
+ }
+
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
retval = FALSE;
@@ -3462,7 +3516,12 @@ _dbus_get_autolaunch_address (const char *scope,
}
i = 0;
- argv[i] = "dbus-launch";
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
+ if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
+ argv[i] = TEST_BUS_LAUNCH_BINARY;
+ else
+#endif
+ argv[i] = DBUS_BINDIR "/dbus-launch";
++i;
argv[i] = "--autolaunch";
++i;
@@ -3477,7 +3536,7 @@ _dbus_get_autolaunch_address (const char *scope,
_dbus_assert (i == _DBUS_N_ELEMENTS (argv));
- retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
+ retval = _read_subprocess_line_argv (argv[0],
TRUE,
argv, address, error);
@@ -3531,11 +3590,9 @@ _dbus_read_local_machine_uuid (DBusGUID *machine_id,
return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
}
-#define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
-#define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
-
/**
* quries launchd for a specific env var which holds the socket path.
+ * @param socket_path append the socket path to this DBusString
* @param launchd_env_var the env var to look up
* @param error a DBusError to store the error in case of failure
* @return the value of the env var
@@ -3551,6 +3608,13 @@ _dbus_lookup_launchd_socket (DBusString *socket_path,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to find launchd socket when setuid");
+ return FALSE;
+ }
+
i = 0;
argv[i] = "launchctl";
++i;
@@ -3591,6 +3655,13 @@ _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
dbus_bool_t valid_socket;
DBusString socket_path;
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to find launchd socket when setuid");
+ return FALSE;
+ }
+
if (!_dbus_string_init (&socket_path))
{
_DBUS_SET_OOM (error);
@@ -3670,167 +3741,6 @@ _dbus_lookup_session_address (dbus_bool_t *supported,
}
/**
- * Returns the standard directories for a session bus to look for service
- * activation files
- *
- * On UNIX this should be the standard xdg freedesktop.org data directories:
- *
- * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
- * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
- *
- * and
- *
- * DBUS_DATADIR
- *
- * @param dirs the directory list we are returning
- * @returns #FALSE on OOM
- */
-
-dbus_bool_t
-_dbus_get_standard_session_servicedirs (DBusList **dirs)
-{
- const char *xdg_data_home;
- const char *xdg_data_dirs;
- DBusString servicedir_path;
-
- if (!_dbus_string_init (&servicedir_path))
- return FALSE;
-
- xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
- xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
-
- if (xdg_data_home != NULL)
- {
- if (!_dbus_string_append (&servicedir_path, xdg_data_home))
- goto oom;
- }
- else
- {
- const DBusString *homedir;
- DBusString local_share;
-
- if (!_dbus_homedir_from_current_process (&homedir))
- goto oom;
-
- if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
- goto oom;
-
- _dbus_string_init_const (&local_share, "/.local/share");
- if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
- goto oom;
- }
-
- if (!_dbus_string_append (&servicedir_path, ":"))
- goto oom;
-
- if (xdg_data_dirs != NULL)
- {
- if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
- goto oom;
-
- if (!_dbus_string_append (&servicedir_path, ":"))
- goto oom;
- }
- else
- {
- if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
- goto oom;
- }
-
- /*
- * add configured datadir to defaults
- * this may be the same as an xdg dir
- * however the config parser should take
- * care of duplicates
- */
- if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
- goto oom;
-
- if (!_dbus_split_paths_and_append (&servicedir_path,
- DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
- dirs))
- goto oom;
-
- _dbus_string_free (&servicedir_path);
- return TRUE;
-
- oom:
- _dbus_string_free (&servicedir_path);
- return FALSE;
-}
-
-
-/**
- * Returns the standard directories for a system bus to look for service
- * activation files
- *
- * On UNIX this should be the standard xdg freedesktop.org data directories:
- *
- * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
- *
- * and
- *
- * DBUS_DATADIR
- *
- * On Windows there is no system bus and this function can return nothing.
- *
- * @param dirs the directory list we are returning
- * @returns #FALSE on OOM
- */
-
-dbus_bool_t
-_dbus_get_standard_system_servicedirs (DBusList **dirs)
-{
- /*
- * DBUS_DATADIR may be the same as one of the standard directories. However,
- * the config parser should take care of the duplicates.
- *
- * Also, append /lib as counterpart of /usr/share on the root
- * directory (the root directory does not know /share), in order to
- * facilitate early boot system bus activation where /usr might not
- * be available.
- */
- static const char standard_search_path[] =
- "/usr/local/share:"
- "/usr/share:"
- DBUS_DATADIR ":"
- "/lib";
- DBusString servicedir_path;
-
- _dbus_string_init_const (&servicedir_path, standard_search_path);
-
- return _dbus_split_paths_and_append (&servicedir_path,
- DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
- dirs);
-}
-
-/**
- * Append the absolute path of the system.conf file
- * (there is no system bus on Windows so this can just
- * return FALSE and print a warning or something)
- *
- * @param str the string to append to
- * @returns #FALSE if no memory
- */
-dbus_bool_t
-_dbus_append_system_config_file (DBusString *str)
-{
- return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
-}
-
-/**
- * Append the absolute path of the session.conf file.
- *
- * @param str the string to append to
- * @returns #FALSE if no memory
- */
-dbus_bool_t
-_dbus_append_session_config_file (DBusString *str)
-{
- return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
-}
-
-/**
* Called when the bus daemon is signaled to reload its configuration; any
* caches should be nuked. Of course any caches that need explicit reload
* are probably broken, but c'est la vie.
@@ -3876,7 +3786,7 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory,
if (!_dbus_homedir_from_uid (uid, &homedir))
goto failed;
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
{
const char *override;
@@ -3892,6 +3802,8 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory,
}
else
{
+ /* Not strictly thread-safe, but if we fail at thread-safety here,
+ * the worst that will happen is some extra warnings. */
static dbus_bool_t already_warned = FALSE;
if (!already_warned)
{
@@ -4007,20 +3919,6 @@ _dbus_socket_can_pass_unix_fd(int fd) {
#endif
}
-
-/*
- * replaces the term DBUS_PREFIX in configure_time_path by the
- * current dbus installation directory. On unix this function is a noop
- *
- * @param configure_time_path
- * @return real path
- */
-const char *
-_dbus_replace_install_prefix (const char *configure_time_path)
-{
- return configure_time_path;
-}
-
/**
* Closes all file descriptors except the first three (i.e. stdin,
* stdout, stderr).
@@ -4086,4 +3984,133 @@ _dbus_close_all (void)
close (i);
}
+/**
+ * **NOTE**: If you modify this function, please also consider making
+ * the corresponding change in GLib. See
+ * glib/gutils.c:g_check_setuid().
+ *
+ * Returns TRUE if the current process was executed as setuid (or an
+ * equivalent __libc_enable_secure is available). See:
+ * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
+ */
+dbus_bool_t
+_dbus_check_setuid (void)
+{
+ /* TODO: get __libc_enable_secure exported from glibc.
+ * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
+ */
+#if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
+ {
+ /* See glibc/include/unistd.h */
+ extern int __libc_enable_secure;
+ return __libc_enable_secure;
+ }
+#elif defined(HAVE_ISSETUGID)
+ /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
+ return issetugid ();
+#else
+ uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
+ gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
+
+ /* We call into this function from _dbus_threads_init_platform_specific()
+ * to make sure these are initialized before we start threading. */
+ static dbus_bool_t check_setuid_initialised;
+ static dbus_bool_t is_setuid;
+
+ if (_DBUS_UNLIKELY (!check_setuid_initialised))
+ {
+#ifdef HAVE_GETRESUID
+ if (getresuid (&ruid, &euid, &suid) != 0 ||
+ getresgid (&rgid, &egid, &sgid) != 0)
+#endif /* HAVE_GETRESUID */
+ {
+ suid = ruid = getuid ();
+ sgid = rgid = getgid ();
+ euid = geteuid ();
+ egid = getegid ();
+ }
+
+ check_setuid_initialised = TRUE;
+ is_setuid = (ruid != euid || ruid != suid ||
+ rgid != egid || rgid != sgid);
+
+ }
+ return is_setuid;
+#endif
+}
+
+/**
+ * Read the address from the socket and append it to the string
+ *
+ * @param fd the socket
+ * @param address
+ * @param error return location for error code
+ */
+dbus_bool_t
+_dbus_append_address_from_socket (int fd,
+ DBusString *address,
+ DBusError *error)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_storage storage;
+ struct sockaddr_un un;
+ struct sockaddr_in ipv4;
+ struct sockaddr_in6 ipv6;
+ } socket;
+ char hostip[INET6_ADDRSTRLEN];
+ int size = sizeof (socket);
+ DBusString path_str;
+
+ if (getsockname (fd, &socket.sa, &size))
+ goto err;
+
+ switch (socket.sa.sa_family)
+ {
+ case AF_UNIX:
+ if (socket.un.sun_path[0]=='\0')
+ {
+ _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
+ if (_dbus_string_append (address, "unix:abstract=") &&
+ _dbus_address_append_escaped (address, &path_str))
+ return TRUE;
+ }
+ else
+ {
+ _dbus_string_init_const (&path_str, socket.un.sun_path);
+ if (_dbus_string_append (address, "unix:path=") &&
+ _dbus_address_append_escaped (address, &path_str))
+ return TRUE;
+ }
+ break;
+ case AF_INET:
+ if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
+ if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
+ hostip, ntohs (socket.ipv4.sin_port)))
+ return TRUE;
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ _dbus_string_init_const (&path_str, hostip);
+ if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
+ if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
+ ntohs (socket.ipv6.sin6_port)) &&
+ _dbus_address_append_escaped (address, &path_str))
+ return TRUE;
+ break;
+#endif
+ default:
+ dbus_set_error (error,
+ _dbus_error_from_errno (EINVAL),
+ "Failed to read address from socket: Unknown socket type.");
+ return FALSE;
+ }
+ err:
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to open socket: %s",
+ _dbus_strerror (errno));
+ return FALSE;
+}
+
/* tests in dbus-sysdeps-util.c */
diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h
index 9b708967..a265b335 100644
--- a/dbus/dbus-sysdeps-unix.h
+++ b/dbus/dbus-sysdeps-unix.h
@@ -138,6 +138,10 @@ dbus_bool_t _dbus_parse_uid (const DBusString *uid_str,
void _dbus_close_all (void);
+dbus_bool_t _dbus_append_address_from_socket (int fd,
+ DBusString *address,
+ DBusError *error);
+
/** @} */
DBUS_END_DECLS
diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c
index ef86d738..0d8a66c7 100644
--- a/dbus/dbus-sysdeps-util-unix.c
+++ b/dbus/dbus-sysdeps-util-unix.c
@@ -49,12 +49,17 @@
#include <sys/socket.h>
#include <dirent.h>
#include <sys/un.h>
+
+#ifdef HAVE_SYSLOG_H
#include <syslog.h>
+#endif
#ifdef HAVE_SYS_SYSLIMITS_H
#include <sys/syslimits.h>
#endif
+#include "sd-daemon.h"
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -123,6 +128,7 @@ _dbus_become_daemon (const DBusString *pidfile,
dup2 (dev_null_fd, 2);
else
_dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
+ close (dev_null_fd);
}
if (!keep_umask)
@@ -375,13 +381,13 @@ _dbus_change_to_daemon_user (const char *user,
/**
* Attempt to ensure that the current process can open
- * at least @limit file descriptors.
+ * at least @p limit file descriptors.
*
- * If @limit is lower than the current, it will not be
+ * If @p limit is lower than the current, it will not be
* lowered. No error is returned if the request can
* not be satisfied.
*
- * @limit Number of file descriptors
+ * @param limit number of file descriptors
*/
void
_dbus_request_file_descriptor_limit (unsigned int limit)
@@ -422,12 +428,19 @@ _dbus_request_file_descriptor_limit (unsigned int limit)
}
void
-_dbus_init_system_log (void)
+_dbus_init_system_log (dbus_bool_t is_daemon)
{
-#ifdef HAVE_DECL_LOG_PERROR
- openlog ("dbus", LOG_PID | LOG_PERROR, LOG_DAEMON);
-#else
- openlog ("dbus", LOG_PID, LOG_DAEMON);
+#ifdef HAVE_SYSLOG_H
+ int logopts = LOG_PID;
+
+#if HAVE_DECL_LOG_PERROR
+#ifdef HAVE_SYSTEMD
+ if (!is_daemon || sd_booted () <= 0)
+#endif
+ logopts |= LOG_PERROR;
+#endif
+
+ openlog ("dbus", logopts, LOG_DAEMON);
#endif
}
@@ -436,8 +449,6 @@ _dbus_init_system_log (void)
*
* @param severity a severity value
* @param msg a printf-style format string
- * @param args arguments for the format string
- *
*/
void
_dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
@@ -464,6 +475,8 @@ _dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
void
_dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args)
{
+ va_list tmp;
+#ifdef HAVE_SYSLOG_H
int flags;
switch (severity)
{
@@ -480,11 +493,14 @@ _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args
return;
}
-#ifndef HAVE_DECL_LOG_PERROR
+ DBUS_VA_COPY (tmp, args);
+ vsyslog (flags, msg, tmp);
+ va_end (tmp);
+#endif
+
+#if !defined(HAVE_SYSLOG_H) || !HAVE_DECL_LOG_PERROR
{
/* vsyslog() won't write to stderr, so we'd better do it */
- va_list tmp;
-
DBUS_VA_COPY (tmp, args);
fprintf (stderr, "dbus[" DBUS_PID_FORMAT "]: ", _dbus_getpid ());
vfprintf (stderr, msg, tmp);
@@ -493,8 +509,6 @@ _dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args
}
#endif
- vsyslog (flags, msg, args);
-
if (severity == DBUS_SYSTEM_LOG_FATAL)
exit (1);
}
@@ -540,7 +554,7 @@ _dbus_user_at_console (const char *username,
DBusError *error)
{
- DBusString f;
+ DBusString u, f;
dbus_bool_t result;
result = FALSE;
@@ -556,8 +570,9 @@ _dbus_user_at_console (const char *username,
goto out;
}
+ _dbus_string_init_const (&u, username);
- if (!_dbus_string_append (&f, username))
+ if (!_dbus_concat_dir_and_file (&f, &u))
{
_DBUS_SET_OOM (error);
goto out;
@@ -1142,6 +1157,7 @@ _dbus_command_for_pid (unsigned long pid,
"Failed to read from \"%s\": %s",
_dbus_string_get_const_data (&path),
_dbus_strerror (errno));
+ _dbus_close (fd, NULL);
goto fail;
}
@@ -1163,3 +1179,180 @@ fail:
_dbus_string_free (&path);
return FALSE;
}
+
+/*
+ * replaces the term DBUS_PREFIX in configure_time_path by the
+ * current dbus installation directory. On unix this function is a noop
+ *
+ * @param configure_time_path
+ * @return real path
+ */
+const char *
+_dbus_replace_install_prefix (const char *configure_time_path)
+{
+ return configure_time_path;
+}
+
+#define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
+#define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
+
+/**
+ * Returns the standard directories for a session bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_session_servicedirs (DBusList **dirs)
+{
+ const char *xdg_data_home;
+ const char *xdg_data_dirs;
+ DBusString servicedir_path;
+
+ if (!_dbus_string_init (&servicedir_path))
+ return FALSE;
+
+ xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
+ xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
+
+ if (xdg_data_home != NULL)
+ {
+ if (!_dbus_string_append (&servicedir_path, xdg_data_home))
+ goto oom;
+ }
+ else
+ {
+ const DBusString *homedir;
+ DBusString local_share;
+
+ if (!_dbus_homedir_from_current_process (&homedir))
+ goto oom;
+
+ if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
+ goto oom;
+
+ _dbus_string_init_const (&local_share, "/.local/share");
+ if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
+ goto oom;
+ }
+
+ if (!_dbus_string_append (&servicedir_path, ":"))
+ goto oom;
+
+ if (xdg_data_dirs != NULL)
+ {
+ if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
+ goto oom;
+
+ if (!_dbus_string_append (&servicedir_path, ":"))
+ goto oom;
+ }
+ else
+ {
+ if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
+ goto oom;
+ }
+
+ /*
+ * add configured datadir to defaults
+ * this may be the same as an xdg dir
+ * however the config parser should take
+ * care of duplicates
+ */
+ if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
+ goto oom;
+
+ if (!_dbus_split_paths_and_append (&servicedir_path,
+ DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
+ dirs))
+ goto oom;
+
+ _dbus_string_free (&servicedir_path);
+ return TRUE;
+
+ oom:
+ _dbus_string_free (&servicedir_path);
+ return FALSE;
+}
+
+
+/**
+ * Returns the standard directories for a system bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * On Windows there is no system bus and this function can return nothing.
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_system_servicedirs (DBusList **dirs)
+{
+ /*
+ * DBUS_DATADIR may be the same as one of the standard directories. However,
+ * the config parser should take care of the duplicates.
+ *
+ * Also, append /lib as counterpart of /usr/share on the root
+ * directory (the root directory does not know /share), in order to
+ * facilitate early boot system bus activation where /usr might not
+ * be available.
+ */
+ static const char standard_search_path[] =
+ "/usr/local/share:"
+ "/usr/share:"
+ DBUS_DATADIR ":"
+ "/lib";
+ DBusString servicedir_path;
+
+ _dbus_string_init_const (&servicedir_path, standard_search_path);
+
+ return _dbus_split_paths_and_append (&servicedir_path,
+ DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
+ dirs);
+}
+
+/**
+ * Append the absolute path of the system.conf file
+ * (there is no system bus on Windows so this can just
+ * return FALSE and print a warning or something)
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_system_config_file (DBusString *str)
+{
+ return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
+}
+
+/**
+ * Append the absolute path of the session.conf file.
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_session_config_file (DBusString *str)
+{
+ return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
+}
diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c
index 111db9ea..4678b11e 100644
--- a/dbus/dbus-sysdeps-util-win.c
+++ b/dbus/dbus-sysdeps-util-win.c
@@ -54,7 +54,7 @@
* Does the chdir, fork, setsid, etc. to become a daemon process.
*
* @param pidfile #NULL, or pidfile to create
- * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none
+ * @param print_pid_pipe file descriptor to print daemon's pid to, or -1 for none
* @param error return location for errors
* @param keep_umask #TRUE to keep the original umask
* @returns #FALSE on failure
@@ -65,7 +65,9 @@ _dbus_become_daemon (const DBusString *pidfile,
DBusError *error,
dbus_bool_t keep_umask)
{
- return TRUE;
+ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Cannot daemonize on Windows");
+ return FALSE;
}
/**
@@ -262,7 +264,7 @@ _dbus_request_file_descriptor_limit (unsigned int limit)
}
void
-_dbus_init_system_log (void)
+_dbus_init_system_log (dbus_bool_t is_daemon)
{
/* OutputDebugStringA doesn't need any special initialization, do nothing */
}
@@ -272,8 +274,6 @@ _dbus_init_system_log (void)
*
* @param severity a severity value
* @param msg a printf-style format string
- * @param args arguments for the format string
- *
*/
void
_dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
@@ -1530,3 +1530,207 @@ _dbus_command_for_pid (unsigned long pid,
// FIXME
return FALSE;
}
+
+/*
+ * replaces the term DBUS_PREFIX in configure_time_path by the
+ * current dbus installation directory. On unix this function is a noop
+ *
+ * @param configure_time_path
+ * @return real path
+ */
+const char *
+_dbus_replace_install_prefix (const char *configure_time_path)
+{
+#ifndef DBUS_PREFIX
+ return configure_time_path;
+#else
+ static char retval[1000];
+ static char runtime_prefix[1000];
+ int len = 1000;
+ int i;
+
+ if (!configure_time_path)
+ return NULL;
+
+ if ((!_dbus_get_install_root(runtime_prefix, len) ||
+ strncmp (configure_time_path, DBUS_PREFIX "/",
+ strlen (DBUS_PREFIX) + 1))) {
+ strcat (retval, configure_time_path);
+ return retval;
+ }
+
+ strcpy (retval, runtime_prefix);
+ strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
+
+ /* Somehow, in some situations, backslashes get collapsed in the string.
+ * Since windows C library accepts both forward and backslashes as
+ * path separators, convert all backslashes to forward slashes.
+ */
+
+ for(i = 0; retval[i] != '\0'; i++) {
+ if(retval[i] == '\\')
+ retval[i] = '/';
+ }
+ return retval;
+#endif
+}
+
+/**
+ * return the relocated DATADIR
+ *
+ * @returns relocated DATADIR static string
+ */
+
+static const char *
+_dbus_windows_get_datadir (void)
+{
+ return _dbus_replace_install_prefix(DBUS_DATADIR);
+}
+
+#undef DBUS_DATADIR
+#define DBUS_DATADIR _dbus_windows_get_datadir ()
+
+
+#define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
+#define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
+
+/**
+ * Returns the standard directories for a session bus to look for service
+ * activation files
+ *
+ * On Windows this should be data directories:
+ *
+ * %CommonProgramFiles%/dbus
+ *
+ * and
+ *
+ * relocated DBUS_DATADIR
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_session_servicedirs (DBusList **dirs)
+{
+ const char *common_progs;
+ DBusString servicedir_path;
+
+ if (!_dbus_string_init (&servicedir_path))
+ return FALSE;
+
+#ifdef DBUS_WINCE
+ {
+ /* On Windows CE, we adjust datadir dynamically to installation location. */
+ const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
+
+ if (data_dir != NULL)
+ {
+ if (!_dbus_string_append (&servicedir_path, data_dir))
+ goto oom;
+
+ if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+ goto oom;
+ }
+ }
+#else
+/*
+ the code for accessing services requires absolute base pathes
+ in case DBUS_DATADIR is relative make it absolute
+*/
+#ifdef DBUS_WIN
+ {
+ DBusString p;
+
+ _dbus_string_init_const (&p, DBUS_DATADIR);
+
+ if (!_dbus_path_is_absolute (&p))
+ {
+ char install_root[1000];
+ if (_dbus_get_install_root (install_root, sizeof(install_root)))
+ if (!_dbus_string_append (&servicedir_path, install_root))
+ goto oom;
+ }
+ }
+#endif
+ if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
+ goto oom;
+
+ if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+ goto oom;
+#endif
+
+ common_progs = _dbus_getenv ("CommonProgramFiles");
+
+ if (common_progs != NULL)
+ {
+ if (!_dbus_string_append (&servicedir_path, common_progs))
+ goto oom;
+
+ if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+ goto oom;
+ }
+
+ if (!_dbus_split_paths_and_append (&servicedir_path,
+ DBUS_STANDARD_SESSION_SERVICEDIR,
+ dirs))
+ goto oom;
+
+ _dbus_string_free (&servicedir_path);
+ return TRUE;
+
+ oom:
+ _dbus_string_free (&servicedir_path);
+ return FALSE;
+}
+
+/**
+ * Returns the standard directories for a system bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * On Windows there is no system bus and this function can return nothing.
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_system_servicedirs (DBusList **dirs)
+{
+ *dirs = NULL;
+ return TRUE;
+}
+
+/**
+ * Append the absolute path of the system.conf file
+ * (there is no system bus on Windows so this can just
+ * return FALSE and print a warning or something)
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_system_config_file (DBusString *str)
+{
+ return _dbus_get_config_file_name(str, "system.conf");
+}
+
+/**
+ * Append the absolute path of the session.conf file.
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_session_config_file (DBusString *str)
+{
+ return _dbus_get_config_file_name(str, "session.conf");
+}
diff --git a/dbus/dbus-sysdeps-util.c b/dbus/dbus-sysdeps-util.c
index 4b3d16f2..6b361ef0 100644
--- a/dbus/dbus-sysdeps-util.c
+++ b/dbus/dbus-sysdeps-util.c
@@ -80,7 +80,7 @@ _dbus_get_environment (void)
return environment;
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static void
check_dirname (const char *filename,
const char *dirname)
@@ -196,4 +196,4 @@ _dbus_sysdeps_test (void)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c
index 397520af..1167e967 100644
--- a/dbus/dbus-sysdeps-win.c
+++ b/dbus/dbus-sysdeps-win.c
@@ -6,7 +6,7 @@
* Copyright (C) 2005 Novell, Inc.
* Copyright (C) 2006 Peter Kümmel <syntheticpp@gmx.net>
* Copyright (C) 2006 Christian Ehrlicher <ch.ehrlicher@gmx.de>
- * Copyright (C) 2006-2010 Ralf Habacker <ralf.habacker@freenet.de>
+ * Copyright (C) 2006-2013 Ralf Habacker <ralf.habacker@freenet.de>
*
* Licensed under the Academic Free License version 2.1
*
@@ -54,12 +54,14 @@
#include <windows.h>
#include <ws2tcpip.h>
#include <wincrypt.h>
+#include <iphlpapi.h>
-/* Declarations missing in mingw's headers */
+/* Declarations missing in mingw's and windows sdk 7.0 headers */
extern BOOL WINAPI ConvertStringSidToSidA (LPCSTR StringSid, PSID *Sid);
extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#if HAVE_ERRNO_H
@@ -76,20 +78,15 @@ extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid);
#include <ws2tcpip.h>
#endif
-#ifdef HAVE_WSPIAPI_H
-// needed for w2k compatibility (getaddrinfo/freeaddrinfo/getnameinfo)
-#ifdef __GNUC__
-#define _inline
-#include "wspiapi.h"
-#else
-#include <wspiapi.h>
-#endif
-#endif // HAVE_WSPIAPI_H
-
#ifndef O_BINARY
#define O_BINARY 0
#endif
+#ifndef PROCESS_QUERY_LIMITED_INFORMATION
+/* MinGW32 < 4 does not define this value in its headers */
+#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
+#endif
+
typedef int socklen_t;
@@ -103,6 +100,203 @@ _dbus_win_set_errno (int err)
#endif
}
+static BOOL is_winxp_sp3_or_lower();
+
+/*
+ * _MIB_TCPROW_EX and friends are not available in system headers
+ * and are mapped to attribute identical ...OWNER_PID typedefs.
+ */
+typedef MIB_TCPROW_OWNER_PID _MIB_TCPROW_EX;
+typedef MIB_TCPTABLE_OWNER_PID MIB_TCPTABLE_EX;
+typedef PMIB_TCPTABLE_OWNER_PID PMIB_TCPTABLE_EX;
+typedef DWORD (WINAPI *ProcAllocateAndGetTcpExtTableFromStack)(PMIB_TCPTABLE_EX*,BOOL,HANDLE,DWORD,DWORD);
+static ProcAllocateAndGetTcpExtTableFromStack lpfnAllocateAndGetTcpExTableFromStack = NULL;
+
+/**
+ * AllocateAndGetTcpExTableFromStack() is undocumented and not exported,
+ * but is the only way to do this in older XP versions.
+ * @return true if the procedures could be loaded
+ */
+static BOOL
+load_ex_ip_helper_procedures(void)
+{
+ HMODULE hModule = LoadLibrary ("iphlpapi.dll");
+ if (hModule == NULL)
+ {
+ _dbus_verbose ("could not load iphlpapi.dll\n");
+ return FALSE;
+ }
+
+ lpfnAllocateAndGetTcpExTableFromStack = (ProcAllocateAndGetTcpExtTableFromStack)GetProcAddress (hModule, "AllocateAndGetTcpExTableFromStack");
+ if (lpfnAllocateAndGetTcpExTableFromStack == NULL)
+ {
+ _dbus_verbose ("could not find function AllocateAndGetTcpExTableFromStack in iphlpapi.dll\n");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * get pid from localhost tcp connection using peer_port
+ * This function is available on WinXP >= SP3
+ * @param peer_port peers tcp port
+ * @return process id or 0 if connection has not been found
+ */
+static dbus_pid_t
+get_pid_from_extended_tcp_table(int peer_port)
+{
+ dbus_pid_t result;
+ DWORD errorCode, size, i;
+ MIB_TCPTABLE_OWNER_PID *tcp_table;
+
+ if ((errorCode =
+ GetExtendedTcpTable (NULL, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) == ERROR_INSUFFICIENT_BUFFER)
+ {
+ tcp_table = (MIB_TCPTABLE_OWNER_PID *) dbus_malloc (size);
+ if (tcp_table == NULL)
+ {
+ _dbus_verbose ("Error allocating memory\n");
+ return 0;
+ }
+ }
+ else
+ {
+ _dbus_win_warn_win_error ("unexpected error returned from GetExtendedTcpTable", errorCode);
+ return 0;
+ }
+
+ if ((errorCode = GetExtendedTcpTable (tcp_table, &size, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0)) != NO_ERROR)
+ {
+ _dbus_verbose ("Error fetching tcp table %d\n", (int)errorCode);
+ dbus_free (tcp_table);
+ return 0;
+ }
+
+ result = 0;
+ for (i = 0; i < tcp_table->dwNumEntries; i++)
+ {
+ MIB_TCPROW_OWNER_PID *p = &tcp_table->table[i];
+ int local_address = ntohl (p->dwLocalAddr);
+ int local_port = ntohs (p->dwLocalPort);
+ if (p->dwState == MIB_TCP_STATE_ESTAB
+ && local_address == INADDR_LOOPBACK && local_port == peer_port)
+ result = p->dwOwningPid;
+ }
+
+ dbus_free (tcp_table);
+ _dbus_verbose ("got pid %lu\n", result);
+ return result;
+}
+
+/**
+ * get pid from localhost tcp connection using peer_port
+ * This function is available on all WinXP versions, but
+ * not in wine (at least version <= 1.6.0)
+ * @param peer_port peers tcp port
+ * @return process id or 0 if connection has not been found
+ */
+static dbus_pid_t
+get_pid_from_tcp_ex_table(int peer_port)
+{
+ dbus_pid_t result;
+ DWORD errorCode, i;
+ PMIB_TCPTABLE_EX tcp_table = NULL;
+
+ if (!load_ex_ip_helper_procedures ())
+ {
+ _dbus_verbose
+ ("Error not been able to load iphelper procedures\n");
+ return 0;
+ }
+
+ errorCode = lpfnAllocateAndGetTcpExTableFromStack (&tcp_table, TRUE, GetProcessHeap(), 0, 2);
+
+ if (errorCode != NO_ERROR)
+ {
+ _dbus_verbose
+ ("Error not been able to call AllocateAndGetTcpExTableFromStack()\n");
+ return 0;
+ }
+
+ result = 0;
+ for (i = 0; i < tcp_table->dwNumEntries; i++)
+ {
+ _MIB_TCPROW_EX *p = &tcp_table->table[i];
+ int local_port = ntohs (p->dwLocalPort);
+ int local_address = ntohl (p->dwLocalAddr);
+ if (local_address == INADDR_LOOPBACK && local_port == peer_port)
+ {
+ result = p->dwOwningPid;
+ break;
+ }
+ }
+
+ HeapFree (GetProcessHeap(), 0, tcp_table);
+ _dbus_verbose ("got pid %lu\n", result);
+ return result;
+}
+
+/**
+ * @brief return peer process id from tcp handle for localhost connections
+ * @param handle tcp socket descriptor
+ * @return process id or 0 in case the process id could not be fetched
+ */
+static dbus_pid_t
+_dbus_get_peer_pid_from_tcp_handle (int handle)
+{
+ struct sockaddr_storage addr;
+ socklen_t len = sizeof (addr);
+ int peer_port;
+
+ dbus_pid_t result;
+ dbus_bool_t is_localhost = FALSE;
+
+ getpeername (handle, (struct sockaddr *) &addr, &len);
+
+ if (addr.ss_family == AF_INET)
+ {
+ struct sockaddr_in *s = (struct sockaddr_in *) &addr;
+ peer_port = ntohs (s->sin_port);
+ is_localhost = (ntohl (s->sin_addr.s_addr) == INADDR_LOOPBACK);
+ }
+ else if (addr.ss_family == AF_INET6)
+ {
+ _dbus_verbose ("FIXME [61922]: IPV6 support not working on windows\n");
+ return 0;
+ /*
+ struct sockaddr_in6 *s = (struct sockaddr_in6 * )&addr;
+ peer_port = ntohs (s->sin6_port);
+ is_localhost = (memcmp(s->sin6_addr.s6_addr, in6addr_loopback.s6_addr, 16) == 0);
+ _dbus_verbose ("IPV6 %08x %08x\n", s->sin6_addr.s6_addr, in6addr_loopback.s6_addr);
+ */
+ }
+ else
+ {
+ _dbus_verbose ("no idea what address family %d is\n", addr.ss_family);
+ return 0;
+ }
+
+ if (!is_localhost)
+ {
+ _dbus_verbose ("could not fetch process id from remote process\n");
+ return 0;
+ }
+
+ if (peer_port == 0)
+ {
+ _dbus_verbose
+ ("Error not been able to fetch tcp peer port from connection\n");
+ return 0;
+ }
+
+ _dbus_verbose ("trying to get peers pid");
+
+ result = get_pid_from_extended_tcp_table (peer_port);
+ if (result > 0)
+ return result;
+ result = get_pid_from_tcp_ex_table (peer_port);
+ return result;
+}
/* Convert GetLastError() to a dbus error. */
const char*
@@ -324,7 +518,7 @@ _dbus_close_socket (int fd,
* on exec. Should be called for all file
* descriptors in D-Bus code.
*
- * @param fd the file descriptor
+ * @param handle the Windows HANDLE
*/
void
_dbus_fd_set_close_on_exec (intptr_t handle)
@@ -340,7 +534,7 @@ _dbus_fd_set_close_on_exec (intptr_t handle)
/**
* Sets a file descriptor to be nonblocking.
*
- * @param fd the file descriptor.
+ * @param handle the file descriptor.
* @param error address of error location.
* @returns #TRUE on success.
*/
@@ -474,21 +668,26 @@ _dbus_connect_named_pipe (const char *path,
#endif
-
-
-void
+/**
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
_dbus_win_startup_winsock (void)
{
/* Straight from MSDN, deuglified */
+ /* Protected by _DBUS_LOCK_sysdeps */
static dbus_bool_t beenhere = FALSE;
WORD wVersionRequested;
WSADATA wsaData;
int err;
+ if (!_DBUS_LOCK (sysdeps))
+ return FALSE;
+
if (beenhere)
- return;
+ goto out;
wVersionRequested = MAKEWORD (2, 0);
@@ -512,6 +711,10 @@ _dbus_win_startup_winsock (void)
}
beenhere = TRUE;
+
+out:
+ _DBUS_UNLOCK (sysdeps);
+ return TRUE;
}
@@ -538,9 +741,12 @@ int _dbus_printf_string_upper_bound (const char *format,
char buf[1024];
int bufsize;
int len;
+ va_list args_copy;
bufsize = sizeof (buf);
- len = _vsnprintf (buf, bufsize - 1, format, args);
+ DBUS_VA_COPY (args_copy, args);
+ len = _vsnprintf (buf, bufsize - 1, format, args_copy);
+ va_end (args_copy);
while (len == -1) /* try again */
{
@@ -553,7 +759,9 @@ int _dbus_printf_string_upper_bound (const char *format,
if (p == NULL)
return -1;
- len = _vsnprintf (p, bufsize - 1, format, args);
+ DBUS_VA_COPY (args_copy, args);
+ len = _vsnprintf (p, bufsize - 1, format, args_copy);
+ va_end (args_copy);
free (p);
}
@@ -738,22 +946,56 @@ _dbus_pid_for_log (void)
return _dbus_getpid ();
}
-
#ifndef DBUS_WINCE
+
+static BOOL is_winxp_sp3_or_lower()
+{
+ OSVERSIONINFOEX osvi;
+ DWORDLONG dwlConditionMask = 0;
+ int op=VER_LESS_EQUAL;
+
+ // Initialize the OSVERSIONINFOEX structure.
+
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ osvi.dwMajorVersion = 5;
+ osvi.dwMinorVersion = 1;
+ osvi.wServicePackMajor = 3;
+ osvi.wServicePackMinor = 0;
+
+ // Initialize the condition mask.
+
+ VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op );
+ VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op );
+ VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op );
+ VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op );
+
+ // Perform the test.
+
+ return VerifyVersionInfo(
+ &osvi,
+ VER_MAJORVERSION | VER_MINORVERSION |
+ VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
+ dwlConditionMask);
+}
+
/** Gets our SID
- * @param points to sid buffer, need to be freed with LocalFree()
+ * @param sid points to sid buffer, need to be freed with LocalFree()
+ * @param process_id the process id for which the sid should be returned
* @returns process sid
*/
static dbus_bool_t
-_dbus_getsid(char **sid)
+_dbus_getsid(char **sid, dbus_pid_t process_id)
{
HANDLE process_token = INVALID_HANDLE_VALUE;
TOKEN_USER *token_user = NULL;
DWORD n;
PSID psid;
int retval = FALSE;
-
- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &process_token))
+
+ HANDLE process_handle = OpenProcess(is_winxp_sp3_or_lower() ? PROCESS_QUERY_INFORMATION : PROCESS_QUERY_LIMITED_INFORMATION, FALSE, process_id);
+
+ if (!OpenProcessToken (process_handle, TOKEN_QUERY, &process_token))
{
_dbus_win_warn_win_error ("OpenProcessToken failed", GetLastError ());
goto failed;
@@ -781,10 +1023,11 @@ _dbus_getsid(char **sid)
retval = TRUE;
failed:
+ CloseHandle (process_handle);
if (process_token != INVALID_HANDLE_VALUE)
CloseHandle (process_token);
- _dbus_verbose("_dbus_getsid() returns %d\n",retval);
+ _dbus_verbose("_dbus_getsid() got '%s' and returns %d\n", *sid, retval);
return retval;
}
#endif
@@ -816,7 +1059,11 @@ _dbus_full_duplex_pipe (int *fd1,
int len;
u_long arg;
- _dbus_win_startup_winsock ();
+ if (!_dbus_win_startup_winsock ())
+ {
+ _DBUS_SET_OOM (error);
+ return FALSE;
+ }
temp = socket (AF_INET, SOCK_STREAM, 0);
if (temp == INVALID_SOCKET)
@@ -1260,7 +1507,11 @@ _dbus_connect_tcp_socket_with_nonce (const char *host,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- _dbus_win_startup_winsock ();
+ if (!_dbus_win_startup_winsock ())
+ {
+ _DBUS_SET_OOM (error);
+ return -1;
+ }
_DBUS_ZERO (hints);
@@ -1405,7 +1656,11 @@ _dbus_listen_tcp_socket (const char *host,
*fds_p = NULL;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
- _dbus_win_startup_winsock ();
+ if (!_dbus_win_startup_winsock ())
+ {
+ _DBUS_SET_OOM (error);
+ return -1;
+ }
_DBUS_ZERO (hints);
@@ -1665,13 +1920,13 @@ again:
* a byte was read, not whether we got valid credentials. On some
* systems, such as Linux, reading/writing the byte isn't actually
* required, but we do it anyway just to avoid multiple codepaths.
- *
+ *
* Fails if no byte is available, so you must select() first.
*
* The point of the byte is that on some systems we have to
* use sendmsg()/recvmsg() to transmit credentials.
*
- * @param client_fd the client file descriptor
+ * @param handle the client file descriptor
* @param credentials struct to fill with credentials of client
* @param error location to store error code
* @returns #TRUE on success
@@ -1683,22 +1938,41 @@ _dbus_read_credentials_socket (int handle,
{
int bytes_read = 0;
DBusString buf;
-
+
+ char *sid = NULL;
+ dbus_pid_t pid;
+ int retval = FALSE;
+
// could fail due too OOM
- if (_dbus_string_init(&buf))
+ if (_dbus_string_init (&buf))
{
- bytes_read = _dbus_read_socket(handle, &buf, 1 );
+ bytes_read = _dbus_read_socket (handle, &buf, 1 );
if (bytes_read > 0)
- _dbus_verbose("got one zero byte from server");
+ _dbus_verbose ("got one zero byte from server\n");
- _dbus_string_free(&buf);
+ _dbus_string_free (&buf);
}
- _dbus_credentials_add_from_current_process (credentials);
- _dbus_verbose("FIXME: get faked credentials from current process");
+ pid = _dbus_get_peer_pid_from_tcp_handle (handle);
+ if (pid == 0)
+ return TRUE;
- return TRUE;
+ _dbus_credentials_add_pid (credentials, pid);
+
+ if (_dbus_getsid (&sid, pid))
+ {
+ if (!_dbus_credentials_add_windows_sid (credentials, sid))
+ goto out;
+ }
+
+ retval = TRUE;
+
+out:
+ if (sid)
+ LocalFree (sid);
+
+ return retval;
}
/**
@@ -1792,10 +2066,10 @@ _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
dbus_bool_t retval = FALSE;
char *sid = NULL;
- if (!_dbus_getsid(&sid))
+ if (!_dbus_getsid(&sid, _dbus_getpid()))
goto failed;
- if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
+ if (!_dbus_credentials_add_pid (credentials, _dbus_getpid()))
goto failed;
if (!_dbus_credentials_add_windows_sid (credentials,sid))
@@ -1830,7 +2104,7 @@ _dbus_append_user_from_current_process (DBusString *str)
dbus_bool_t retval = FALSE;
char *sid = NULL;
- if (!_dbus_getsid(&sid))
+ if (!_dbus_getsid(&sid, _dbus_getpid()))
return FALSE;
retval = _dbus_string_append (str,sid);
@@ -1999,14 +2273,18 @@ _dbus_generate_random_bytes (DBusString *str,
* Gets the temporary files directory by inspecting the environment variables
* TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
*
- * @returns location of temp directory
+ * @returns location of temp directory, or #NULL if no memory for locking
*/
const char*
_dbus_get_tmpdir(void)
{
+ /* Protected by _DBUS_LOCK_sysdeps */
static const char* tmpdir = NULL;
static char buf[1000];
+ if (!_DBUS_LOCK (sysdeps))
+ return NULL;
+
if (tmpdir == NULL)
{
char *last_slash;
@@ -2028,6 +2306,8 @@ _dbus_get_tmpdir(void)
tmpdir = buf;
}
+ _DBUS_UNLOCK (sysdeps);
+
_dbus_assert(tmpdir != NULL);
return tmpdir;
@@ -2063,51 +2343,7 @@ _dbus_delete_file (const DBusString *filename,
return TRUE;
}
-/*
- * replaces the term DBUS_PREFIX in configure_time_path by the
- * current dbus installation directory. On unix this function is a noop
- *
- * @param configure_time_path
- * @return real path
- */
-const char *
-_dbus_replace_install_prefix (const char *configure_time_path)
-{
-#ifndef DBUS_PREFIX
- return configure_time_path;
-#else
- static char retval[1000];
- static char runtime_prefix[1000];
- int len = 1000;
- int i;
-
- if (!configure_time_path)
- return NULL;
-
- if ((!_dbus_get_install_root(runtime_prefix, len) ||
- strncmp (configure_time_path, DBUS_PREFIX "/",
- strlen (DBUS_PREFIX) + 1))) {
- strcat (retval, configure_time_path);
- return retval;
- }
-
- strcpy (retval, runtime_prefix);
- strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
-
- /* Somehow, in some situations, backslashes get collapsed in the string.
- * Since windows C library accepts both forward and backslashes as
- * path separators, convert all backslashes to forward slashes.
- */
-
- for(i = 0; retval[i] != '\0'; i++) {
- if(retval[i] == '\\')
- retval[i] = '/';
- }
- return retval;
-#endif
-}
-
-#if !defined (DBUS_DISABLE_ASSERTS) || defined(DBUS_BUILD_TESTS)
+#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS)
#if defined(_MSC_VER) || defined(DBUS_WINCE)
# ifdef BACKTRACES
@@ -2946,142 +3182,6 @@ _dbus_make_file_world_readable(const DBusString *filename,
}
/**
- * return the relocated DATADIR
- *
- * @returns relocated DATADIR static string
- */
-
-static const char *
-_dbus_windows_get_datadir (void)
-{
- return _dbus_replace_install_prefix(DBUS_DATADIR);
-}
-
-#undef DBUS_DATADIR
-#define DBUS_DATADIR _dbus_windows_get_datadir ()
-
-
-#define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
-#define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
-
-/**
- * Returns the standard directories for a session bus to look for service
- * activation files
- *
- * On Windows this should be data directories:
- *
- * %CommonProgramFiles%/dbus
- *
- * and
- *
- * relocated DBUS_DATADIR
- *
- * @param dirs the directory list we are returning
- * @returns #FALSE on OOM
- */
-
-dbus_bool_t
-_dbus_get_standard_session_servicedirs (DBusList **dirs)
-{
- const char *common_progs;
- DBusString servicedir_path;
-
- if (!_dbus_string_init (&servicedir_path))
- return FALSE;
-
-#ifdef DBUS_WINCE
- {
- /* On Windows CE, we adjust datadir dynamically to installation location. */
- const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
-
- if (data_dir != NULL)
- {
- if (!_dbus_string_append (&servicedir_path, data_dir))
- goto oom;
-
- if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
- goto oom;
- }
- }
-#else
-/*
- the code for accessing services requires absolute base pathes
- in case DBUS_DATADIR is relative make it absolute
-*/
-#ifdef DBUS_WIN
- {
- DBusString p;
-
- _dbus_string_init_const (&p, DBUS_DATADIR);
-
- if (!_dbus_path_is_absolute (&p))
- {
- char install_root[1000];
- if (_dbus_get_install_root (install_root, sizeof(install_root)))
- if (!_dbus_string_append (&servicedir_path, install_root))
- goto oom;
- }
- }
-#endif
- if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
- goto oom;
-
- if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
- goto oom;
-#endif
-
- common_progs = _dbus_getenv ("CommonProgramFiles");
-
- if (common_progs != NULL)
- {
- if (!_dbus_string_append (&servicedir_path, common_progs))
- goto oom;
-
- if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
- goto oom;
- }
-
- if (!_dbus_split_paths_and_append (&servicedir_path,
- DBUS_STANDARD_SESSION_SERVICEDIR,
- dirs))
- goto oom;
-
- _dbus_string_free (&servicedir_path);
- return TRUE;
-
- oom:
- _dbus_string_free (&servicedir_path);
- return FALSE;
-}
-
-/**
- * Returns the standard directories for a system bus to look for service
- * activation files
- *
- * On UNIX this should be the standard xdg freedesktop.org data directories:
- *
- * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
- *
- * and
- *
- * DBUS_DATADIR
- *
- * On Windows there is no system bus and this function can return nothing.
- *
- * @param dirs the directory list we are returning
- * @returns #FALSE on OOM
- */
-
-dbus_bool_t
-_dbus_get_standard_system_servicedirs (DBusList **dirs)
-{
- *dirs = NULL;
- return TRUE;
-}
-
-_DBUS_DEFINE_GLOBAL_LOCK (atomic);
-
-/**
* Atomically increments an integer
*
* @param atomic pointer to the integer to increment
@@ -3121,8 +3221,18 @@ _dbus_atomic_dec (DBusAtomic *atomic)
dbus_int32_t
_dbus_atomic_get (DBusAtomic *atomic)
{
- /* this is what GLib does, hopefully it's right... */
- MemoryBarrier ();
+ /* In this situation, GLib issues a MemoryBarrier() and then returns
+ * atomic->value. However, mingw from mingw.org (not to be confused with
+ * mingw-w64 from mingw-w64.sf.net) does not have MemoryBarrier in its
+ * headers, so we have to get a memory barrier some other way.
+ *
+ * InterlockedIncrement is older, and is documented on MSDN to be a full
+ * memory barrier, so let's use that.
+ */
+ long dummy = 0;
+
+ InterlockedExchange (&dummy, 1);
+
return atomic->value;
}
@@ -3153,7 +3263,7 @@ _dbus_get_is_errno_eagain_or_ewouldblock (void)
/**
* return the absolute path of the dbus installation
*
- * @param s buffer for installation path
+ * @param prefix buffer for installation path
* @param len length of buffer
* @returns #FALSE on failure
*/
@@ -3258,32 +3368,6 @@ _dbus_get_config_file_name(DBusString *config_file, char *s)
return TRUE;
}
-/**
- * Append the absolute path of the system.conf file
- * (there is no system bus on Windows so this can just
- * return FALSE and print a warning or something)
- *
- * @param str the string to append to
- * @returns #FALSE if no memory
- */
-dbus_bool_t
-_dbus_append_system_config_file (DBusString *str)
-{
- return _dbus_get_config_file_name(str, "system.conf");
-}
-
-/**
- * Append the absolute path of the session.conf file.
- *
- * @param str the string to append to
- * @returns #FALSE if no memory
- */
-dbus_bool_t
-_dbus_append_session_config_file (DBusString *str)
-{
- return _dbus_get_config_file_name(str, "session.conf");
-}
-
/* See comment in dbus-sysdeps-unix.c */
dbus_bool_t
_dbus_lookup_session_address (dbus_bool_t *supported,
@@ -3335,7 +3419,7 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory,
_dbus_string_append(&homedir,homepath);
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
{
const char *override;
@@ -3351,6 +3435,8 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory,
}
else
{
+ /* Not strictly thread-safe, but if we fail at thread-safety here,
+ * the worst that will happen is some extra warnings. */
static dbus_bool_t already_warned = FALSE;
if (!already_warned)
{
@@ -3575,7 +3661,7 @@ _dbus_win_set_error_from_win_error (DBusError *error,
void
_dbus_win_warn_win_error (const char *message,
- int code)
+ unsigned long code)
{
DBusError error;
@@ -3632,6 +3718,12 @@ _dbus_path_is_absolute (const DBusString *filename)
return FALSE;
}
+dbus_bool_t
+_dbus_check_setuid (void)
+{
+ return FALSE;
+}
+
/** @} end of sysdeps-win */
/* tests in dbus-sysdeps-util.c */
diff --git a/dbus/dbus-sysdeps-win.h b/dbus/dbus-sysdeps-win.h
index 74624b75..02e7a83f 100644
--- a/dbus/dbus-sysdeps-win.h
+++ b/dbus/dbus-sysdeps-win.h
@@ -27,7 +27,7 @@
#define DBUS_SYSDEPS_WIN_H
extern void *_dbus_win_get_dll_hmodule (void);
-#define _WINSOCKAPI_
+#define WIN32_LEAN_AND_MEAN
#include "dbus-hash.h"
#include "dbus-string.h"
@@ -42,9 +42,9 @@ extern void *_dbus_win_get_dll_hmodule (void);
void _dbus_win_set_errno (int err);
const char* _dbus_win_error_from_last_error (void);
-void _dbus_win_startup_winsock (void);
+dbus_bool_t _dbus_win_startup_winsock (void);
void _dbus_win_warn_win_error (const char *message,
- int code);
+ unsigned long code);
char * _dbus_win_error_string (int error_number);
void _dbus_win_free_error_string (char *string);
@@ -85,6 +85,9 @@ dbus_bool_t _dbus_get_config_file_name(DBusString *config_file,
dbus_bool_t _dbus_get_install_root(char *prefix, int len);
+void _dbus_threads_windows_init_global (void);
+void _dbus_threads_windows_ensure_ctor_linked (void);
+
#endif
/** @} end of sysdeps-win.h */
diff --git a/dbus/dbus-sysdeps-wince-glue.c b/dbus/dbus-sysdeps-wince-glue.c
index 74b1371f..e276f046 100644
--- a/dbus/dbus-sysdeps-wince-glue.c
+++ b/dbus/dbus-sysdeps-wince-glue.c
@@ -491,7 +491,7 @@ SearchPathA (LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension,
/** Gets our SID
- * @param points to sid buffer, need to be freed with LocalFree()
+ * @param sid points to sid buffer, need to be freed with LocalFree()
* @returns process sid
*/
dbus_bool_t
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index 861bfec9..de3a18cb 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -29,6 +29,7 @@
#include "dbus-protocol.h"
#include "dbus-string.h"
#include "dbus-list.h"
+#include "dbus-misc.h"
/* NOTE: If you include any unix/windows-specific headers here, you are probably doing something
* wrong and should be putting some code in dbus-sysdeps-unix.c or dbus-sysdeps-win.c.
@@ -46,10 +47,6 @@
#include <errno.h>
#endif
-_DBUS_DEFINE_GLOBAL_LOCK (win_fds);
-_DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
-_DBUS_DEFINE_GLOBAL_LOCK (system_users);
-
#ifdef DBUS_WIN
#include <stdlib.h>
#elif (defined __APPLE__)
@@ -96,6 +93,8 @@ _dbus_abort (void)
}
/**
+ * @ingroup DBusMisc
+ *
* Wrapper for setenv(). If the value is #NULL, unsets
* the environment variable.
*
@@ -104,13 +103,16 @@ _dbus_abort (void)
* we can not rely on internal implementation details of
* the underlying libc library.
*
+ * This function is not thread-safe, because altering the environment
+ * in Unix is not thread-safe in general.
+ *
* @param varname name of environment variable
- * @param value value of environment variable
- * @returns #TRUE on success.
+ * @param value value of environment variable, or #NULL to unset
+ * @returns #TRUE on success, #FALSE if not enough memory.
*/
dbus_bool_t
-_dbus_setenv (const char *varname,
- const char *value)
+dbus_setenv (const char *varname,
+ const char *value)
{
_dbus_assert (varname != NULL);
@@ -182,6 +184,11 @@ _dbus_setenv (const char *varname,
const char*
_dbus_getenv (const char *varname)
{
+ /* Don't respect any environment variables if the current process is
+ * setuid. This is the equivalent of glibc's __secure_getenv().
+ */
+ if (_dbus_check_setuid ())
+ return NULL;
return getenv (varname);
}
diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
index c03e2f54..e586946f 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -87,9 +87,8 @@ typedef struct DBusPipe DBusPipe;
void _dbus_abort (void) _DBUS_GNUC_NORETURN;
+dbus_bool_t _dbus_check_setuid (void);
const char* _dbus_getenv (const char *varname);
-dbus_bool_t _dbus_setenv (const char *varname,
- const char *value);
dbus_bool_t _dbus_clearenv (void);
char ** _dbus_get_environment (void);
@@ -277,6 +276,19 @@ dbus_int32_t _dbus_atomic_get (DBusAtomic *atomic);
#define _DBUS_POLLHUP 0x0080
/** Invalid request: fd not open */
#define _DBUS_POLLNVAL 0x1000
+#elif defined(__QNX__)
+/** Writing now will not block */
+#define _DBUS_POLLOUT 0x0002
+/** There is data to read */
+#define _DBUS_POLLIN 0x0005
+/** There is urgent data to read */
+#define _DBUS_POLLPRI 0x0008
+/** Error condition */
+#define _DBUS_POLLERR 0x0020
+/** Hung up */
+#define _DBUS_POLLHUP 0x0040
+/** Invalid request: fd not open */
+#define _DBUS_POLLNVAL 0x1000
#else
/** There is data to read */
#define _DBUS_POLLIN 0x0001
@@ -308,12 +320,12 @@ int _dbus_poll (DBusPollFD *fds,
void _dbus_sleep_milliseconds (int milliseconds);
-void _dbus_get_real_time (long *tv_sec,
- long *tv_usec);
-
void _dbus_get_monotonic_time (long *tv_sec,
long *tv_usec);
+void _dbus_get_real_time (long *tv_sec,
+ long *tv_usec);
+
/**
* directory interface
*/
@@ -436,7 +448,7 @@ void _dbus_set_signal_handler (int sig,
dbus_bool_t _dbus_user_at_console (const char *username,
DBusError *error);
-void _dbus_init_system_log (void);
+void _dbus_init_system_log (dbus_bool_t is_daemon);
typedef enum {
DBUS_SYSTEM_LOG_INFO,
@@ -506,6 +518,16 @@ dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id,
*/
dbus_bool_t _dbus_threads_init_platform_specific (void);
+/**
+ * Lock a static mutex used to protect _dbus_threads_init_platform_specific().
+ */
+void _dbus_threads_lock_platform_specific (void);
+
+/**
+ * Undo _dbus_threads_lock_platform_specific().
+ */
+void _dbus_threads_unlock_platform_specific (void);
+
dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs,
const char *suffix,
DBusList **dir_list);
diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c
index 224a6c8c..5990d6ec 100644
--- a/dbus/dbus-test.c
+++ b/dbus/dbus-test.c
@@ -28,7 +28,7 @@
#include <stdio.h>
#include <stdlib.h>
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
static void
die (const char *failure)
{
@@ -41,7 +41,7 @@ check_memleaks (void)
{
dbus_shutdown ();
- printf ("%s: checking for memleaks\n", "dbus-test");
+ printf ("%s: checking for memleaks\n", "test-dbus");
if (_dbus_get_malloc_blocks_outstanding () != 0)
{
_dbus_warn ("%d dbus_malloc blocks were not freed\n",
@@ -60,7 +60,7 @@ run_test (const char *test_name,
{
if (!specific_test || strcmp (specific_test, test_name) == 0)
{
- printf ("%s: running %s tests\n", "dbus-test", test_name);
+ printf ("%s: running %s tests\n", "test-dbus", test_name);
if (!test ())
die (test_name);
@@ -76,7 +76,7 @@ run_data_test (const char *test_name,
{
if (!specific_test || strcmp (specific_test, test_name) == 0)
{
- printf ("%s: running %s tests\n", "dbus-test", test_name);
+ printf ("%s: running %s tests\n", "test-dbus", test_name);
if (!test (test_data_dir))
die (test_name);
@@ -84,7 +84,7 @@ run_data_test (const char *test_name,
}
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/**
* An exported symbol to be run in order to execute
@@ -94,11 +94,12 @@ run_data_test (const char *test_name,
* (with --enable-tests=no)
*
* @param test_data_dir the directory with test data (test/data normally)
+ * @param specific_test run specific test or #NULL to run all tests
*/
void
dbus_internal_do_not_use_run_tests (const char *test_data_dir, const char *specific_test)
{
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
if (!_dbus_threads_init_debug ())
die ("debug threads init");
@@ -164,7 +165,7 @@ 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);
- printf ("%s: completed successfully\n", "dbus-test");
+ printf ("%s: completed successfully\n", "test-dbus");
#else
printf ("Not compiled with unit tests, not running any\n");
#endif
diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c
index bb1169db..12d40493 100644
--- a/dbus/dbus-threads.c
+++ b/dbus/dbus-threads.c
@@ -27,18 +27,6 @@
#include "dbus-list.h"
static int thread_init_generation = 0;
-
-static DBusList *uninitialized_rmutex_list = NULL;
-static DBusList *uninitialized_cmutex_list = NULL;
-static DBusList *uninitialized_condvar_list = NULL;
-
-/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */
-#define _DBUS_DUMMY_MUTEX ((DBusMutex*)0xABCDEF)
-#define _DBUS_DUMMY_RMUTEX ((DBusRMutex *) _DBUS_DUMMY_MUTEX)
-#define _DBUS_DUMMY_CMUTEX ((DBusCMutex *) _DBUS_DUMMY_MUTEX)
-
-/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */
-#define _DBUS_DUMMY_CONDVAR ((DBusCondVar*)0xABCDEF2)
/**
* @defgroup DBusThreadsInternals Thread functions
@@ -59,11 +47,6 @@ static DBusList *uninitialized_condvar_list = NULL;
* If possible, the mutex returned by this function is recursive, to
* avoid deadlocks. However, that cannot be relied on.
*
- * The extra level of indirection given by allocating a pointer
- * to point to the mutex location allows the threading
- * module to swap out dummy mutexes for a real mutex so libraries
- * can initialize threads even after the D-Bus API has been used.
- *
* @param location_p the location of the new mutex, can return #NULL on OOM
*/
void
@@ -71,17 +54,13 @@ _dbus_rmutex_new_at_location (DBusRMutex **location_p)
{
_dbus_assert (location_p != NULL);
- if (thread_init_generation == _dbus_current_generation)
+ if (!dbus_threads_init_default ())
{
- *location_p = _dbus_platform_rmutex_new ();
+ *location_p = NULL;
+ return;
}
- else
- {
- *location_p = _DBUS_DUMMY_RMUTEX;
- if (!_dbus_list_append (&uninitialized_rmutex_list, location_p))
- *location_p = NULL;
- }
+ *location_p = _dbus_platform_rmutex_new ();
}
/**
@@ -92,11 +71,6 @@ _dbus_rmutex_new_at_location (DBusRMutex **location_p)
*
* The returned mutex is suitable for use with condition variables.
*
- * The extra level of indirection given by allocating a pointer
- * to point to the mutex location allows the threading
- * module to swap out dummy mutexes for a real mutex so libraries
- * can initialize threads even after the D-Bus API has been used.
- *
* @param location_p the location of the new mutex, can return #NULL on OOM
*/
void
@@ -104,22 +78,17 @@ _dbus_cmutex_new_at_location (DBusCMutex **location_p)
{
_dbus_assert (location_p != NULL);
- if (thread_init_generation == _dbus_current_generation)
+ if (!dbus_threads_init_default ())
{
- *location_p = _dbus_platform_cmutex_new ();
+ *location_p = NULL;
+ return;
}
- else
- {
- *location_p = _DBUS_DUMMY_CMUTEX;
- if (!_dbus_list_append (&uninitialized_cmutex_list, location_p))
- *location_p = NULL;
- }
+ *location_p = _dbus_platform_cmutex_new ();
}
/**
- * Frees a DBusRMutex or removes it from the uninitialized mutex list;
- * does nothing if passed a #NULL pointer.
+ * Frees a DBusRMutex; does nothing if passed a #NULL pointer.
*/
void
_dbus_rmutex_free_at_location (DBusRMutex **location_p)
@@ -127,23 +96,12 @@ _dbus_rmutex_free_at_location (DBusRMutex **location_p)
if (location_p == NULL)
return;
- if (thread_init_generation == _dbus_current_generation)
- {
- if (*location_p != NULL)
- _dbus_platform_rmutex_free (*location_p);
- }
- else
- {
- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_RMUTEX);
-
- _dbus_list_remove (&uninitialized_rmutex_list, location_p);
- }
+ if (*location_p != NULL)
+ _dbus_platform_rmutex_free (*location_p);
}
/**
- * Frees a DBusCMutex and removes it from the
- * uninitialized mutex list;
- * does nothing if passed a #NULL pointer.
+ * Frees a DBusCMutex; does nothing if passed a #NULL pointer.
*/
void
_dbus_cmutex_free_at_location (DBusCMutex **location_p)
@@ -151,17 +109,8 @@ _dbus_cmutex_free_at_location (DBusCMutex **location_p)
if (location_p == NULL)
return;
- if (thread_init_generation == _dbus_current_generation)
- {
- if (*location_p != NULL)
- _dbus_platform_cmutex_free (*location_p);
- }
- else
- {
- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CMUTEX);
-
- _dbus_list_remove (&uninitialized_cmutex_list, location_p);
- }
+ if (*location_p != NULL)
+ _dbus_platform_cmutex_free (*location_p);
}
/**
@@ -172,8 +121,10 @@ _dbus_cmutex_free_at_location (DBusCMutex **location_p)
void
_dbus_rmutex_lock (DBusRMutex *mutex)
{
- if (mutex && thread_init_generation == _dbus_current_generation)
- _dbus_platform_rmutex_lock (mutex);
+ if (mutex == NULL)
+ return;
+
+ _dbus_platform_rmutex_lock (mutex);
}
/**
@@ -184,8 +135,10 @@ _dbus_rmutex_lock (DBusRMutex *mutex)
void
_dbus_cmutex_lock (DBusCMutex *mutex)
{
- if (mutex && thread_init_generation == _dbus_current_generation)
- _dbus_platform_cmutex_lock (mutex);
+ if (mutex == NULL)
+ return;
+
+ _dbus_platform_cmutex_lock (mutex);
}
/**
@@ -196,8 +149,10 @@ _dbus_cmutex_lock (DBusCMutex *mutex)
void
_dbus_rmutex_unlock (DBusRMutex *mutex)
{
- if (mutex && thread_init_generation == _dbus_current_generation)
- _dbus_platform_rmutex_unlock (mutex);
+ if (mutex == NULL)
+ return;
+
+ _dbus_platform_rmutex_unlock (mutex);
}
/**
@@ -208,8 +163,10 @@ _dbus_rmutex_unlock (DBusRMutex *mutex)
void
_dbus_cmutex_unlock (DBusCMutex *mutex)
{
- if (mutex && thread_init_generation == _dbus_current_generation)
- _dbus_platform_cmutex_unlock (mutex);
+ if (mutex == NULL)
+ return;
+
+ _dbus_platform_cmutex_unlock (mutex);
}
/**
@@ -223,19 +180,17 @@ _dbus_cmutex_unlock (DBusCMutex *mutex)
DBusCondVar *
_dbus_condvar_new (void)
{
- if (thread_init_generation == _dbus_current_generation)
- return _dbus_platform_condvar_new ();
- else
- return _DBUS_DUMMY_CONDVAR;
+ if (!dbus_threads_init_default ())
+ return NULL;
+
+ return _dbus_platform_condvar_new ();
}
/**
* This does the same thing as _dbus_condvar_new. It however
* gives another level of indirection by allocating a pointer
- * to point to the condvar location. This allows the threading
- * module to swap out dummy condvars for a real condvar so libraries
- * can initialize threads even after the D-Bus API has been used.
+ * to point to the condvar location; this used to be useful.
*
* @returns the location of a new condvar or #NULL on OOM
*/
@@ -245,17 +200,7 @@ _dbus_condvar_new_at_location (DBusCondVar **location_p)
{
_dbus_assert (location_p != NULL);
- if (thread_init_generation == _dbus_current_generation)
- {
- *location_p = _dbus_condvar_new();
- }
- else
- {
- *location_p = _DBUS_DUMMY_CONDVAR;
-
- if (!_dbus_list_append (&uninitialized_condvar_list, location_p))
- *location_p = NULL;
- }
+ *location_p = _dbus_condvar_new();
}
@@ -266,14 +211,14 @@ _dbus_condvar_new_at_location (DBusCondVar **location_p)
void
_dbus_condvar_free (DBusCondVar *cond)
{
- if (cond && thread_init_generation == _dbus_current_generation)
- _dbus_platform_condvar_free (cond);
+ if (cond == NULL)
+ return;
+
+ _dbus_platform_condvar_free (cond);
}
/**
- * Frees a conditional variable and removes it from the
- * uninitialized_condvar_list;
- * does nothing if passed a #NULL pointer.
+ * Frees a condition variable; does nothing if passed a #NULL pointer.
*/
void
_dbus_condvar_free_at_location (DBusCondVar **location_p)
@@ -281,17 +226,8 @@ _dbus_condvar_free_at_location (DBusCondVar **location_p)
if (location_p == NULL)
return;
- if (thread_init_generation == _dbus_current_generation)
- {
- if (*location_p != NULL)
- _dbus_platform_condvar_free (*location_p);
- }
- else
- {
- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CONDVAR);
-
- _dbus_list_remove (&uninitialized_condvar_list, location_p);
- }
+ if (*location_p != NULL)
+ _dbus_platform_condvar_free (*location_p);
}
/**
@@ -304,8 +240,10 @@ void
_dbus_condvar_wait (DBusCondVar *cond,
DBusCMutex *mutex)
{
- if (cond && mutex && thread_init_generation == _dbus_current_generation)
- _dbus_platform_condvar_wait (cond, mutex);
+ if (cond == NULL || mutex == NULL)
+ return;
+
+ _dbus_platform_condvar_wait (cond, mutex);
}
/**
@@ -324,11 +262,11 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond,
DBusCMutex *mutex,
int timeout_milliseconds)
{
- if (cond && mutex && thread_init_generation == _dbus_current_generation)
- return _dbus_platform_condvar_wait_timeout (cond, mutex,
- timeout_milliseconds);
- else
+ if (cond == NULL || mutex == NULL)
return TRUE;
+
+ return _dbus_platform_condvar_wait_timeout (cond, mutex,
+ timeout_milliseconds);
}
/**
@@ -339,215 +277,83 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond,
void
_dbus_condvar_wake_one (DBusCondVar *cond)
{
- if (cond && thread_init_generation == _dbus_current_generation)
- _dbus_platform_condvar_wake_one (cond);
+ if (cond == NULL)
+ return;
+
+ _dbus_platform_condvar_wake_one (cond);
}
+static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL };
+
static void
-shutdown_global_locks (void *data)
+shutdown_global_locks (void *nil)
{
- DBusRMutex ***locks = data;
int i;
- i = 0;
- while (i < _DBUS_N_GLOBAL_LOCKS)
+ for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++)
{
- if (*(locks[i]) != NULL)
- _dbus_platform_rmutex_free (*(locks[i]));
-
- *(locks[i]) = NULL;
- ++i;
+ _dbus_assert (global_locks[i] != NULL);
+ _dbus_platform_rmutex_free (global_locks[i]);
+ global_locks[i] = NULL;
}
-
- dbus_free (locks);
-}
-
-static void
-shutdown_uninitialized_locks (void *data)
-{
- _dbus_list_clear (&uninitialized_rmutex_list);
- _dbus_list_clear (&uninitialized_cmutex_list);
- _dbus_list_clear (&uninitialized_condvar_list);
}
static dbus_bool_t
-init_uninitialized_locks (void)
+init_global_locks (void)
{
- DBusList *link;
-
- _dbus_assert (thread_init_generation != _dbus_current_generation);
-
- link = uninitialized_rmutex_list;
- while (link != NULL)
- {
- DBusRMutex **mp;
-
- mp = link->data;
- _dbus_assert (*mp == _DBUS_DUMMY_RMUTEX);
-
- *mp = _dbus_platform_rmutex_new ();
- if (*mp == NULL)
- goto fail_mutex;
-
- link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link);
- }
-
- link = uninitialized_cmutex_list;
- while (link != NULL)
- {
- DBusCMutex **mp;
-
- mp = link->data;
- _dbus_assert (*mp == _DBUS_DUMMY_CMUTEX);
-
- *mp = _dbus_platform_cmutex_new ();
- if (*mp == NULL)
- goto fail_mutex;
-
- link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link);
- }
+ int i;
+ dbus_bool_t ok;
- link = uninitialized_condvar_list;
- while (link != NULL)
+ for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++)
{
- DBusCondVar **cp;
-
- cp = (DBusCondVar **)link->data;
- _dbus_assert (*cp == _DBUS_DUMMY_CONDVAR);
+ _dbus_assert (global_locks[i] == NULL);
- *cp = _dbus_platform_condvar_new ();
- if (*cp == NULL)
- goto fail_condvar;
+ global_locks[i] = _dbus_platform_rmutex_new ();
- link = _dbus_list_get_next_link (&uninitialized_condvar_list, link);
+ if (global_locks[i] == NULL)
+ goto failed;
}
- _dbus_list_clear (&uninitialized_rmutex_list);
- _dbus_list_clear (&uninitialized_cmutex_list);
- _dbus_list_clear (&uninitialized_condvar_list);
+ _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]);
+ ok = _dbus_register_shutdown_func_unlocked (shutdown_global_locks, NULL);
+ _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]);
- if (!_dbus_register_shutdown_func (shutdown_uninitialized_locks,
- NULL))
- goto fail_condvar;
+ if (!ok)
+ goto failed;
return TRUE;
- fail_condvar:
- link = uninitialized_condvar_list;
- while (link != NULL)
- {
- DBusCondVar **cp;
-
- cp = link->data;
-
- if (*cp != _DBUS_DUMMY_CONDVAR && *cp != NULL)
- _dbus_platform_condvar_free (*cp);
-
- *cp = _DBUS_DUMMY_CONDVAR;
-
- link = _dbus_list_get_next_link (&uninitialized_condvar_list, link);
- }
-
- fail_mutex:
- link = uninitialized_rmutex_list;
- while (link != NULL)
- {
- DBusRMutex **mp;
-
- mp = link->data;
-
- if (*mp != _DBUS_DUMMY_RMUTEX && *mp != NULL)
- _dbus_platform_rmutex_free (*mp);
-
- *mp = _DBUS_DUMMY_RMUTEX;
-
- link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link);
- }
-
- link = uninitialized_cmutex_list;
- while (link != NULL)
+ failed:
+ for (i = i - 1; i >= 0; i--)
{
- DBusCMutex **mp;
-
- mp = link->data;
-
- if (*mp != _DBUS_DUMMY_CMUTEX && *mp != NULL)
- _dbus_platform_cmutex_free (*mp);
-
- *mp = _DBUS_DUMMY_CMUTEX;
-
- link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link);
+ _dbus_platform_rmutex_free (global_locks[i]);
+ global_locks[i] = NULL;
}
return FALSE;
}
-static dbus_bool_t
-init_locks (void)
+dbus_bool_t
+_dbus_lock (DBusGlobalLock lock)
{
- int i;
- DBusRMutex ***dynamic_global_locks;
- DBusRMutex **global_locks[] = {
-#define LOCK_ADDR(name) (& _dbus_lock_##name)
- LOCK_ADDR (win_fds),
- LOCK_ADDR (sid_atom_cache),
- LOCK_ADDR (list),
- LOCK_ADDR (connection_slots),
- LOCK_ADDR (pending_call_slots),
- LOCK_ADDR (server_slots),
- LOCK_ADDR (message_slots),
-#if !DBUS_USE_SYNC
- LOCK_ADDR (atomic),
-#endif
- LOCK_ADDR (bus),
- LOCK_ADDR (bus_datas),
- LOCK_ADDR (shutdown_funcs),
- LOCK_ADDR (system_users),
- LOCK_ADDR (message_cache),
- LOCK_ADDR (shared_connections),
- LOCK_ADDR (machine_uuid)
-#undef LOCK_ADDR
- };
-
- _dbus_assert (_DBUS_N_ELEMENTS (global_locks) ==
- _DBUS_N_GLOBAL_LOCKS);
-
- i = 0;
-
- dynamic_global_locks = dbus_new (DBusRMutex**, _DBUS_N_GLOBAL_LOCKS);
- if (dynamic_global_locks == NULL)
- goto failed;
-
- while (i < _DBUS_N_ELEMENTS (global_locks))
- {
- *global_locks[i] = _dbus_platform_rmutex_new ();
-
- if (*global_locks[i] == NULL)
- goto failed;
+ _dbus_assert (lock >= 0);
+ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS);
- dynamic_global_locks[i] = global_locks[i];
-
- ++i;
- }
-
- if (!_dbus_register_shutdown_func (shutdown_global_locks,
- dynamic_global_locks))
- goto failed;
+ if (thread_init_generation != _dbus_current_generation &&
+ !dbus_threads_init_default ())
+ return FALSE;
- if (!init_uninitialized_locks ())
- goto failed;
-
+ _dbus_platform_rmutex_lock (global_locks[lock]);
return TRUE;
+}
- failed:
- dbus_free (dynamic_global_locks);
-
- for (i = i - 1; i >= 0; i--)
- {
- _dbus_platform_rmutex_free (*global_locks[i]);
- *global_locks[i] = NULL;
- }
- return FALSE;
+void
+_dbus_unlock (DBusGlobalLock lock)
+{
+ _dbus_assert (lock >= 0);
+ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS);
+
+ _dbus_platform_rmutex_unlock (global_locks[lock]);
}
/** @} */ /* end of internals */
@@ -584,14 +390,24 @@ init_locks (void)
dbus_bool_t
dbus_threads_init (const DBusThreadFunctions *functions)
{
+ _dbus_threads_lock_platform_specific ();
+
if (thread_init_generation == _dbus_current_generation)
- return TRUE;
+ {
+ _dbus_threads_unlock_platform_specific ();
+ return TRUE;
+ }
- if (!init_locks ())
- return FALSE;
+ if (!_dbus_threads_init_platform_specific() ||
+ !init_global_locks ())
+ {
+ _dbus_threads_unlock_platform_specific ();
+ return FALSE;
+ }
thread_init_generation = _dbus_current_generation;
-
+
+ _dbus_threads_unlock_platform_specific ();
return TRUE;
}
@@ -602,11 +418,16 @@ dbus_threads_init (const DBusThreadFunctions *functions)
/**
* Initializes threads. If this function is not called, the D-Bus
* library will not lock any data structures. If it is called, D-Bus
- * will do locking, at some cost in efficiency. Note that this
- * function must be called BEFORE the second thread is started.
+ * will do locking, at some cost in efficiency.
+ *
+ * Since D-Bus 1.7 it is safe to call this function from any thread,
+ * any number of times (but it must be called before any other
+ * libdbus API is used).
*
- * It's safe to call dbus_threads_init_default() as many times as you
- * want, but only the first time will have an effect.
+ * In D-Bus 1.6 or older, this function must be called in the main thread
+ * before any other thread starts. As a result, it is not sufficient to
+ * call this function in a library or plugin, unless the library or plugin
+ * imposes a similar requirement on its callers.
*
* dbus_shutdown() reverses the effects of this function when it
* resets all global state in libdbus.
@@ -616,18 +437,18 @@ dbus_threads_init (const DBusThreadFunctions *functions)
dbus_bool_t
dbus_threads_init_default (void)
{
- return _dbus_threads_init_platform_specific ();
+ return dbus_threads_init (NULL);
}
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
dbus_bool_t
_dbus_threads_init_debug (void)
{
- return _dbus_threads_init_platform_specific();
+ return dbus_threads_init (NULL);
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h
index 44b9d785..396f0ffd 100644
--- a/dbus/dbus-transport-protected.h
+++ b/dbus/dbus-transport-protected.h
@@ -111,7 +111,7 @@ struct DBusTransport
DBusFreeFunction free_windows_user_data; /**< Function to free windows_user_data */
unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */
- unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */
+ unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_peek_is_authenticated() to query value */
unsigned int send_credentials_pending : 1; /**< #TRUE if we need to send credentials */
unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */
unsigned int is_server : 1; /**< #TRUE if on the server side */
diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c
index 0673a8ce..774f4598 100644
--- a/dbus/dbus-transport-socket.c
+++ b/dbus/dbus-transport-socket.c
@@ -135,7 +135,7 @@ check_write_watch (DBusTransport *transport)
_dbus_transport_ref (transport);
- if (_dbus_transport_get_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
else
{
@@ -190,7 +190,7 @@ check_read_watch (DBusTransport *transport)
_dbus_transport_ref (transport);
- if (_dbus_transport_get_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
need_read_watch =
(_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
(_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
@@ -255,8 +255,7 @@ read_data_into_auth (DBusTransport *transport,
bytes_read = _dbus_read_socket (socket_transport->fd,
buffer, socket_transport->max_bytes_read_per_iteration);
- _dbus_auth_return_buffer (transport->auth, buffer,
- bytes_read > 0 ? bytes_read : 0);
+ _dbus_auth_return_buffer (transport->auth, buffer);
if (bytes_read > 0)
{
@@ -404,7 +403,7 @@ do_authentication (DBusTransport *transport,
oom = FALSE;
- orig_auth_state = _dbus_transport_get_is_authenticated (transport);
+ orig_auth_state = _dbus_transport_try_to_authenticate (transport);
/* This is essential to avoid the check_write_watch() at the end,
* we don't want to add a write watch in do_iteration before
@@ -419,7 +418,7 @@ do_authentication (DBusTransport *transport,
_dbus_transport_ref (transport);
- while (!_dbus_transport_get_is_authenticated (transport) &&
+ while (!_dbus_transport_try_to_authenticate (transport) &&
_dbus_transport_get_is_connected (transport))
{
if (!exchange_credentials (transport, do_reading, do_writing))
@@ -477,7 +476,7 @@ do_authentication (DBusTransport *transport,
out:
if (auth_completed)
- *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
+ *auth_completed = (orig_auth_state != _dbus_transport_try_to_authenticate (transport));
check_read_watch (transport);
check_write_watch (transport);
@@ -498,7 +497,7 @@ do_writing (DBusTransport *transport)
dbus_bool_t oom;
/* No messages without authentication! */
- if (!_dbus_transport_get_is_authenticated (transport))
+ if (!_dbus_transport_try_to_authenticate (transport))
{
_dbus_verbose ("Not authenticated, not writing anything\n");
return TRUE;
@@ -703,7 +702,7 @@ do_reading (DBusTransport *transport)
_dbus_verbose ("fd = %d\n",socket_transport->fd);
/* No messages without authentication! */
- if (!_dbus_transport_get_is_authenticated (transport))
+ if (!_dbus_transport_try_to_authenticate (transport))
return TRUE;
oom = FALSE;
@@ -748,29 +747,23 @@ do_reading (DBusTransport *transport)
if (bytes_read > 0)
{
- int orig_len;
-
_dbus_message_loader_get_buffer (transport->loader,
&buffer);
- orig_len = _dbus_string_get_length (buffer);
-
if (!_dbus_auth_decode_data (transport->auth,
&socket_transport->encoded_incoming,
buffer))
{
_dbus_verbose ("Out of memory decoding incoming data\n");
_dbus_message_loader_return_buffer (transport->loader,
- buffer,
- _dbus_string_get_length (buffer) - orig_len);
+ buffer);
oom = TRUE;
goto out;
}
_dbus_message_loader_return_buffer (transport->loader,
- buffer,
- _dbus_string_get_length (buffer) - orig_len);
+ buffer);
_dbus_string_set_length (&socket_transport->encoded_incoming, 0);
_dbus_string_compact (&socket_transport->encoded_incoming, 2048);
@@ -789,7 +782,7 @@ do_reading (DBusTransport *transport)
if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
{
_dbus_verbose ("Out of memory reading file descriptors\n");
- _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
+ _dbus_message_loader_return_buffer (transport->loader, buffer);
oom = TRUE;
goto out;
}
@@ -812,8 +805,7 @@ do_reading (DBusTransport *transport)
}
_dbus_message_loader_return_buffer (transport->loader,
- buffer,
- bytes_read < 0 ? 0 : bytes_read);
+ buffer);
}
if (bytes_read < 0)
@@ -1055,7 +1047,7 @@ socket_do_iteration (DBusTransport *transport,
poll_fd.fd = socket_transport->fd;
poll_fd.events = 0;
- if (_dbus_transport_get_is_authenticated (transport))
+ if (_dbus_transport_try_to_authenticate (transport))
{
/* This is kind of a hack; if we have stuff to write, then try
* to avoid the poll. This is probably about a 5% speedup on an
@@ -1299,7 +1291,7 @@ _dbus_transport_new_for_socket (int fd,
* @param host the host to connect to
* @param port the port to connect to
* @param family the address family to connect to
- * @param path to nonce file
+ * @param noncefile path to nonce file
* @param error location to store reason for failure.
* @returns a new transport, or #NULL on failure.
*/
@@ -1337,12 +1329,12 @@ _dbus_transport_new_for_tcp_socket (const char *host,
goto error;
if (family != NULL &&
- (!_dbus_string_append (&address, "family=") ||
+ (!_dbus_string_append (&address, ",family=") ||
!_dbus_string_append (&address, family)))
goto error;
if (noncefile != NULL &&
- (!_dbus_string_append (&address, "noncefile=") ||
+ (!_dbus_string_append (&address, ",noncefile=") ||
!_dbus_string_append (&address, noncefile)))
goto error;
diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c
index 6ba5c0b5..9a9fea50 100644
--- a/dbus/dbus-transport-unix.c
+++ b/dbus/dbus-transport-unix.c
@@ -412,7 +412,7 @@ _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
dbus_bool_t
_dbus_transport_unix_test (void)
diff --git a/dbus/dbus-transport-win.c b/dbus/dbus-transport-win.c
index faaf1bd2..8fc15749 100644
--- a/dbus/dbus-transport-win.c
+++ b/dbus/dbus-transport-win.c
@@ -51,39 +51,8 @@ _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
DBusTransport **transport_p,
DBusError *error)
{
- const char *method;
-
- const char *host = dbus_address_entry_get_value (entry, "host");
- const char *port = dbus_address_entry_get_value (entry, "port");
- const char *family = dbus_address_entry_get_value (entry, "family");
- const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
-
- method = dbus_address_entry_get_method (entry);
- _dbus_assert (method != NULL);
-
- if (strcmp (method, "nonce-tcp") != 0)
- {
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
- }
-
- if (port == NULL)
- {
- _dbus_set_bad_address (error, "nonce-tcp", "port", NULL);
- return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
- }
-
- *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
- if (*transport_p == NULL)
- {
- _DBUS_ASSERT_ERROR_IS_SET (error);
- return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
- }
- else
- {
- _DBUS_ASSERT_ERROR_IS_CLEAR (error);
- return DBUS_TRANSPORT_OPEN_OK;
- }
+ /* currently no Windows-specific transports */
+ return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
}
/** @} */
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index ba720f25..ecc31827 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -32,7 +32,7 @@
#include "dbus-credentials.h"
#include "dbus-mainloop.h"
#include "dbus-message.h"
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include "dbus-server-debug-pipe.h"
#endif
@@ -242,6 +242,7 @@ _dbus_transport_finalize_base (DBusTransport *transport)
* opened DBusTransport object. If it isn't, returns #NULL
* and sets @p error.
*
+ * @param address the address to be checked.
* @param error address where an error can be returned.
* @returns a new transport, or #NULL on failure.
*/
@@ -253,7 +254,6 @@ check_address (const char *address, DBusError *error)
int len, i;
_dbus_assert (address != NULL);
- _dbus_assert (*address != '\0');
if (!dbus_parse_address (address, &entries, &len, error))
return NULL; /* not a valid address */
@@ -273,6 +273,7 @@ check_address (const char *address, DBusError *error)
* Creates a new transport for the "autostart" method.
* This creates a client-side of a transport.
*
+ * @param scope scope of autolaunch (Windows only)
* @param error address where an error can be returned.
* @returns a new transport, or #NULL on failure.
*/
@@ -349,7 +350,7 @@ static const struct {
{ _dbus_transport_open_socket },
{ _dbus_transport_open_platform_specific },
{ _dbus_transport_open_autolaunch }
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
, { _dbus_transport_open_debug_pipe }
#endif
};
@@ -685,10 +686,33 @@ auth_via_default_rules (DBusTransport *transport)
return allow;
}
+/**
+ * Returns #TRUE if we have been authenticated. It will return #TRUE even if
+ * the transport is now disconnected, but was ever authenticated before
+ * disconnecting.
+ *
+ * This replaces the older _dbus_transport_get_is_authenticated() which
+ * had side-effects.
+ *
+ * @param transport the transport
+ * @returns whether we're authenticated
+ */
+dbus_bool_t
+_dbus_transport_peek_is_authenticated (DBusTransport *transport)
+{
+ return transport->authenticated;
+}
/**
- * Returns #TRUE if we have been authenticated. Will return #TRUE
- * even if the transport is disconnected.
+ * Returns #TRUE if we have been authenticated. It will return #TRUE even if
+ * the transport is now disconnected, but was ever authenticated before
+ * disconnecting.
+ *
+ * If we have not finished authenticating, but we have enough buffered input
+ * to finish the job, then this function will do so before it returns.
+ *
+ * This used to be called _dbus_transport_get_is_authenticated(), but that
+ * name seems inappropriate for a function with side-effects.
*
* @todo we drop connection->mutex when calling the unix_user_function,
* and windows_user_function, which may not be safe really.
@@ -697,7 +721,7 @@ auth_via_default_rules (DBusTransport *transport)
* @returns whether we're authenticated
*/
dbus_bool_t
-_dbus_transport_get_is_authenticated (DBusTransport *transport)
+_dbus_transport_try_to_authenticate (DBusTransport *transport)
{
if (transport->authenticated)
return TRUE;
@@ -1021,9 +1045,7 @@ recover_unused_bytes (DBusTransport *transport)
orig_len);
_dbus_message_loader_return_buffer (transport->loader,
- buffer,
- _dbus_string_get_length (buffer) -
- orig_len);
+ buffer);
_dbus_auth_delete_unused_bytes (transport->auth);
@@ -1053,9 +1075,7 @@ recover_unused_bytes (DBusTransport *transport)
orig_len);
_dbus_message_loader_return_buffer (transport->loader,
- buffer,
- _dbus_string_get_length (buffer) -
- orig_len);
+ buffer);
if (succeeded)
_dbus_auth_delete_unused_bytes (transport->auth);
@@ -1084,12 +1104,12 @@ _dbus_transport_get_dispatch_status (DBusTransport *transport)
_dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
return DBUS_DISPATCH_COMPLETE; /* complete for now */
- if (!_dbus_transport_get_is_authenticated (transport))
+ if (!_dbus_transport_try_to_authenticate (transport))
{
if (_dbus_auth_do_work (transport->auth) ==
DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
return DBUS_DISPATCH_NEED_MEMORY;
- else if (!_dbus_transport_get_is_authenticated (transport))
+ else if (!_dbus_transport_try_to_authenticate (transport))
return DBUS_DISPATCH_COMPLETE;
}
@@ -1338,7 +1358,7 @@ _dbus_transport_get_unix_process_id (DBusTransport *transport,
if (_dbus_credentials_include (auth_identity,
DBUS_CREDENTIAL_UNIX_PROCESS_ID))
{
- *pid = _dbus_credentials_get_unix_pid (auth_identity);
+ *pid = _dbus_credentials_get_pid (auth_identity);
return TRUE;
}
else
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 4b821517..80fa24ef 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -38,7 +38,8 @@ DBusTransport* _dbus_transport_ref (DBusTransport
void _dbus_transport_unref (DBusTransport *transport);
void _dbus_transport_disconnect (DBusTransport *transport);
dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport);
-dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport);
+dbus_bool_t _dbus_transport_peek_is_authenticated (DBusTransport *transport);
+dbus_bool_t _dbus_transport_try_to_authenticate (DBusTransport *transport);
dbus_bool_t _dbus_transport_get_is_anonymous (DBusTransport *transport);
dbus_bool_t _dbus_transport_can_pass_unix_fd (DBusTransport *transport);
diff --git a/dbus/dbus-types.h b/dbus/dbus-types.h
index 57fc586a..021a55af 100644
--- a/dbus/dbus-types.h
+++ b/dbus/dbus-types.h
@@ -79,43 +79,23 @@ typedef dbus_uint32_t dbus_bool_t;
/**
* @typedef dbus_uint64_t
*
- * A 64-bit unsigned integer on all platforms that support it.
- * If supported, #DBUS_HAVE_INT64 will be defined.
- *
- * C99 requires a 64-bit type and most likely all interesting
- * compilers support one. GLib for example flat-out requires
- * a 64-bit type.
- *
- * You probably want to just assume #DBUS_HAVE_INT64 is always defined.
+ * A 64-bit unsigned integer.
*/
/**
* @typedef dbus_int64_t
*
- * A 64-bit signed integer on all platforms that support it.
- * If supported, #DBUS_HAVE_INT64 will be defined.
- *
- * C99 requires a 64-bit type and most likely all interesting
- * compilers support one. GLib for example flat-out requires
- * a 64-bit type.
- *
- * You probably want to just assume #DBUS_HAVE_INT64 is always defined.
+ * A 64-bit signed integer.
*/
/**
* @def DBUS_HAVE_INT64
*
- * Defined if 64-bit integers are available. Will be defined
- * on any platform you care about, unless you care about
- * some truly ancient UNIX, or some bizarre embedded platform.
+ * Always defined.
*
- * C99 requires a 64-bit type and most likely all interesting
- * compilers support one. GLib for example flat-out requires
- * a 64-bit type.
- *
- * You should feel comfortable ignoring this macro and just using
- * int64 unconditionally.
- *
+ * In older libdbus versions, this would be undefined if there was no
+ * 64-bit integer type on that platform. libdbus no longer supports
+ * such platforms.
*/
/**
@@ -136,7 +116,7 @@ typedef dbus_uint32_t dbus_bool_t;
/**
* An 8-byte struct you could use to access int64 without having
- * int64 support
+ * int64 support. Use #dbus_int64_t or #dbus_uint64_t instead.
*/
typedef struct
{
@@ -162,10 +142,8 @@ typedef union
dbus_int32_t i32; /**< as int32 */
dbus_uint32_t u32; /**< as int32 */
dbus_bool_t bool_val; /**< as boolean */
-#ifdef DBUS_HAVE_INT64
dbus_int64_t i64; /**< as int64 */
dbus_uint64_t u64; /**< as int64 */
-#endif
DBus8ByteStruct eight; /**< as 8-byte struct */
double dbl; /**< as double */
unsigned char byt; /**< as byte */
diff --git a/dbus/dbus-userdb-util.c b/dbus/dbus-userdb-util.c
index 16bf2291..888a23e9 100644
--- a/dbus/dbus-userdb-util.c
+++ b/dbus/dbus-userdb-util.c
@@ -21,6 +21,7 @@
*
*/
#include <config.h>
+#include <unistd.h>
#define DBUS_USERDB_INCLUDES_PRIVATE 1
#include "dbus-userdb.h"
#include "dbus-test.h"
@@ -29,7 +30,6 @@
#include <string.h>
#if HAVE_SYSTEMD
-#include <systemd/sd-daemon.h>
#include <systemd/sd-login.h>
#endif
@@ -55,7 +55,8 @@ _dbus_is_console_user (dbus_uid_t uid,
dbus_bool_t result = FALSE;
#ifdef HAVE_SYSTEMD
- if (sd_booted () > 0)
+ /* check if we have logind */
+ if (access ("/run/systemd/seats/", F_OK) >= 0)
{
int r;
@@ -103,7 +104,11 @@ _dbus_is_console_user (dbus_uid_t uid,
#endif /* HAVE_CONSOLE_OWNER_FILE */
- _dbus_user_database_lock_system ();
+ if (!_dbus_user_database_lock_system ())
+ {
+ _DBUS_SET_OOM (error);
+ return FALSE;
+ }
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -157,7 +162,10 @@ _dbus_get_group_id (const DBusString *groupname,
{
DBusUserDatabase *db;
const DBusGroupInfo *info;
- _dbus_user_database_lock_system ();
+
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -194,7 +202,10 @@ _dbus_get_user_id_and_primary_group (const DBusString *username,
{
DBusUserDatabase *db;
const DBusUserInfo *info;
- _dbus_user_database_lock_system ();
+
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -250,7 +261,6 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db,
gid = n;
}
-#ifdef DBUS_ENABLE_USERDB_CACHE
if (gid != DBUS_GID_UNSET)
info = _dbus_hash_table_lookup_uintptr (db->groups, gid);
else
@@ -263,9 +273,6 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db,
return info;
}
else
-#else
- if (1)
-#endif
{
if (gid != DBUS_GID_UNSET)
_dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
@@ -387,7 +394,9 @@ _dbus_groups_from_uid (dbus_uid_t uid,
*group_ids = NULL;
*n_group_ids = 0;
- _dbus_user_database_lock_system ();
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -424,7 +433,7 @@ _dbus_groups_from_uid (dbus_uid_t uid,
}
/** @} */
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
#include <stdio.h>
/**
@@ -477,4 +486,4 @@ _dbus_userdb_test (const char *test_data_dir)
return TRUE;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c
index 4e8b39aa..52f927a3 100644
--- a/dbus/dbus-userdb.c
+++ b/dbus/dbus-userdb.c
@@ -144,7 +144,6 @@ _dbus_user_database_lookup (DBusUserDatabase *db,
uid = n;
}
-#ifdef DBUS_ENABLE_USERDB_CACHE
if (uid != DBUS_UID_UNSET)
info = _dbus_hash_table_lookup_uintptr (db->users, uid);
else
@@ -157,9 +156,6 @@ _dbus_user_database_lookup (DBusUserDatabase *db,
return info;
}
else
-#else
- if (1)
-#endif
{
if (uid != DBUS_UID_UNSET)
_dbus_verbose ("No cache for UID "DBUS_UID_FORMAT"\n",
@@ -306,11 +302,18 @@ init_system_db (void)
/**
* Locks global system user database.
*/
-void
+dbus_bool_t
_dbus_user_database_lock_system (void)
{
- _DBUS_LOCK (system_users);
- database_locked = TRUE;
+ if (_DBUS_LOCK (system_users))
+ {
+ database_locked = TRUE;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
}
/**
@@ -345,8 +348,12 @@ _dbus_user_database_get_system (void)
void
_dbus_user_database_flush_system (void)
{
- _dbus_user_database_lock_system ();
-
+ if (!_dbus_user_database_lock_system ())
+ {
+ /* nothing to flush */
+ return;
+ }
+
if (system_db != NULL)
_dbus_user_database_flush (system_db);
@@ -363,7 +370,9 @@ _dbus_user_database_flush_system (void)
dbus_bool_t
_dbus_username_from_current_process (const DBusString **username)
{
- _dbus_user_database_lock_system ();
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
+
if (!init_system_db ())
{
_dbus_user_database_unlock_system ();
@@ -385,7 +394,9 @@ _dbus_username_from_current_process (const DBusString **username)
dbus_bool_t
_dbus_homedir_from_current_process (const DBusString **homedir)
{
- _dbus_user_database_lock_system ();
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
+
if (!init_system_db ())
{
_dbus_user_database_unlock_system ();
@@ -410,7 +421,10 @@ _dbus_homedir_from_username (const DBusString *username,
{
DBusUserDatabase *db;
const DBusUserInfo *info;
- _dbus_user_database_lock_system ();
+
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -449,7 +463,10 @@ _dbus_homedir_from_uid (dbus_uid_t uid,
{
DBusUserDatabase *db;
const DBusUserInfo *info;
- _dbus_user_database_lock_system ();
+
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -496,7 +513,9 @@ _dbus_credentials_add_from_user (DBusCredentials *credentials,
DBusUserDatabase *db;
const DBusUserInfo *info;
- _dbus_user_database_lock_system ();
+ /* FIXME: this can't distinguish ENOMEM from other errors */
+ if (!_dbus_user_database_lock_system ())
+ return FALSE;
db = _dbus_user_database_get_system ();
if (db == NULL)
@@ -579,7 +598,7 @@ _dbus_user_database_flush (DBusUserDatabase *db)
_dbus_hash_table_remove_all(db->groups);
}
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
/**
* Increments refcount of user database.
* @param db the database
@@ -594,7 +613,7 @@ _dbus_user_database_ref (DBusUserDatabase *db)
return db;
}
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
/**
* Decrements refcount of user database.
diff --git a/dbus/dbus-userdb.h b/dbus/dbus-userdb.h
index cb49d9e7..d6b72d8c 100644
--- a/dbus/dbus-userdb.h
+++ b/dbus/dbus-userdb.h
@@ -86,7 +86,7 @@ void _dbus_group_info_free_allocated (DBusGroupInfo *info);
#endif /* DBUS_USERDB_INCLUDES_PRIVATE */
DBusUserDatabase* _dbus_user_database_get_system (void);
-void _dbus_user_database_lock_system (void);
+dbus_bool_t _dbus_user_database_lock_system (void) _DBUS_GNUC_WARN_UNUSED_RESULT;
void _dbus_user_database_unlock_system (void);
void _dbus_user_database_flush_system (void);
diff --git a/dbus/dbus-valgrind-internal.h b/dbus/dbus-valgrind-internal.h
index 55566ec0..6760b40d 100644
--- a/dbus/dbus-valgrind-internal.h
+++ b/dbus/dbus-valgrind-internal.h
@@ -32,10 +32,10 @@
# include <memcheck.h>
# include <valgrind.h>
#else
-# define VALGRIND_CREATE_MEMPOOL(_1, _2, _3) /* nothing */
-# define VALGRIND_DESTROY_MEMPOOL(_1) /* nothing */
-# define VALGRIND_MEMPOOL_ALLOC(_1, _2, _3) /* nothing */
-# define VALGRIND_MEMPOOL_FREE(_1, _2) /* nothing */
+# define VALGRIND_CREATE_MEMPOOL(_1, _2, _3) do { } while (0)
+# define VALGRIND_DESTROY_MEMPOOL(_1) do { } while (0)
+# define VALGRIND_MEMPOOL_ALLOC(_1, _2, _3) do { } while (0)
+# define VALGRIND_MEMPOOL_FREE(_1, _2) do { } while (0)
/* Recent gcc will warn if you have a statement that's just a macro
* expanding to (0), but not if you have an inline stub function that
diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c
index b9f4ac23..b82c57d4 100644
--- a/dbus/dbus-watch.c
+++ b/dbus/dbus-watch.c
@@ -259,6 +259,25 @@ _dbus_watch_list_free (DBusWatchList *watch_list)
dbus_free (watch_list);
}
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+static const char*
+watch_flags_to_string (int flags)
+{
+ const char *watch_type;
+
+ if ((flags & DBUS_WATCH_READABLE) &&
+ (flags & DBUS_WATCH_WRITABLE))
+ watch_type = "readwrite";
+ else if (flags & DBUS_WATCH_READABLE)
+ watch_type = "read";
+ else if (flags & DBUS_WATCH_WRITABLE)
+ watch_type = "write";
+ else
+ watch_type = "not read or write";
+ return watch_type;
+}
+#endif /* DBUS_ENABLE_VERBOSE_MODE */
+
/**
* Sets the watch functions. This function is the "backend"
* for dbus_connection_set_watch_functions() and
@@ -292,27 +311,9 @@ _dbus_watch_list_set_functions (DBusWatchList *watch_list,
DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
link);
-#ifdef DBUS_ENABLE_VERBOSE_MODE
- {
- const char *watch_type;
- int flags;
-
- flags = dbus_watch_get_flags (link->data);
- if ((flags & DBUS_WATCH_READABLE) &&
- (flags & DBUS_WATCH_WRITABLE))
- watch_type = "readwrite";
- else if (flags & DBUS_WATCH_READABLE)
- watch_type = "read";
- else if (flags & DBUS_WATCH_WRITABLE)
- watch_type = "write";
- else
- watch_type = "not read or write";
-
- _dbus_verbose ("Adding a %s watch on fd %d using newly-set add watch function\n",
- watch_type,
- dbus_watch_get_socket (link->data));
- }
-#endif /* DBUS_ENABLE_VERBOSE_MODE */
+ _dbus_verbose ("Adding a %s watch on fd %d using newly-set add watch function\n",
+ watch_flags_to_string (dbus_watch_get_flags (link->data)),
+ dbus_watch_get_socket (link->data));
if (!(* add_function) (link->data, data))
{
diff --git a/dbus/sd-daemon.c b/dbus/sd-daemon.c
index 9c23b917..485b3010 100644
--- a/dbus/sd-daemon.c
+++ b/dbus/sd-daemon.c
@@ -25,14 +25,14 @@
***/
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+# define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
@@ -40,10 +40,28 @@
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
+#include <stddef.h>
+#include <limits.h>
+
+#if defined(__linux__) && !defined(SD_DAEMON_DISABLE_MQ)
+# include <mqueue.h>
+#endif
#include "sd-daemon.h"
-int sd_listen_fds(int unset_environment) {
+#if (__GNUC__ >= 4)
+# ifdef SD_EXPORT_SYMBOLS
+/* Export symbols */
+# define _sd_export_ __attribute__ ((visibility("default")))
+# else
+/* Don't export the symbols */
+# define _sd_export_ __attribute__ ((visibility("hidden")))
+# endif
+#else
+# define _sd_export_
+#endif
+
+_sd_export_ int sd_listen_fds(int unset_environment) {
#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
return 0;
@@ -53,7 +71,8 @@ int sd_listen_fds(int unset_environment) {
char *p = NULL;
unsigned long l;
- if (!(e = getenv("LISTEN_PID"))) {
+ e = getenv("LISTEN_PID");
+ if (!e) {
r = 0;
goto finish;
}
@@ -61,12 +80,12 @@ int sd_listen_fds(int unset_environment) {
errno = 0;
l = strtoul(e, &p, 10);
- if (errno != 0) {
+ if (errno > 0) {
r = -errno;
goto finish;
}
- if (!p || *p || l <= 0) {
+ if (!p || p == e || *p || l <= 0) {
r = -EINVAL;
goto finish;
}
@@ -77,7 +96,8 @@ int sd_listen_fds(int unset_environment) {
goto finish;
}
- if (!(e = getenv("LISTEN_FDS"))) {
+ e = getenv("LISTEN_FDS");
+ if (!e) {
r = 0;
goto finish;
}
@@ -85,12 +105,12 @@ int sd_listen_fds(int unset_environment) {
errno = 0;
l = strtoul(e, &p, 10);
- if (errno != 0) {
+ if (errno > 0) {
r = -errno;
goto finish;
}
- if (!p || *p) {
+ if (!p || p == e || *p) {
r = -EINVAL;
goto finish;
}
@@ -98,7 +118,8 @@ int sd_listen_fds(int unset_environment) {
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
int flags;
- if ((flags = fcntl(fd, F_GETFD)) < 0) {
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0) {
r = -errno;
goto finish;
}
@@ -124,13 +145,12 @@ finish:
#endif
}
-int sd_is_fifo(int fd, const char *path) {
+_sd_export_ int sd_is_fifo(int fd, const char *path) {
struct stat st_fd;
if (fd < 0)
return -EINVAL;
- memset(&st_fd, 0, sizeof(st_fd));
if (fstat(fd, &st_fd) < 0)
return -errno;
@@ -140,7 +160,6 @@ int sd_is_fifo(int fd, const char *path) {
if (path) {
struct stat st_path;
- memset(&st_path, 0, sizeof(st_path));
if (stat(path, &st_path) < 0) {
if (errno == ENOENT || errno == ENOTDIR)
@@ -157,6 +176,42 @@ int sd_is_fifo(int fd, const char *path) {
return 1;
}
+_sd_export_ int sd_is_special(int fd, const char *path) {
+ struct stat st_fd;
+
+ if (fd < 0)
+ return -EINVAL;
+
+ if (fstat(fd, &st_fd) < 0)
+ return -errno;
+
+ if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode))
+ return 0;
+
+ if (path) {
+ struct stat st_path;
+
+ if (stat(path, &st_path) < 0) {
+
+ if (errno == ENOENT || errno == ENOTDIR)
+ return 0;
+
+ return -errno;
+ }
+
+ if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode))
+ return
+ st_path.st_dev == st_fd.st_dev &&
+ st_path.st_ino == st_fd.st_ino;
+ else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode))
+ return st_path.st_rdev == st_fd.st_rdev;
+ else
+ return 0;
+ }
+
+ return 1;
+}
+
static int sd_is_socket_internal(int fd, int type, int listening) {
struct stat st_fd;
@@ -208,21 +263,19 @@ union sockaddr_union {
struct sockaddr_storage storage;
};
-int sd_is_socket(int fd, int family, int type, int listening) {
+_sd_export_ int sd_is_socket(int fd, int family, int type, int listening) {
int r;
if (family < 0)
return -EINVAL;
- if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+ r = sd_is_socket_internal(fd, type, listening);
+ if (r <= 0)
return r;
if (family > 0) {
- union sockaddr_union sockaddr;
- socklen_t l;
-
- memset(&sockaddr, 0, sizeof(sockaddr));
- l = sizeof(sockaddr);
+ union sockaddr_union sockaddr = {};
+ socklen_t l = sizeof(sockaddr);
if (getsockname(fd, &sockaddr.sa, &l) < 0)
return -errno;
@@ -236,20 +289,18 @@ int sd_is_socket(int fd, int family, int type, int listening) {
return 1;
}
-int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
- union sockaddr_union sockaddr;
- socklen_t l;
+_sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
+ union sockaddr_union sockaddr = {};
+ socklen_t l = sizeof(sockaddr);
int r;
if (family != 0 && family != AF_INET && family != AF_INET6)
return -EINVAL;
- if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+ r = sd_is_socket_internal(fd, type, listening);
+ if (r <= 0)
return r;
- memset(&sockaddr, 0, sizeof(sockaddr));
- l = sizeof(sockaddr);
-
if (getsockname(fd, &sockaddr.sa, &l) < 0)
return -errno;
@@ -281,17 +332,15 @@ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port
return 1;
}
-int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
- union sockaddr_union sockaddr;
- socklen_t l;
+_sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
+ union sockaddr_union sockaddr = {};
+ socklen_t l = sizeof(sockaddr);
int r;
- if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+ r = sd_is_socket_internal(fd, type, listening);
+ if (r <= 0)
return r;
- memset(&sockaddr, 0, sizeof(sockaddr));
- l = sizeof(sockaddr);
-
if (getsockname(fd, &sockaddr.sa, &l) < 0)
return -errno;
@@ -302,29 +351,66 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
return 0;
if (path) {
- if (length <= 0)
+ if (length == 0)
length = strlen(path);
- if (length <= 0)
+ if (length == 0)
/* Unnamed socket */
- return l == sizeof(sa_family_t);
+ return l == offsetof(struct sockaddr_un, sun_path);
if (path[0])
/* Normal path socket */
return
- (l >= sizeof(sa_family_t) + length + 1) &&
+ (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
memcmp(path, sockaddr.un.sun_path, length+1) == 0;
else
/* Abstract namespace socket */
return
- (l == sizeof(sa_family_t) + length) &&
+ (l == offsetof(struct sockaddr_un, sun_path) + length) &&
memcmp(path, sockaddr.un.sun_path, length) == 0;
}
return 1;
}
-int sd_notify(int unset_environment, const char *state) {
+_sd_export_ int sd_is_mq(int fd, const char *path) {
+#if !defined(__linux__) || defined(SD_DAEMON_DISABLE_MQ)
+ return 0;
+#else
+ struct mq_attr attr;
+
+ if (fd < 0)
+ return -EINVAL;
+
+ if (mq_getattr(fd, &attr) < 0)
+ return -errno;
+
+ if (path) {
+ char fpath[PATH_MAX];
+ struct stat a, b;
+
+ if (path[0] != '/')
+ return -EINVAL;
+
+ if (fstat(fd, &a) < 0)
+ return -errno;
+
+ strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12);
+ fpath[sizeof(fpath)-1] = 0;
+
+ if (stat(fpath, &b) < 0)
+ return -errno;
+
+ if (a.st_dev != b.st_dev ||
+ a.st_ino != b.st_ino)
+ return 0;
+ }
+
+ return 1;
+#endif
+}
+
+_sd_export_ int sd_notify(int unset_environment, const char *state) {
#if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC)
return 0;
#else
@@ -339,7 +425,8 @@ int sd_notify(int unset_environment, const char *state) {
goto finish;
}
- if (!(e = getenv("NOTIFY_SOCKET")))
+ e = getenv("NOTIFY_SOCKET");
+ if (!e)
return 0;
/* Must be an abstract socket, or an absolute path */
@@ -348,7 +435,8 @@ int sd_notify(int unset_environment, const char *state) {
goto finish;
}
- if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) {
+ fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0) {
r = -errno;
goto finish;
}
@@ -366,7 +454,7 @@ int sd_notify(int unset_environment, const char *state) {
memset(&msghdr, 0, sizeof(msghdr));
msghdr.msg_name = &sockaddr;
- msghdr.msg_namelen = sizeof(sa_family_t) + strlen(e);
+ msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
msghdr.msg_namelen = sizeof(struct sockaddr_un);
@@ -392,7 +480,7 @@ finish:
#endif
}
-int sd_notifyf(int unset_environment, const char *format, ...) {
+_sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) {
#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
return 0;
#else
@@ -414,22 +502,19 @@ int sd_notifyf(int unset_environment, const char *format, ...) {
#endif
}
-int sd_booted(void) {
+_sd_export_ int sd_booted(void) {
#if defined(DISABLE_SYSTEMD) || !defined(__linux__)
return 0;
#else
+ struct stat st;
- struct stat a, b;
-
- /* We simply test whether the systemd cgroup hierarchy is
- * mounted */
-
- if (lstat("/sys/fs/cgroup", &a) < 0)
- return 0;
+ /* We test whether the runtime unit file directory has been
+ * created. This takes place in mount-setup.c, so is
+ * guaranteed to happen very early during boot. */
- if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
+ if (lstat("/run/systemd/system/", &st) < 0)
return 0;
- return a.st_dev != b.st_dev;
+ return !!S_ISDIR(st.st_mode);
#endif
}
diff --git a/dbus/sd-daemon.h b/dbus/sd-daemon.h
index c68c96d2..fb7456d5 100644
--- a/dbus/sd-daemon.h
+++ b/dbus/sd-daemon.h
@@ -58,21 +58,21 @@ extern "C" {
You may find an up-to-date version of these source files online:
- http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
- http://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
+ http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h
+ http://cgit.freedesktop.org/systemd/systemd/plain/src/libsystemd-daemon/sd-daemon.c
This should compile on non-Linux systems, too, but with the
exception of the sd_is_xxx() calls all functions will become NOPs.
- See sd-daemon(7) for more information.
+ See sd-daemon(3) for more information.
*/
+#ifndef _sd_printf_attr_
#if __GNUC__ >= 4
#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b)))
-#define _sd_hidden_ __attribute__ ((visibility("hidden")))
#else
#define _sd_printf_attr_(a,b)
-#define _sd_hidden_
+#endif
#endif
/*
@@ -109,7 +109,7 @@ extern "C" {
See sd_listen_fds(3) for more information.
*/
-int sd_listen_fds(int unset_environment) _sd_hidden_;
+int sd_listen_fds(int unset_environment);
/*
Helper call for identifying a passed file descriptor. Returns 1 if
@@ -121,7 +121,19 @@ int sd_listen_fds(int unset_environment) _sd_hidden_;
See sd_is_fifo(3) for more information.
*/
-int sd_is_fifo(int fd, const char *path) _sd_hidden_;
+int sd_is_fifo(int fd, const char *path);
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a special character device on the file
+ system stored under the specified path, 0 otherwise.
+ If path is NULL a path name check will not be done and the call
+ only verifies if the file descriptor refers to a special character.
+ Returns a negative errno style error code on failure.
+
+ See sd_is_special(3) for more information.
+*/
+int sd_is_special(int fd, const char *path);
/*
Helper call for identifying a passed file descriptor. Returns 1 if
@@ -137,7 +149,7 @@ int sd_is_fifo(int fd, const char *path) _sd_hidden_;
See sd_is_socket(3) for more information.
*/
-int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
+int sd_is_socket(int fd, int family, int type, int listening);
/*
Helper call for identifying a passed file descriptor. Returns 1 if
@@ -151,7 +163,7 @@ int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
See sd_is_socket_inet(3) for more information.
*/
-int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_;
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
/*
Helper call for identifying a passed file descriptor. Returns 1 if
@@ -167,17 +179,25 @@ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port
See sd_is_socket_unix(3) for more information.
*/
-int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_;
+int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length);
+
+/*
+ Helper call for identifying a passed file descriptor. Returns 1 if
+ the file descriptor is a POSIX Message Queue of the specified name,
+ 0 otherwise. If path is NULL a message queue name check is not
+ done. Returns a negative errno style error code on failure.
+*/
+int sd_is_mq(int fd, const char *path);
/*
Informs systemd about changed daemon state. This takes a number of
- newline seperated environment-style variable assignments in a
+ newline separated environment-style variable assignments in a
string. The following variables are known:
READY=1 Tells systemd that daemon startup is finished (only
relevant for services of Type=notify). The passed
argument is a boolean "1" or "0". Since there is
- little value in signalling non-readiness the only
+ little value in signaling non-readiness the only
value daemons should send is "READY=1".
STATUS=... Passes a single-line status string back to systemd
@@ -197,8 +217,13 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
MAINPID=... The main pid of a daemon, in case systemd did not
fork off the process itself. Example: "MAINPID=4711"
+ WATCHDOG=1 Tells systemd to update the watchdog timestamp.
+ Services using this feature should do this in
+ regular intervals. A watchdog framework can use the
+ timestamps to detect failed services.
+
Daemons can choose to send additional variables. However, it is
- recommened to prefix variable names not listed above with X_.
+ recommended to prefix variable names not listed above with X_.
Returns a negative errno-style error code on failure. Returns > 0
if systemd could be notified, 0 if it couldn't possibly because
@@ -213,7 +238,7 @@ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t
See sd_notify(3) for more information.
*/
-int sd_notify(int unset_environment, const char *state) _sd_hidden_;
+int sd_notify(int unset_environment, const char *state);
/*
Similar to sd_notify() but takes a format string.
@@ -235,7 +260,7 @@ int sd_notify(int unset_environment, const char *state) _sd_hidden_;
See sd_notifyf(3) for more information.
*/
-int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3) _sd_hidden_;
+int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3);
/*
Returns > 0 if the system was booted with systemd. Returns < 0 on
@@ -244,11 +269,11 @@ int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(
fine. You should NOT protect them with a call to this function. Also
note that this function checks whether the system, not the user
session is controlled by systemd. However the functions above work
- for both session and system services.
+ for both user and system services.
See sd_booted(3) for more information.
*/
-int sd_booted(void) _sd_hidden_;
+int sd_booted(void);
#ifdef __cplusplus
}