[at-spi2-core] Make the bus launcher abort if an instance is already running



commit 72b5b5733841657af00f31370d26bdfd5a0b60b7
Author: Mike Gorse <mgorse novell com>
Date:   Thu Jun 9 11:50:58 2011 -0500

    Make the bus launcher abort if an instance is already running
    
    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 |   47 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)
---
diff --git a/bus/at-spi-bus-launcher.c b/bus/at-spi-bus-launcher.c
index 9300979..dcc35e4 100644
--- a/bus/at-spi-bus-launcher.c
+++ b/bus/at-spi-bus-launcher.c
@@ -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);



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