diff --git a/CMakeLists.txt b/CMakeLists.txt
index 28017a4e..2dd95e98 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.4)
+cmake_minimum_required(VERSION 3.9)
# we do not need to have WIN32 defined
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
@@ -71,7 +71,7 @@ set(DBUS_MACHINE_UUID_FILE ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/dbus/machin
set(DBUS_BINDIR ${CMAKE_INSTALL_FULL_BINDIR})
set(DBUS_DAEMONDIR ${CMAKE_INSTALL_FULL_BINDIR})
set(DBUS_LOCALSTATEDIR ${CMAKE_INSTALL_FULL_LOCALSTATEDIR})
-set(DBUS_RUNSTATEDIR ${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/run)
+set(DBUS_RUNSTATEDIR ${CMAKE_INSTALL_FULL_RUNSTATEDIR})
# On Windows this is relative to where we put the bus setup, in
# ${datadir}/dbus-1. For simplicity, we only do this if
@@ -599,6 +599,18 @@ set(DBUS_SYSTEM_PID_FILE ${DBUS_RUNSTATEDIR}/dbus/pid)
# address.
set(DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=${DBUS_RUNSTATEDIR}/dbus/system_bus_socket" CACHE STRING "system bus default address")
+# This check assumes that the disposition of /run and /var/run on the
+# system where we're building is the same as on the system we're building
+# for, so we can't usefully do this check if we're building for Windows,
+# or if we're cross-building for Unix on a Windows machine.
+#
+# The check is shared between Autotools and CMake.
+# Because we only run it on Unix, it's fine to make it a shell script.
+if(UNIX AND (NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows"))
+ execute_process(
+ COMMAND "${CMAKE_SOURCE_DIR}/tools/check-runstatedir.sh" "${DBUS_RUNSTATEDIR}/dbus/system_bus_socket")
+endif()
+
if(WIN32)
set(DBUS_SESSION_BUS_LISTEN_ADDRESS "autolaunch:" CACHE STRING "session bus default listening address")
set(DBUS_SESSION_BUS_CONNECT_ADDRESS "autolaunch:" CACHE STRING "session bus fallback address for clients")
diff --git a/Makefile.am b/Makefile.am
index ae2d648d..81f3c91e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,6 +37,7 @@ EXTRA_DIST = \
test/CMakeLists.txt \
test/name-test/CMakeLists.txt \
tools/CMakeLists.txt \
+ tools/check-runstatedir.sh \
cmake \
$(NULL)
diff --git a/NEWS b/NEWS
index 15c119f0..085a4cf8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,31 @@
dbus 1.15.4 (UNRELEASED)
========================
+Dependencies:
+
+• Building with CMake now requires CMake ≥ 3.9.
+
+Build-time configuration changes:
+
+• On Unix platforms, a path in the runtime state directory (often /run)
+ is now used for the well-known system bus socket by default. OS
+ distributors should check that the path used is equivalent to the
+ interoperable path /var/run/dbus/system_bus_socket, especially if
+ running on an OS where /var/run is not guaranteed to be a symbolic
+ link to /run.
+ (dbus#180; Issam E. Maghni, Simon McVittie)
+ · With Autotools, this is controlled by --runstatedir, which defaults
+ to ${localstatedir}/run but is often set to /run by OS distributors.
+ The path to the system bus socket can be overridden with the
+ --with-system-socket option if required.
+ · With CMake, this is controlled by the RUNSTATEDIR option, which has
+ behaviour similar to Autotools. There is no separate option for the
+ path to the system bus socket.
+ · With Meson, this is controlled by the runtime_dir option, which
+ defaults to /run if the installation prefix is set to /usr, or has
+ behaviour similar to Autotools otherwise. The path to the system bus
+ socket can be overridden with the system_socket option if required.
+
New API:
• Add dbus_connection_set_builtin_filters_enabled(), intended to be called
diff --git a/bus/Makefile.am b/bus/Makefile.am
index 51a8de81..1f5017c5 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -185,7 +185,7 @@ install-data-hook:
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/session.d
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/services
if DBUS_UNIX
- $(mkinstalldirs) $(DESTDIR)$(localstatedir)/run/dbus
+ $(mkinstalldirs) $(DESTDIR)$(runstatedir)/dbus
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/system.d
$(mkinstalldirs) $(DESTDIR)$(dbusdatadir)/system-services
endif
diff --git a/bus/meson.build b/bus/meson.build
index 1aaaf48d..058e3b25 100644
--- a/bus/meson.build
+++ b/bus/meson.build
@@ -191,7 +191,7 @@ install_emptydirs += [
if platform_unix
install_emptydirs += [
- get_option('localstatedir') / 'run' / 'dbus',
+ runstatedir / 'dbus',
get_option('datadir') / 'dbus-1' / 'system.d',
get_option('datadir') / 'dbus-1' / 'system-services',
]
diff --git a/configure.ac b/configure.ac
index ecff6a04..7da53d5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1286,8 +1286,8 @@ AM_CONDITIONAL(DBUS_CAN_UPLOAD_DOCS,
[test x$enable_doxygen_docs = xyes && test x$enable_xml_docs = xyes &&
test x$enable_ducktype_docs = xyes])
-# Autoconf 2.70 will support this, and many distros patch this option in,
-# but Autoconf 2.70 hasn't actually been released yet.
+# Autoconf 2.70 supports this, and many distros patched this option in
+# before Autoconf 2.70 was released
AS_IF([test -z "${runstatedir}"], [runstatedir='${localstatedir}/run'])
AC_SUBST([runstatedir])
@@ -1330,14 +1330,14 @@ AS_HELP_STRING([--with-systemduserunitdir=DIR], [Directory for systemd user serv
AC_SUBST([systemduserunitdir], [$with_systemduserunitdir])
##### Set up location for system bus socket
-if ! test -z "$with_system_socket"; then
- DBUS_SYSTEM_SOCKET=$with_system_socket
-else
- # We don't use runstatedir for this (yet?), because /var/run has been the
- # interoperable system bus socket for 10+ years.
- # See https://bugs.freedesktop.org/show_bug.cgi?id=101628
- DBUS_SYSTEM_SOCKET=${EXPANDED_LOCALSTATEDIR}/run/dbus/system_bus_socket
-fi
+
+AS_IF([test -n "$with_system_socket"],
+ [DBUS_SYSTEM_SOCKET=$with_system_socket],
+ [DBUS_SYSTEM_SOCKET=${EXPANDED_RUNSTATEDIR}/dbus/system_bus_socket])
+
+dnl The actual check script is shared between Autotools and CMake.
+AS_IF([test "$dbus_win" != yes],
+ [${CONFIG_SHELL-/bin/sh} "${srcdir}/tools/check-runstatedir.sh" "$DBUS_SYSTEM_SOCKET"])
AC_SUBST(DBUS_SYSTEM_SOCKET)
AC_DEFINE_UNQUOTED(DBUS_SYSTEM_SOCKET,"$DBUS_SYSTEM_SOCKET",[The name of the socket the system bus listens on by default])
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index 9b02f5cd..3b0f4cab 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -5783,13 +5783,27 @@
variable. If that variable is not set, applications should try
to connect to the well-known address
unix:path=/var/run/dbus/system_bus_socket.
-
-
- The D-Bus reference implementation actually honors the
- $(localstatedir) configure option
- for this address, on both client and server side.
-
-
+ Implementations of the well-known system bus should listen on
+ an address that will result in that connection being successful.
+
+
+ On systems where /var/run/ is known to be
+ synonymous with /run/ (such as most Linux
+ operating system distributions), implementations might prefer
+ to make use of that knowledge to connect to or listen on
+ unix:path=/run/dbus/system_bus_socket instead,
+ which has some minor technical advantages, particularly during
+ early startup and late shutdown.
+
+
+ In practice, implementations of D-Bus often have build-time
+ configuration options for the system bus address, whose defaults
+ often depend on other build-time options such as the installation
+ prefix (in particular, this is the case for dbus, the reference
+ implementation of D-Bus).
+ Distributors intending to provide access to the well-known
+ system bus should verify that they are using an interoperable
+ address.
On Unix systems, the system bus should default to searching
diff --git a/meson.build b/meson.build
index 20e9dbc6..33294e2e 100644
--- a/meson.build
+++ b/meson.build
@@ -822,15 +822,29 @@ config.set_quoted('DBUS_SESSION_CONFIG_FILE',
system_socket = get_option('system_socket')
if system_socket == ''
- # We don't use runstatedir for this (yet?), because /var/run has been the
- # interoperable system bus socket for 10+ years.
- # See https://bugs.freedesktop.org/show_bug.cgi?id=101628
system_socket = (
- get_option('prefix')
- / get_option('localstatedir')
- /'run'/'dbus'/'system_bus_socket'
+ get_option('prefix') / runstatedir / 'dbus' / 'system_bus_socket'
)
endif
+
+# This check assumes that the disposition of /run and /var/run on the
+# system where we're building is the same as on the system we're building
+# for, so we can't usefully do this check if we're building for Windows,
+# or if we're cross-building for Unix on a Windows machine.
+#
+# The check is shared between Autotools, CMake and Meson.
+# Because we only run it on Unix, it's fine to make it a shell script.
+if platform_unix and build_machine.system() != 'windows'
+ msg = run_command(
+ find_program('tools/check-runstatedir.sh'),
+ system_socket,
+ check: false,
+ ).stdout()
+ if msg != ''
+ warning(msg)
+ endif
+endif
+
data_config.set('DBUS_SYSTEM_SOCKET', system_socket)
## System bus only listens on local domain sockets, and never
diff --git a/tools/check-runstatedir.sh b/tools/check-runstatedir.sh
new file mode 100755
index 00000000..75eb713d
--- /dev/null
+++ b/tools/check-runstatedir.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# Copyright 2022 Collabora Ltd.
+# SPDX-License-Identifier: MIT
+
+# Usage: check-runstatedir.sh /run/dbus/system_bus_socket
+
+set -e
+set -u
+
+same_file () {
+ # Many shells implement test -ef (test whether two names point to
+ # the same file), but POSIX doesn't require it, so fall back to
+ # comparing realpath output if necessary. We prefer test -ef if
+ # available, since it does the right thing for bind-mounts, not just
+ # symlinks
+ if test / -ef / 2>/dev/null; then
+ test "$1" -ef "$2"
+ else
+ test "$(realpath "$1")" = "$(realpath "$2")"
+ fi
+}
+
+if [ -e /run ] && [ -e /var/run ] && ! same_file /run /var/run; then
+ echo
+ echo "WARNING: /run and /var/run are not the same directory."
+ echo "| Tools that do not agree on whether a socket is in /run or in"
+ echo "| /var/run will fail to interoperate."
+ echo "| Ask your OS distributor to make these two directories equivalent"
+ echo "| via a symbolic link or bind mount: there is no useful reason to"
+ echo "| make them different."
+ echo
+fi
+
+system_socket="$1"
+
+case "$system_socket" in
+ (/run/dbus/system_bus_socket)
+ # --with-system-socket=/run/dbus/system_bus_socket
+ if ! same_file /run /var/run; then
+ echo
+ echo "WARNING: system bus socket: /run/dbus/system_bus_socket"
+ echo "| The system bus has been configured to listen on"
+ echo "| /run/dbus/system_bus_socket, but /run is not the same"
+ echo "| as /var/run on this system."
+ echo "|"
+ echo "| Most D-Bus implementations will expect to find the D-Bus"
+ echo "| system bus socket at /var/run/dbus/system_bus_socket."
+ echo "| Consider creating a symbolic link."
+ echo
+ fi
+ ;;
+
+ (/var/run/dbus/system_bus_socket)
+ # e.g. --localstatedir=/var
+ if ! same_file /run /var/run; then
+ echo
+ echo "NOTE: system bus socket: /var/run/dbus/system_bus_socket"
+ echo "| The system bus has been configured to listen on"
+ echo "| /var/run/dbus/system_bus_socket, but /run is not the same"
+ echo "| as /var/run on this system."
+ echo "|"
+ echo "| Some D-Bus implementations might expect to find the"
+ echo "| D-Bus system bus socket at /run/dbus/system_bus_socket."
+ echo "| Consider creating a symbolic link."
+ echo
+ fi
+ ;;
+
+ (*)
+ # e.g. --prefix=/opt/dbus
+ echo
+ echo "NOTE: system bus listens on $system_socket"
+ echo "| This build of dbus will not interoperate with the well-known"
+ echo "| system bus socket, /var/run/dbus/system_bus_socket."
+ echo
+ ;;
+esac