summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-20 22:14:48 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2015-02-24 11:25:50 +0000
commit160f5bb9d262ebb0c3ae53487996c1f76c3ad352 (patch)
treeb108ea2ae8298a4b5e0f02dd0eca08f12da56f11
parent71c11a9e487ec5c4b533371098201efb5d966961 (diff)
downloaddbus-160f5bb9d262ebb0c3ae53487996c1f76c3ad352.tar.gz
dbus-launch: if autolaunching, use XDG_RUNTIME_DIR/bus if available
This provides backwards-compatible autolaunching behaviour, as long as dbus-launch inherits the XDG_RUNTIME_DIR (which it presumably did if it's going to work at all, since it must also have inherited the DISPLAY). In particular, we go through the motions of starting the dbus-daemon, so that we can start the "babysitter" process that will maintain the X11 window to store the bus address. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=61301 Reviewed-by: Philip Withnall <philip.withnall@collabora.co.uk> [smcv: decorate _dbus_lookup_user_bus with DBUS_PRIVATE_EXPORT so we can still call it after fixing fd.o#83115; update cmake to match Autotools]
-rw-r--r--dbus/dbus-sysdeps-unix.c7
-rw-r--r--dbus/dbus-sysdeps-unix.h1
-rw-r--r--tools/dbus-launch.c64
-rw-r--r--tools/tool-common.h2
4 files changed, 69 insertions, 5 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 17f2f322..0bcd5abd 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -3713,7 +3713,12 @@ _dbus_get_autolaunch_address (const char *scope,
/* fd.o #19997: if $DISPLAY isn't set to something useful, then
* dbus-launch-x11 is just going to fail. Rather than trying to
- * run it, we might as well bail out early with a nice error. */
+ * run it, we might as well bail out early with a nice error.
+ *
+ * This is not strictly true in a world where the user bus exists,
+ * because dbus-launch --autolaunch knows how to connect to that -
+ * but if we were going to connect to the user bus, we'd have done
+ * so before trying autolaunch: in any case. */
display = _dbus_getenv ("DISPLAY");
if (display == NULL || display[0] == '\0')
diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h
index 86813b5a..333f5eea 100644
--- a/dbus/dbus-sysdeps-unix.h
+++ b/dbus/dbus-sysdeps-unix.h
@@ -90,6 +90,7 @@ dbus_bool_t _dbus_lookup_launchd_socket (DBusString *socket_path,
const char *launchd_env_var,
DBusError *error);
+DBUS_PRIVATE_EXPORT
dbus_bool_t _dbus_lookup_user_bus (dbus_bool_t *supported,
DBusString *address,
DBusError *error);
diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c
index 604663e2..0f1e6ede 100644
--- a/tools/dbus-launch.c
+++ b/tools/dbus-launch.c
@@ -46,6 +46,11 @@
extern Display *xdisplay;
#endif
+#include "dbus/dbus-internals.h"
+#include "dbus/dbus-sysdeps-unix.h"
+
+#include "tool-common.h"
+
/* PROCESSES
*
* If you are in a shell and run "dbus-launch myapp", here is what happens:
@@ -421,7 +426,8 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
else if (c_shell_syntax)
{
printf ("setenv DBUS_SESSION_BUS_ADDRESS '%s';\n", bus_address);
- printf ("set DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
+ if (bus_pid)
+ printf ("set DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
if (bus_wid)
printf ("set DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
fflush (stdout);
@@ -430,7 +436,8 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
{
printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
printf ("export DBUS_SESSION_BUS_ADDRESS;\n");
- printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
+ if (bus_pid)
+ printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
if (bus_wid)
printf ("DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
fflush (stdout);
@@ -438,7 +445,8 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
else
{
printf ("DBUS_SESSION_BUS_ADDRESS=%s\n", bus_address);
- printf ("DBUS_SESSION_BUS_PID=%ld\n", (long) bus_pid);
+ if (bus_pid)
+ printf ("DBUS_SESSION_BUS_PID=%ld\n", (long) bus_pid);
if (bus_wid)
printf ("DBUS_SESSION_BUS_WINDOWID=%ld\n", (long) bus_wid);
fflush (stdout);
@@ -832,6 +840,8 @@ main (int argc, char **argv)
int bus_pid_to_babysitter_pipe[2];
int bus_address_to_launcher_pipe[2];
char *config_file;
+ dbus_bool_t user_bus_supported = FALSE;
+ DBusString user_bus;
exit_with_session = FALSE;
config_file = NULL;
@@ -985,6 +995,7 @@ main (int argc, char **argv)
char *address;
pid_t pid;
long wid;
+ DBusError error = DBUS_ERROR_INIT;
if (get_machine_uuid () == NULL)
{
@@ -992,6 +1003,37 @@ main (int argc, char **argv)
exit (1);
}
+ if (!_dbus_string_init (&user_bus))
+ tool_oom ("initializing");
+
+ /* If we have an XDG_RUNTIME_DIR and it contains a suitable socket,
+ * dbus-launch --autolaunch can use it, since --autolaunch implies
+ * "I'm OK with getting a bus that is already active".
+ *
+ * (However, plain dbus-launch without --autolaunch must not do so,
+ * because that would break lots of regression tests, which often
+ * use dbus-launch instead of the more appropriate dbus-run-session.)
+ *
+ * At this stage, we just save the user bus's address; later on, the
+ * "babysitter" process will be available to advertise the user-bus
+ * on the X11 display and in ~/.dbus/session-bus, for full
+ * backwards compatibility.
+ */
+ if (!_dbus_lookup_user_bus (&user_bus_supported, &user_bus, &error))
+ {
+ fprintf (stderr, "%s\n", error.message);
+ exit (1);
+ }
+ else if (user_bus_supported)
+ {
+ verbose ("=== Using existing user bus \"%s\"\n",
+ _dbus_string_get_const_data (&user_bus));
+ }
+ else
+ {
+ _dbus_string_free (&user_bus);
+ }
+
verbose ("Autolaunch enabled (using X11).\n");
if (!exit_with_session)
{
@@ -1101,6 +1143,22 @@ main (int argc, char **argv)
close (bus_pid_to_babysitter_pipe[READ_END]);
close (bus_pid_to_babysitter_pipe[WRITE_END]);
+ /* If we have a user bus and want to use it, do so instead of
+ * exec'ing a new dbus-daemon. */
+ if (autolaunch && user_bus_supported)
+ {
+ do_write (bus_pid_to_launcher_pipe[WRITE_END], "0\n", 2);
+ close (bus_pid_to_launcher_pipe[WRITE_END]);
+
+ do_write (bus_address_to_launcher_pipe[WRITE_END],
+ _dbus_string_get_const_data (&user_bus),
+ _dbus_string_get_length (&user_bus));
+ do_write (bus_address_to_launcher_pipe[WRITE_END], "\n", 1);
+ close (bus_address_to_launcher_pipe[WRITE_END]);
+
+ exit (0);
+ }
+
sprintf (write_pid_fd_as_string,
"%d", bus_pid_to_launcher_pipe[WRITE_END]);
diff --git a/tools/tool-common.h b/tools/tool-common.h
index d56abf8a..c5984821 100644
--- a/tools/tool-common.h
+++ b/tools/tool-common.h
@@ -33,7 +33,7 @@
#endif
void tool_millisleep (int ms);
-void tool_oom (const char *doing);
+void tool_oom (const char *doing) _DBUS_GNUC_NORETURN;
dbus_bool_t tool_write_all (int fd, const void *buf, size_t size);
#endif