Make the bus launcher abort if an instance is already running
authorMike Gorse <mgorse@novell.com>
Thu, 9 Jun 2011 16:50:58 +0000 (11:50 -0500)
committerMike Gorse <mgorse@novell.com>
Thu, 9 Jun 2011 16:50:58 +0000 (11:50 -0500)
Upon starting up, at-spi-bus-launcher now looks for an X property with
the bus address and tries to connect to it, aborting if successful.
This fixes a bug where, if the launcher was run twice (perhaps by both
an autostart script and a request for the bus address), the second
instance would start its main loop, eventually abort, and delete the X
property, which would cause a new X property to be created later,
overriding the old one, if a different user requested the address,
leading to a11y breakage.

bus/at-spi-bus-launcher.c

index 9300979..dcc35e4 100644 (file)
@@ -27,6 +27,7 @@
 #include <signal.h>
 #include <sys/wait.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include <gio/gio.h>
 #include <X11/Xlib.h>
@@ -349,6 +350,49 @@ is_a11y_using_corba (void)
   return result;
 }
 
+static gboolean
+already_running ()
+{
+  Atom AT_SPI_BUS;
+  Atom actual_type;
+  Display *bridge_display;
+  int actual_format;
+  unsigned char *data = NULL;
+  unsigned long nitems;
+  unsigned long leftover;
+  gboolean result = FALSE;
+
+  bridge_display = XOpenDisplay (NULL);
+  if (!bridge_display)
+             return FALSE;
+      
+  AT_SPI_BUS = XInternAtom (bridge_display, "AT_SPI_BUS", False);
+  XGetWindowProperty (bridge_display,
+                     XDefaultRootWindow (bridge_display),
+                     AT_SPI_BUS, 0L,
+                     (long) BUFSIZ, False,
+                     (Atom) 31, &actual_type, &actual_format,
+                     &nitems, &leftover, &data);
+
+  if (data)
+  {
+    GDBusConnection *bus;
+    GError *error = NULL;
+    const gchar *old_session = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
+    /* TODO: Is there a better way to connect? This is really hacky */
+    g_setenv ("DBUS_SESSION_BUS_ADDRESS", data, TRUE);
+    bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
+    g_setenv ("DBUS_SESSION_BUS_ADDRESS", old_session, TRUE);
+    if (bus != NULL)
+      result = TRUE;
+    g_object_unref (bus);
+  }
+
+  XCloseDisplay (bridge_display);
+  return result;
+}
+
+
 int
 main (int    argc,
       char **argv)
@@ -363,6 +407,9 @@ main (int    argc,
   if (is_a11y_using_corba ())
     return 0;
 
+  if (already_running ())
+    return 0;
+
   _global_app = g_slice_new0 (A11yBusLauncher);
   _global_app->loop = g_main_loop_new (NULL, FALSE);
   _global_app->launch_immediately = (argc == 2 && strcmp (argv[1], "--launch-immediately") == 0);