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



commit 32492c6ab0000c50564360c74acf069814d942d1
Author: Simon McVittie <simon mcvittie collabora co uk>
Date:   Wed Apr 15 17:57:29 2015 +0100

    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>

 gio/gdbusaddress.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gio/gtestdbus.c    |    2 +
 2 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index 89c4c58..6523623 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -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);
 }
 
diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c
index c7065ae..295c1ea 100644
--- a/gio/gtestdbus.c
+++ b/gio/gtestdbus.c
@@ -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");
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]