2006-10-01 Havoc Pennington <hp@redhat.com>

* tools/dbus-launch.c (print_variables): if no syntax is given,
	don't print something that's sort-of-half-sh-syntax, just print
	a plain key-value pairs thing.

	* tools/dbus-launch-x11.c: use machine ID rather than hostname for
	the local machine representation (but still have the hostname in
	the display). Remove the hostname from the display if it is
	localhost. Change session files to be named
	~/.dbus/session-bus/machine-display. Change X atoms to be
	underscore-prefixed so nobody whines about ICCCM compliance.
	Otherwise name them the same as the env variables.
	Change session file format to include key-value pairs and an
	explanatory comment. Keys are the same as the env variables.
	(set_address_in_x11): X property format can't depend on
	sizeof(pid_t) on a particular machine, fix to always be 32 bits

	* tools/dbus-launch.c: make --autolaunch take a machine id
	argument. If --autolaunch is used with a program to run, complain
	for now (but add a FIXME). Also, don't look for existing bus if
	there's a program to run (but add a FIXME).

	* dbus/dbus-sysdeps-unix.c (_dbus_get_autolaunch_address): pass
	machine uuid to dbus-launch (avoids linking dbus-launch to libdbus
	just to get this, and avoids duplicating uuid-reading code).

	* tools/dbus-launch.1: clarify various things
This commit is contained in:
Havoc Pennington 2006-10-01 20:05:39 +00:00
parent 7020b57376
commit 10fe37f582
7 changed files with 374 additions and 94 deletions

View file

@ -1,3 +1,32 @@
2006-10-01 Havoc Pennington <hp@redhat.com>
* tools/dbus-launch.c (print_variables): if no syntax is given,
don't print something that's sort-of-half-sh-syntax, just print
a plain key-value pairs thing.
* tools/dbus-launch-x11.c: use machine ID rather than hostname for
the local machine representation (but still have the hostname in
the display). Remove the hostname from the display if it is
localhost. Change session files to be named
~/.dbus/session-bus/machine-display. Change X atoms to be
underscore-prefixed so nobody whines about ICCCM compliance.
Otherwise name them the same as the env variables.
Change session file format to include key-value pairs and an
explanatory comment. Keys are the same as the env variables.
(set_address_in_x11): X property format can't depend on
sizeof(pid_t) on a particular machine, fix to always be 32 bits
* tools/dbus-launch.c: make --autolaunch take a machine id
argument. If --autolaunch is used with a program to run, complain
for now (but add a FIXME). Also, don't look for existing bus if
there's a program to run (but add a FIXME).
* dbus/dbus-sysdeps-unix.c (_dbus_get_autolaunch_address): pass
machine uuid to dbus-launch (avoids linking dbus-launch to libdbus
just to get this, and avoids duplicating uuid-reading code).
* tools/dbus-launch.1: clarify various things
2006-10-01 Havoc Pennington <hp@redhat.com>
* test/test-service.c (path_message_func): remove broken extra

View file

@ -2293,18 +2293,44 @@ _dbus_get_tmpdir(void)
* @returns #TRUE on success, #FALSE if an error happened
*/
dbus_bool_t
_dbus_get_autolaunch_address (DBusString *address, DBusError *error)
_dbus_get_autolaunch_address (DBusString *address,
DBusError *error)
{
static char *argv[] = { DBUS_BINDIR "/dbus-launch", "--autolaunch",
"--binary-syntax", NULL };
static char *argv[5];
int address_pipe[2];
pid_t pid;
int ret;
int status;
int orig_len;
int i;
DBusString uuid;
dbus_bool_t retval;
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
retval = FALSE;
_dbus_string_init (&uuid);
if (!_dbus_get_local_machine_uuid_encoded (&uuid))
{
_DBUS_SET_OOM (error);
goto out;
}
i = 0;
argv[i] = DBUS_BINDIR "/dbus-launch";
++i;
argv[i] = "--autolaunch";
++i;
argv[i] = _dbus_string_get_const_data (&uuid);
++i;
argv[i] = "--binary-syntax";
++i;
argv[i] = NULL;
++i;
_dbus_assert (i == _DBUS_N_ELEMENTS (argv));
orig_len = _dbus_string_get_length (address);
#define READ_END 0
@ -2316,7 +2342,7 @@ _dbus_get_autolaunch_address (DBusString *address, DBusError *error)
_dbus_strerror (errno));
_dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
_dbus_strerror (errno));
return FALSE;
goto out;
}
pid = fork ();
@ -2327,7 +2353,7 @@ _dbus_get_autolaunch_address (DBusString *address, DBusError *error)
_dbus_strerror (errno));
_dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
_dbus_strerror (errno));
return FALSE;
goto out;
}
if (pid == 0)
@ -2389,9 +2415,19 @@ _dbus_get_autolaunch_address (DBusString *address, DBusError *error)
_dbus_string_set_length (address, orig_len);
dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
"Failed to execute dbus-launch to autolaunch D-Bus session");
return FALSE;
goto out;
}
return TRUE;
retval = TRUE;
out:
if (retval)
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
else
_DBUS_ASSERT_ERROR_IS_SET (error);
_dbus_string_free (&uuid);
return retval;
}
/**

View file

@ -1,4 +1,6 @@
INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\"
configdir=$(sysconfdir)/dbus-1
INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_X_CFLAGS) -DDBUS_LOCALEDIR=\"@EXPANDED_DATADIR@/locale\" -DDBUS_COMPILATION -DDBUS_DAEMONDIR=\"@DBUS_DAEMONDIR@\" -DDBUS_MACHINE_UUID_FILE=\""$(configdir)/machine-id"\"
bin_PROGRAMS=dbus-send dbus-monitor dbus-launch dbus-cleanup-sockets dbus-uuidgen

View file

@ -24,6 +24,8 @@
#ifdef DBUS_BUILD_X11
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -46,39 +48,53 @@ x_io_error_handler (Display *xdisplay)
return 0;
}
static char *
get_local_hostname (void)
static void
remove_prefix (char *s,
char *prefix)
{
static const int increment = 128;
static char *cache = NULL;
char *buffer = NULL;
int size = 0;
int plen;
while (cache == NULL)
plen = strlen (prefix);
if (strncmp (s, prefix, plen) == 0)
{
size += increment;
buffer = realloc (buffer, size);
if (buffer == NULL)
return NULL; /* out of memory */
memmove (s, s + plen, strlen (s) - plen + 1);
}
}
if (gethostname (buffer, size - 1) == -1 &&
errno != ENAMETOOLONG)
return NULL;
buffer[size - 1] = '\0'; /* to make sure */
cache = buffer;
static const char*
get_homedir (void)
{
const char *home;
home = getenv ("HOME");
if (home == NULL)
{
/* try from the user database */
struct passwd *user = getpwuid (getuid());
if (user != NULL)
home = user->pw_dir;
}
return cache;
if (home == NULL)
{
fprintf (stderr, "Can't get user home directory\n");
exit (1);
}
return home;
}
#define DBUS_DIR ".dbus"
#define DBUS_SESSION_BUS_DIR "session-bus"
static char *
get_session_file (void)
{
static const char prefix[] = "/.dbus-session-file_";
char *hostname;
static const char prefix[] = "/" DBUS_DIR "/" DBUS_SESSION_BUS_DIR "/";
const char *machine;
const char *home;
char *display;
char *home;
char *result;
char *p;
@ -92,43 +108,46 @@ get_session_file (void)
/* remove the screen part of the display name */
p = strrchr (display, ':');
if (p != NULL)
for ( ; *p; ++p)
if (*p == '.')
{
for ( ; *p; ++p)
{
*p = '\0';
break;
if (*p == '.')
{
*p = '\0';
break;
}
}
}
/* replace the : in the display with _ */
/* Note that we leave the hostname in the display most of the
* time. The idea is that we want to be per-(machine,display,user)
* triplet to be extra-sure we get a bus we can connect to. Ideally
* we'd recognize when the hostname matches the machine we're on in
* all cases; we do try to drop localhost and localhost.localdomain
* as a special common case so that alternate spellings of DISPLAY
* don't result in extra bus instances.
*
* We also kill the ":" if there's nothing in front of it. This
* avoids an ugly double underscore in the filename.
*/
remove_prefix (display, "localhost.localdomain:");
remove_prefix (display, "localhost:");
remove_prefix (display, ":");
/* replace the : in the display with _ if the : is still there.
* use _ instead of - since it can't be in hostnames.
*/
for (p = display; *p; ++p)
if (*p == ':')
*p = '_';
hostname = get_local_hostname ();
if (hostname == NULL)
{
/* out of memory */
free (display);
return NULL;
if (*p == ':')
*p = '_';
}
machine = get_machine_uuid ();
home = getenv ("HOME");
if (home == NULL)
{
/* try from the user database */
struct passwd *user = getpwuid (getuid());
if (user == NULL)
{
verbose ("X11 integration disabled because the home directory"
" could not be determined\n");
free (display);
return NULL;
}
home = user->pw_dir;
}
result = malloc (strlen (home) + strlen (prefix) + strlen (hostname) +
home = get_homedir ();
result = malloc (strlen (home) + strlen (prefix) + strlen (machine) +
strlen (display) + 2);
if (result == NULL)
{
@ -139,8 +158,8 @@ get_session_file (void)
strcpy (result, home);
strcat (result, prefix);
strcat (result, hostname);
strcat (result, "_");
strcat (result, machine);
strcat (result, "-");
strcat (result, display);
free (display);
@ -148,6 +167,46 @@ get_session_file (void)
return result;
}
static void
ensure_session_directory (void)
{
const char *home;
char *dir;
home = get_homedir ();
/* be sure we have space for / and nul */
dir = malloc (strlen (home) + strlen (DBUS_DIR) + strlen (DBUS_SESSION_BUS_DIR) + 3);
if (dir == NULL)
{
fprintf (stderr, "no memory\n");
exit (1);
}
strcpy (dir, home);
strcat (dir, "/");
strcat (dir, DBUS_DIR);
if (mkdir (dir, 0700) < 0)
{
/* only print a warning here, writing the session file itself will fail later */
if (errno != EEXIST)
fprintf (stderr, "Unable to create %s\n", dir);
}
strcat (dir, "/");
strcat (dir, DBUS_SESSION_BUS_DIR);
if (mkdir (dir, 0700) < 0)
{
/* only print a warning here, writing the session file itself will fail later */
if (errno != EEXIST)
fprintf (stderr, "Unable to create %s\n", dir);
}
free (dir);
}
static Display *
open_x11 (void)
{
@ -166,12 +225,12 @@ open_x11 (void)
static int
init_x_atoms (Display *display)
{
static const char selection_prefix[] = "DBUS_SESSION_SELECTION_";
static const char address_prefix[] = "DBUS_SESSION_ADDRESS";
static const char pid_prefix[] = "DBUS_SESSION_PID";
static const char selection_prefix[] = "_DBUS_SESSION_BUS_SELECTION_";
static const char address_prefix[] = "_DBUS_SESSION_BUS_ADDRESS";
static const char pid_prefix[] = "_DBUS_SESSION_BUS_PID";
static int init = FALSE;
char *atom_name;
char *hostname;
const char *machine;
char *user_name;
struct passwd *user;
@ -186,15 +245,9 @@ init_x_atoms (Display *display)
}
user_name = xstrdup(user->pw_name);
hostname = get_local_hostname ();
if (hostname == NULL)
{
verbose ("Could not create X11 atoms; aborting X11 integration.\n");
free (user_name);
return FALSE;
}
machine = get_machine_uuid ();
atom_name = malloc (strlen (hostname) + strlen (user_name) + 2 +
atom_name = malloc (strlen (machine) + strlen (user_name) + 2 +
MAX (strlen (selection_prefix),
MAX (strlen (address_prefix),
strlen (pid_prefix))));
@ -209,7 +262,7 @@ init_x_atoms (Display *display)
strcpy (atom_name, selection_prefix);
strcat (atom_name, user_name);
strcat (atom_name, "_");
strcat (atom_name, hostname);
strcat (atom_name, machine);
selection_atom = XInternAtom (display, atom_name, FALSE);
/* create the address property atom */
@ -285,7 +338,8 @@ set_address_in_x11(char *address, pid_t pid)
{
char *current_address;
Window wid;
int pid32;
/* lock the X11 display to make sure we're doing this atomically */
XGrabServer (xdisplay);
@ -313,8 +367,14 @@ set_address_in_x11(char *address, pid_t pid)
/* Save the property in the window */
XChangeProperty (xdisplay, wid, address_atom, XA_STRING, 8, PropModeReplace,
(unsigned char *)address, strlen (address));
pid32 = pid;
if (sizeof(pid32) != 4)
{
fprintf (stderr, "int is not 32 bits!\n");
exit (1);
}
XChangeProperty (xdisplay, wid, pid_atom, XA_CARDINAL, 32, PropModeReplace,
(unsigned char *)&pid, sizeof(pid) / 4);
(unsigned char *)&pid32, 1);
/* Now grab the selection */
XSetSelectionOwner (xdisplay, selection_atom, wid, CurrentTime);
@ -337,6 +397,7 @@ set_address_in_file (char *address, pid_t pid, Window wid)
char *session_file;
FILE *f;
ensure_session_directory ();
session_file = get_session_file();
if (session_file == NULL)
return FALSE;
@ -344,7 +405,18 @@ set_address_in_file (char *address, pid_t pid, Window wid)
f = fopen (session_file, "w");
if (f == NULL)
return FALSE; /* some kind of error */
fprintf (f, "%s\n%ld\n%ld\n", address, (long)pid, (long)wid);
fprintf (f,
"# This file allows processes on the machine with id %s using \n"
"# display %s to find the D-Bus session bus with the below address.\n"
"# If the DBUS_SESSION_BUS_ADDRESS environment variable is set, it will\n"
"# be used rather than this file.\n"
"# See \"man dbus-launch\" for more details.\n"
"DBUS_SESSION_BUS_ADDRESS=%s\n"
"DBUS_SESSION_BUS_PID=%ld\n"
"DBUS_SESSION_BUS_WINDOWID=%ld\n",
get_machine_uuid (),
getenv ("DISPLAY"),
address, (long)pid, (long)wid);
fclose (f);
free (session_file);

View file

@ -7,27 +7,36 @@
dbus-launch \- Utility to start a message bus from a shell script
.SH SYNOPSIS
.PP
.B dbus-launch [\-\-version] [\-\-sh-syntax] [\-\-csh-syntax] [\-\-auto-syntax] [\-\-exit-with-session] [\-\-autolaunch] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
.B dbus-launch [\-\-version] [\-\-sh-syntax] [\-\-csh-syntax] [\-\-auto-syntax] [\-\-exit-with-session] [\-\-autolaunch=MACHINEID] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
.SH DESCRIPTION
The \fIdbus-launch\fP command is used to start \fIdbus-daemon\fP
from a shell script. It would normally be called from a user's login
The \fIdbus-launch\fP command is used to start a session bus
instance of \fIdbus-daemon\fP from a shell script.
It would normally be called from a user's login
scripts. Unlike the daemon itself, \fIdbus-launch\fP exits, so
backticks or the $() construct can be used to read information from
\fIdbus-launch\fP.
With no arguments, \fIdbus-launch\fP will simply print the values of
DBUS_SESSION_BUS_ADDRESS and DBUS_SESSION_BUS_PID.
With no arguments, \fIdbus-launch\fP will launch a session bus
instance and print the address and pid of that instance to standard
output.
You may specify a program to be run; in this case, \fIdbus-launch\fP
will then set the appropriate environment variables and execute the
will launch a session bus instance, set the appropriate environment
variables so the specified program can find the bus, and then execute the
specified program, with the specified arguments. See below for
examples.
Finally, you may use the \-\-sh-syntax, \-\-csh-syntax, or
\-\-auto-syntax commands to cause \fIdbus-launch\fP to emit shell code
to set up the environment. This is useful in shell scripts.
If you launch a program, \fIdbus-launch\fP will not print the
information about the new bus to standard output.
When \fIdbus-launch\fP prints bus information to standard output, by
default it is in a simple key-value pairs format. However, you may
request several alternate syntaxes using the \-\-sh-syntax, \-\-csh-syntax,
\-\-binary-syntax, or
\-\-auto-syntax options. Several of these cause \fIdbus-launch\fP to emit shell code
to set up the environment.
With the \-\-auto-syntax option, \fIdbus-launch\fP looks at the value
of the SHELL environment variable to determine which shell syntax
@ -67,12 +76,60 @@ dbus-launch gnome-session
.fi
The above would likely be appropriate for ~/.xsession or ~/.Xclients.
.SH AUTOMATIC LAUNCHING
.PP
If DBUS_SESSION_BUS_ADDRESS is not set for a process that tries to use
D-Bus, by default the process will attempt to invoke dbus-launch with
the --autolaunch option to start up a new session bus or find the
existing bus address on the X display or in a file in
~/.dbus/session-bus/
.PP
Whenever an autolaunch occurs, the application that had to
start a new bus will be in its own little world; it can effectively
end up starting a whole new session if it tries to use a lot of
bus services. This can be suboptimal or even totally broken, depending
on the app and what it tries to do.
.PP
There are two common reasons for autolaunch. One is ssh to a remote
machine. The ideal fix for that would be forwarding of
DBUS_SESSION_BUS_ADDRESS in the same way that DISPLAY is forwarded.
In the meantime, you can edit the session.conf config file to
have your session bus listen on TCP, and manually set
DBUS_SESSION_BUS_ADDRESS, if you like.
.PP
The second common reason for autolaunch is an su to another user, and
display of X applications running as the second user on the display
belonging to the first user. Perhaps the ideal fix in this case
would be to allow the second user to connect to the session bus of the
first user, just as they can connect to the first user's display.
However, a mechanism for that has not been coded.
.PP
You can always avoid autolaunch by manually setting
DBUS_SESSION_BUS_ADDRESS. Autolaunch happens because the default
address if none is set is "autolaunch:", so if any other address is
set there will be no autolaunch. You can however include autolaunch in
an explicit session bus address as a fallback, for example
DBUS_SESSION_BUS_ADDRESS="something:,autolaunch:" - in that case if
the first address doesn't work, processes will autolaunch. (The bus
address variable contains a comma-separated list of addresses to try.)
.SH OPTIONS
The following options are supported:
.TP
.I "--auto-syntax"
Choose \-\-csh-syntax or \-\-sh-syntax based on the SHELL environment variable.
.I "--binary-syntax"
Write to stdout a nul-terminated bus address, then the bus PID as a
binary integer of size sizeof(pid_t), then the bus X window ID as a
binary integer of size sizeof(long). Integers are in the machine's
byte order, not network byte order or any other canonical byte order.
.TP
.I "--config-file=FILENAME"
Pass \-\-config-file=FILENAME to the bus daemon, instead of passing it
@ -90,11 +147,12 @@ server. If this process gets a HUP on stdin or loses its X connection,
it kills the message bus daemon.
.TP
.I "--autolaunch"
.I "--autolaunch=MACHINEID"
This option implies that \fIdbus-launch\fP should scan for a
previously-started session and reuse the values found there. If no
session is found, it will start a new session. The
\-\-exit-with-session option is implied if \-\-autolaunch is given.
This option is used by libdbus, you probably do not want to use it manually.
.TP
.I "--sh-syntax"

View file

@ -1,7 +1,8 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-launch.c dbus-launch utility
*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2003, 2006 Red Hat, Inc.
* Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
*
* Licensed under the Academic Free License version 2.1
*
@ -39,6 +40,27 @@
extern Display *xdisplay;
#endif
static char* machine_uuid = NULL;
const char*
get_machine_uuid (void)
{
return machine_uuid;
}
static void
save_machine_uuid (const char *uuid_arg)
{
if (strlen (uuid_arg) != 32)
{
fprintf (stderr, "machine ID '%s' looks like it's the wrong length, should be 32 hex digits",
uuid_arg);
exit (1);
}
machine_uuid = xstrdup (uuid_arg);
}
void
verbose (const char *format,
...)
@ -303,8 +325,9 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
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);
}
else
else if (bourne_shell_syntax)
{
printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
if (bourne_shell_syntax)
@ -312,6 +335,15 @@ print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
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);
}
else
{
printf ("DBUS_SESSION_BUS_ADDRESS=%s\n", bus_address);
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);
}
}
@ -614,8 +646,38 @@ main (int argc, char **argv)
version ();
else if (strcmp (arg, "--exit-with-session") == 0)
exit_with_session = TRUE;
else if (strstr (arg, "--autolaunch=") == arg)
{
const char *s;
if (autolaunch)
{
fprintf (stderr, "--autolaunch given twice\n");
exit (1);
}
autolaunch = TRUE;
s = strchr (arg, '=');
++s;
save_machine_uuid (s);
}
else if (prev_arg &&
strcmp (prev_arg, "--autolaunch") == 0)
{
if (autolaunch)
{
fprintf (stderr, "--autolaunch given twice\n");
exit (1);
}
autolaunch = TRUE;
save_machine_uuid (arg);
}
else if (strcmp (arg, "--autolaunch") == 0)
autolaunch = TRUE;
; /* wait for next arg */
else if (strstr (arg, "--config-file=") == arg)
{
const char *file;
@ -673,7 +735,7 @@ main (int argc, char **argv)
verbose ("--exit-with-session enabled\n");
if (autolaunch)
{
{
#ifndef DBUS_BUILD_X11
fprintf (stderr, "Autolaunch requested, but X11 support not compiled in.\n"
"Cannot continue.\n");
@ -682,7 +744,23 @@ main (int argc, char **argv)
char *address;
pid_t pid;
long wid;
if (get_machine_uuid () == NULL)
{
fprintf (stderr, "Machine UUID not provided as arg to --autolaunch\n");
exit (1);
}
/* FIXME right now autolaunch always does print_variables(), but it should really
* exec the child program instead if a child program was specified. For now
* we just exit if this conflict arises.
*/
if (runprog)
{
fprintf (stderr, "Currently --autolaunch does not support running a program\n");
exit (1);
}
verbose ("Autolaunch enabled (using X11).\n");
if (!exit_with_session)
{
@ -703,7 +781,7 @@ main (int argc, char **argv)
}
if (address != NULL)
{
{
verbose ("dbus-daemon is already running. Returning existing parameters.\n");
print_variables (address, pid, wid, c_shell_syntax,
bourne_shell_syntax, binary_syntax);
@ -902,7 +980,10 @@ main (int argc, char **argv)
close (bus_pid_to_launcher_pipe[READ_END]);
#ifdef DBUS_BUILD_X11
if (xdisplay != NULL)
/* FIXME the runprog == NULL is broken - we need to launch the runprog with the existing bus,
* instead of just doing print_variables() if there's an existing bus.
*/
if (xdisplay != NULL && runprog == NULL)
{
ret2 = x11_save_address (bus_address, bus_pid, &wid);
if (ret2 == 0)

View file

@ -45,6 +45,8 @@ void verbose (const char *format, ...);
char *xstrdup (const char *str);
void kill_bus_and_exit (int exitcode);
const char* get_machine_uuid (void);
#ifdef DBUS_BUILD_X11
/* defined in dbus-launch-x11.c */
int x11_init (void);