? dbus-string.c.flc Index: dbus-bus.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-bus.c,v retrieving revision 1.55 diff -u -r1.55 dbus-bus.c --- dbus-bus.c 6 Sep 2006 22:00:07 -0000 1.55 +++ dbus-bus.c 15 Sep 2006 15:31:31 -0000 @@ -175,6 +175,11 @@ if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION], "DBUS_SESSION_BUS_ADDRESS")) return FALSE; + + if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) + bus_connection_addresses[DBUS_BUS_SESSION] = + _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS); + _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ? bus_connection_addresses[DBUS_BUS_SESSION] : "none set"); } Index: dbus-internals.h =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-internals.h,v retrieving revision 1.58 diff -u -r1.58 dbus-internals.h --- dbus-internals.h 11 Sep 2006 15:05:21 -0000 1.58 +++ dbus-internals.h 15 Sep 2006 15:31:31 -0000 @@ -37,6 +37,9 @@ DBUS_BEGIN_DECLS +#define DBUS_SESSION_BUS_DEFAULT_METHOD "session" +#define DBUS_SESSION_BUS_DEFAULT_ADDRESS DBUS_SESSION_BUS_DEFAULT_METHOD ":" + void _dbus_warn (const char *format, ...) _DBUS_GNUC_PRINTF (1, 2); Index: dbus-sysdeps-unix.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-unix.c,v retrieving revision 1.3 diff -u -r1.3 dbus-sysdeps-unix.c --- dbus-sysdeps-unix.c 14 Sep 2006 05:07:11 -0000 1.3 +++ dbus-sysdeps-unix.c 15 Sep 2006 15:31:34 -0000 @@ -26,6 +26,7 @@ #include "dbus-sysdeps.h" #include "dbus-threads.h" #include "dbus-protocol.h" +#include "dbus-transport.h" #include "dbus-string.h" #include #include @@ -2212,6 +2213,144 @@ return tmpdir; } +static DBusTransport* +check_address (const char *address, DBusError *error) +{ + DBusAddressEntry **entries; + DBusTransport *transport = NULL; + int len, i; + + if (address == NULL || *address == '\0') + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Unable to determine the address of the message bus " + "(try 'man dbus-launch' and 'man dbus-daemon' for help)"); + return NULL; + } + + if (!dbus_parse_address (address, &entries, &len, error)) + return FALSE; /* not a valid address */ + + for (i = 0; i < len; i++) + { + transport = _dbus_transport_open (entries[i], error); + if (transport != NULL) + break; + } + + dbus_address_entries_free (entries); + return transport; +} + + +#define READ_END 0 +#define WRITE_END 1 +/** + * Determines the address of the session bus by querying X11. Returns + * an open DBusTransport, or error. + */ +DBusTransport * +_dbus_transport_open_sysdep (DBusAddressEntry *entry, + DBusError *error) +{ + static char *cached_address = 0; + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (cached_address == NULL) + { + static char *argv[] = { DBUS_BINDIR "/dbus-launch", "--x11-integration", + "--binary-syntax", NULL }; + char *intermediary_cache; + DBusString address; + int address_pipe[2]; + pid_t pid; + int ret; + + if (!_dbus_string_init (&address)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (pipe (address_pipe) < 0) + { + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to create a pipe: %s", + _dbus_strerror (errno)); + _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n", + _dbus_strerror (errno)); + return NULL; + } + + pid = fork (); + if (pid < 0) + { + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to fork(): %s", + _dbus_strerror (errno)); + _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n", + _dbus_strerror (errno)); + return NULL; + } + + if (pid == 0) + { + /* child process */ + int fd = open ("/dev/null", O_RDWR); + + /* set-up stdXXX */ + close (address_pipe[READ_END]); + close (0); /* close stdin */ + close (1); /* close stdout */ + close (2); /* close stderr */ + dup2 (fd, 0); + dup2 (address_pipe[WRITE_END], 1); + dup2 (fd, 2); + close (fd); + close (address_pipe[WRITE_END]); + + execv (argv[0], argv); + + /* failed, try searching PATH */ + argv[0] = "dbus-launch"; + execvp ("dbus-launch", argv); + + /* still nothing, we failed */ + _exit (1); + } + + /* parent process */ + close (address_pipe[WRITE_END]); + ret = 0; + do + { + ret = _dbus_read (address_pipe[READ_END], &address, 1024); + } + while (ret == 1024); + + /* reap the child process to avoid it lingering as zombie */ + do + { + ret = waitpid (pid, NULL, 0); + } + while (ret == -1 && errno == EINTR); + + if (!_dbus_string_steal_data (&address, &intermediary_cache)) + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + else + /* may leak if reentrant access happens + * the proper solution would be to do a test_and_set. */ + cached_address = intermediary_cache; + _dbus_string_free (&address); + } + + if (cached_address) + return check_address (cached_address, error); + + return NULL; +} + + /** @} end of sysdeps */ /* tests in dbus-sysdeps-util.c */ Index: dbus-transport.c =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v retrieving revision 1.48 diff -u -r1.48 dbus-transport.c --- dbus-transport.c 25 Aug 2006 19:56:00 -0000 1.48 +++ dbus-transport.c 15 Sep 2006 15:31:34 -0000 @@ -297,6 +297,10 @@ transport = _dbus_transport_new_for_tcp_socket (host, lport, error); } + else if (strcmp (method, DBUS_SESSION_BUS_DEFAULT_METHOD) == 0) + { + transport = _dbus_transport_open_sysdep (entry, error); + } #ifdef DBUS_BUILD_TESTS else if (strcmp (method, "debug-pipe") == 0) { Index: dbus-transport.h =================================================================== RCS file: /cvs/dbus/dbus/dbus/dbus-transport.h,v retrieving revision 1.20 diff -u -r1.20 dbus-transport.h --- dbus-transport.h 26 Feb 2005 06:37:46 -0000 1.20 +++ dbus-transport.h 15 Sep 2006 15:31:34 -0000 @@ -34,6 +34,9 @@ DBusTransport* _dbus_transport_open (DBusAddressEntry *entry, DBusError *error); +DBusTransport* _dbus_transport_open_sysdep (DBusAddressEntry *entry, + DBusError *error); + DBusTransport* _dbus_transport_ref (DBusTransport *transport); void _dbus_transport_unref (DBusTransport *transport); void _dbus_transport_disconnect (DBusTransport *transport);