GDBus: try XDG_RUNTIME_DIR/bus before resorting to dbus-launch

This is the right thing to do for the "a session is a user-session"
model implemented in dbus 1.9.14, which is described in
<http://lists.freedesktop.org/archives/dbus/2015-January/016522.html>.

It also resembles sd-bus' behaviour, although sd-bus will only try
kdbus and XDG_RUNTIME_DIR/bus, and never runs dbus-launch.

On systems following the more traditional "a session is a login-session"
model, X_R_D/bus won't exist, so it is harmless to check for it before
falling back to X11 autolaunching. Again, this matches the behaviour
of current libdbus and sd-bus versions.

Now that we do this, g_test_dbus_unset() needs to clear XDG_RUNTIME_DIR
as well as everything else.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=747941
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk>
This commit is contained in:
Simon McVittie 2015-04-15 17:57:29 +01:00
parent 0d3f56e31c
commit 32492c6ab0
2 changed files with 69 additions and 0 deletions

View File

@ -39,8 +39,12 @@
#include "gdbusprivate.h"
#include "giomodule-priv.h"
#include "gdbusdaemon.h"
#include "gstdio.h"
#ifdef G_OS_UNIX
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <gio/gunixsocketaddress.h>
#endif
@ -988,6 +992,49 @@ g_dbus_address_get_stream_sync (const gchar *address,
/* ---------------------------------------------------------------------------------------------------- */
/*
* Return the address of XDG_RUNTIME_DIR/bus if it exists, belongs to
* us, and is a socket, and we are on Unix.
*/
static gchar *
get_session_address_xdg (void)
{
#ifdef G_OS_UNIX
gchar *ret = NULL;
gchar *bus;
gchar *tmp;
GStatBuf buf;
bus = g_build_filename (g_get_user_runtime_dir (), "bus", NULL);
/* if ENOENT, EPERM, etc., quietly don't use it */
if (g_stat (bus, &buf) < 0)
goto out;
/* if it isn't ours, we have incorrectly inherited someone else's
* XDG_RUNTIME_DIR; silently don't use it
*/
if (buf.st_uid != geteuid ())
goto out;
/* if it isn't a socket, silently don't use it */
if ((buf.st_mode & S_IFMT) != S_IFSOCK)
goto out;
tmp = g_dbus_address_escape_value (bus);
ret = g_strconcat ("unix:path=", tmp, NULL);
g_free (tmp);
out:
g_free (bus);
return ret;
#else
return NULL;
#endif
}
/* ---------------------------------------------------------------------------------------------------- */
#ifdef G_OS_UNIX
static gchar *
get_session_address_dbus_launch (GError **error)
@ -1431,11 +1478,31 @@ get_session_address_dbus_launch (GError **error)
static gchar *
get_session_address_platform_specific (GError **error)
{
gchar *ret;
/* Use XDG_RUNTIME_DIR/bus if it exists and is suitable. This is appropriate
* for systems using the "a session is a user-session" model described in
* <http://lists.freedesktop.org/archives/dbus/2015-January/016522.html>,
* and implemented in dbus >= 1.9.14 and sd-bus.
*
* On systems following the more traditional "a session is a login-session"
* model, this will fail and we'll fall through to X11 autolaunching
* (dbus-launch) below.
*/
ret = get_session_address_xdg ();
if (ret != NULL)
return ret;
/* TODO (#694472): try launchd on OS X, like
* _dbus_lookup_session_address_launchd() does, since
* 'dbus-launch --autolaunch' probably won't work there
*/
/* As a last resort, try the "autolaunch:" transport. On Unix this means
* X11 autolaunching; on Windows this means a different autolaunching
* mechanism based on shared memory.
*/
return get_session_address_dbus_launch (error);
}

View File

@ -838,4 +838,6 @@ g_test_dbus_unset (void)
g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
g_unsetenv ("DBUS_STARTER_ADDRESS");
g_unsetenv ("DBUS_STARTER_BUS_TYPE");
/* avoid using XDG_RUNTIME_DIR/bus */
g_unsetenv ("XDG_RUNTIME_DIR");
}