mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-04-20 04:50:48 +02:00
* configure.in: add DBUS_BINDIR as a #define to C source code.
* tools/dbus-launch.c
* tools/dbus-launch.h
* tools/dbus-launch-x11.c:
* tools/dbus-launch.1: Add the --autolaunch option to
dbus-launch, which makes it scan for an existing session
started with --autolaunch. With that option, it also creates
an X11 window and saves the bus address and PID to it.
* dbus/dbus-sysdeps.h:
* dbus/dbus-sysdeps-unix.c (_dbus_get_autolaunch_address): Add
a function that runs "dbus-launch --autolaunch" to retrieve
the running D-Bus session address (or start one if none was running)
* dbus/dbus-transport.c: Add the handler for the "autolaunch:"
address protocol, which tries to get the running session from
dbus-launch.
* dbus/dbus-bus.c:
* dbus/dbus-internals.h: Make "autolaunch:" be the default
D-Bus session bus address.
* dbus/dbus-connection.c: Fix horrible typo in error message.
This commit is contained in:
parent
5f292c611f
commit
f6fa010403
13 changed files with 900 additions and 127 deletions
27
ChangeLog
27
ChangeLog
|
|
@ -1,3 +1,30 @@
|
|||
2006-09-30 Thiago Macieira <thiago@kde.org>
|
||||
|
||||
* configure.in: add DBUS_BINDIR as a #define to C source code.
|
||||
|
||||
* tools/dbus-launch.c
|
||||
* tools/dbus-launch.h
|
||||
* tools/dbus-launch-x11.c:
|
||||
* tools/dbus-launch.1: Add the --autolaunch option to
|
||||
dbus-launch, which makes it scan for an existing session
|
||||
started with --autolaunch. With that option, it also creates
|
||||
an X11 window and saves the bus address and PID to it.
|
||||
|
||||
* dbus/dbus-sysdeps.h:
|
||||
* dbus/dbus-sysdeps-unix.c (_dbus_get_autolaunch_address): Add
|
||||
a function that runs "dbus-launch --autolaunch" to retrieve
|
||||
the running D-Bus session address (or start one if none was running)
|
||||
|
||||
* dbus/dbus-transport.c: Add the handler for the "autolaunch:"
|
||||
address protocol, which tries to get the running session from
|
||||
dbus-launch.
|
||||
|
||||
* dbus/dbus-bus.c:
|
||||
* dbus/dbus-internals.h: Make "autolaunch:" be the default
|
||||
D-Bus session bus address.
|
||||
|
||||
* dbus/dbus-connection.c: Fix horrible typo in error message.
|
||||
|
||||
2006-09-18 John (J5) Palmieri <johnp@redhat.com>
|
||||
|
||||
* tools/Makefile.am: use @EXPANDED_DATADIR@ instead of @DATADIRNAME@
|
||||
|
|
|
|||
|
|
@ -1052,6 +1052,11 @@ fi
|
|||
AC_SUBST(DBUS_DAEMONDIR)
|
||||
AC_DEFINE_UNQUOTED(DBUS_DAEMONDIR,"$DBUS_DAEMONDIR", [Directory for installing the DBUS daemon])
|
||||
|
||||
#### Directory to install the other binaries
|
||||
DBUS_BINDIR=$EXPANDED_BINDIR
|
||||
AC_SUBST(DBUS_BINDIR)
|
||||
AC_DEFINE_UNQUOTED(DBUS_BINDIR,"$DBUS_BINDIR", [Directory for installing the binaries])
|
||||
|
||||
#### Tell tests where to find certain stuff in builddir
|
||||
|
||||
DBUS_PWD=`pwd`
|
||||
|
|
|
|||
|
|
@ -175,6 +175,13 @@ init_connections_unlocked (void)
|
|||
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);
|
||||
if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
|
||||
return FALSE;
|
||||
|
||||
_dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
|
||||
bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2783,7 +2783,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
|
|||
|
||||
error_msg = generate_local_error_message (client_serial,
|
||||
DBUS_ERROR_DISCONNECTED,
|
||||
"Connection was dissconnected before a reply was recived");
|
||||
"Connection was disconnected before a reply was received");
|
||||
|
||||
/* on OOM error_msg is set to NULL */
|
||||
complete_pending_call_and_unlock (connection, pending, error_msg);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
DBUS_BEGIN_DECLS
|
||||
|
||||
#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
|
||||
|
||||
void _dbus_warn (const char *format,
|
||||
...) _DBUS_GNUC_PRINTF (1, 2);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "dbus-sysdeps-unix.h"
|
||||
#include "dbus-threads.h"
|
||||
#include "dbus-protocol.h"
|
||||
#include "dbus-transport.h"
|
||||
#include "dbus-string.h"
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -2275,6 +2276,118 @@ _dbus_get_tmpdir(void)
|
|||
return tmpdir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the address of the session bus by querying a
|
||||
* platform-specific method.
|
||||
*
|
||||
* If successful, returns #TRUE and appends the address to @p
|
||||
* address. If a failure happens, returns #FALSE and
|
||||
* sets an error in @p error.
|
||||
*
|
||||
* @param address a DBusString where the address can be stored
|
||||
* @param error a DBusError to store the error in case of failure
|
||||
* @returns #TRUE on success, #FALSE if an error happened
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_get_autolaunch_address (DBusString *address, DBusError *error)
|
||||
{
|
||||
static char *argv[] = { DBUS_BINDIR "/dbus-launch", "--autolaunch",
|
||||
"--binary-syntax", NULL };
|
||||
int address_pipe[2];
|
||||
pid_t pid;
|
||||
int ret;
|
||||
int status;
|
||||
int orig_len = _dbus_string_get_length (address);
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
#define READ_END 0
|
||||
#define WRITE_END 1
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
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 FALSE;
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
/* child process */
|
||||
int fd = open ("/dev/null", O_RDWR);
|
||||
if (fd == -1)
|
||||
/* huh?! can't open /dev/null? */
|
||||
_exit (1);
|
||||
|
||||
/* set-up stdXXX */
|
||||
close (address_pipe[READ_END]);
|
||||
close (0); /* close stdin */
|
||||
close (1); /* close stdout */
|
||||
close (2); /* close stderr */
|
||||
|
||||
if (dup2 (fd, 0) == -1)
|
||||
_exit (1);
|
||||
if (dup2 (address_pipe[WRITE_END], 1) == -1)
|
||||
_exit (1);
|
||||
if (dup2 (fd, 2) == -1)
|
||||
_exit (1);
|
||||
|
||||
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 > 0);
|
||||
|
||||
/* reap the child process to avoid it lingering as zombie */
|
||||
do
|
||||
{
|
||||
ret = waitpid (pid, &status, 0);
|
||||
}
|
||||
while (ret == -1 && errno == EINTR);
|
||||
|
||||
/* We succeeded if the process exited with status 0 and
|
||||
anything was read */
|
||||
if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
|
||||
_dbus_string_get_length (address) == orig_len)
|
||||
{
|
||||
/* The process ended with 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;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** @} end of sysdeps */
|
||||
|
||||
/* tests in dbus-sysdeps-util.c */
|
||||
|
|
|
|||
|
|
@ -376,6 +376,9 @@ dbus_bool_t _dbus_user_at_console (const char *username,
|
|||
dbus_bool_t _dbus_parse_uid (const DBusString *uid_str,
|
||||
dbus_uid_t *uid);
|
||||
|
||||
dbus_bool_t _dbus_get_autolaunch_address (DBusString *address,
|
||||
DBusError *error);
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
||||
#endif /* DBUS_SYSDEPS_H */
|
||||
|
|
|
|||
|
|
@ -201,13 +201,118 @@ _dbus_transport_finalize_base (DBusTransport *transport)
|
|||
dbus_free (transport->expected_guid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies if a given D-Bus address is a valid address
|
||||
* by attempting to connect to it. If it is, returns the
|
||||
* opened DBusTransport object. If it isn't, returns #NULL
|
||||
* and sets @p error.
|
||||
*
|
||||
* @param error address where an error can be returned.
|
||||
* @returns a new transport, or #NULL on failure.
|
||||
*/
|
||||
static DBusTransport*
|
||||
check_address (const char *address, DBusError *error)
|
||||
{
|
||||
DBusAddressEntry **entries;
|
||||
DBusTransport *transport = NULL;
|
||||
int len, i;
|
||||
|
||||
_dbus_assert (address != NULL);
|
||||
_dbus_assert (*address != '\0');
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new transport for the "autostart" method.
|
||||
* This creates a client-side of a transport.
|
||||
*
|
||||
* @param error address where an error can be returned.
|
||||
* @returns a new transport, or #NULL on failure.
|
||||
*/
|
||||
static DBusTransport*
|
||||
_dbus_transport_new_for_autolaunch (DBusError *error)
|
||||
{
|
||||
DBusString address;
|
||||
DBusTransport *result = NULL;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
if (!_dbus_string_init (&address))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_dbus_get_autolaunch_address (&address, error))
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = check_address (_dbus_string_get_const_data (&address), error);
|
||||
if (result == NULL)
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
else
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
out:
|
||||
_dbus_string_free (&address);
|
||||
return result;
|
||||
}
|
||||
|
||||
static DBusTransportOpenResult
|
||||
_dbus_transport_open_autolaunch (DBusAddressEntry *entry,
|
||||
DBusTransport **transport_p,
|
||||
DBusError *error)
|
||||
{
|
||||
const char *method;
|
||||
|
||||
method = dbus_address_entry_get_method (entry);
|
||||
_dbus_assert (method != NULL);
|
||||
|
||||
if (strcmp (method, "autolaunch") == 0)
|
||||
{
|
||||
*transport_p = _dbus_transport_new_for_autolaunch (error);
|
||||
|
||||
if (*transport_p == NULL)
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
return DBUS_TRANSPORT_OPEN_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
|
||||
DBusTransport **transport_p,
|
||||
DBusError *error);
|
||||
} open_funcs[] = {
|
||||
{ _dbus_transport_open_socket },
|
||||
{ _dbus_transport_open_platform_specific }
|
||||
{ _dbus_transport_open_platform_specific },
|
||||
{ _dbus_transport_open_autolaunch }
|
||||
#ifdef DBUS_BUILD_TESTS
|
||||
, { _dbus_transport_open_debug_pipe }
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ dbus_monitor_SOURCES= \
|
|||
dbus-print-message.h
|
||||
|
||||
dbus_launch_SOURCES= \
|
||||
dbus-launch.c
|
||||
dbus-launch.c \
|
||||
dbus-launch-x11.c
|
||||
|
||||
dbus_cleanup_sockets_SOURCES= \
|
||||
dbus-cleanup-sockets.c
|
||||
|
|
|
|||
392
tools/dbus-launch-x11.c
Normal file
392
tools/dbus-launch-x11.c
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-launch.h dbus-launch utility
|
||||
*
|
||||
* Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include "dbus-launch.h"
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pwd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
Display *xdisplay;
|
||||
static Atom selection_atom;
|
||||
static Atom address_atom;
|
||||
static Atom pid_atom;
|
||||
|
||||
static int
|
||||
x_io_error_handler (Display *xdisplay)
|
||||
{
|
||||
verbose ("X IO error\n");
|
||||
kill_bus_and_exit (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_local_hostname (void)
|
||||
{
|
||||
static const int increment = 128;
|
||||
static char *cache = NULL;
|
||||
char *buffer = NULL;
|
||||
int size = 0;
|
||||
|
||||
while (cache == NULL)
|
||||
{
|
||||
size += increment;
|
||||
buffer = realloc (buffer, size);
|
||||
if (buffer == NULL)
|
||||
return NULL; /* out of memory */
|
||||
|
||||
if (gethostname (buffer, size - 1) == -1 &&
|
||||
errno != ENAMETOOLONG)
|
||||
return NULL;
|
||||
|
||||
buffer[size - 1] = '\0'; /* to make sure */
|
||||
cache = buffer;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_session_file (void)
|
||||
{
|
||||
static const char prefix[] = "/.dbus-session-file_";
|
||||
char *hostname;
|
||||
char *display;
|
||||
char *home;
|
||||
char *result;
|
||||
char *p;
|
||||
|
||||
display = xstrdup (getenv ("DISPLAY"));
|
||||
if (display == NULL)
|
||||
{
|
||||
verbose ("X11 integration disabled because X11 is not running\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* remove the screen part of the display name */
|
||||
p = strrchr (display, ':');
|
||||
if (p != NULL)
|
||||
for ( ; *p; ++p)
|
||||
if (*p == '.')
|
||||
{
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* replace the : in the display with _ */
|
||||
for (p = display; *p; ++p)
|
||||
if (*p == ':')
|
||||
*p = '_';
|
||||
|
||||
hostname = get_local_hostname ();
|
||||
if (hostname == NULL)
|
||||
{
|
||||
/* out of memory */
|
||||
free (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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) +
|
||||
strlen (display) + 2);
|
||||
if (result == NULL)
|
||||
{
|
||||
/* out of memory */
|
||||
free (display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strcpy (result, home);
|
||||
strcat (result, prefix);
|
||||
strcat (result, hostname);
|
||||
strcat (result, "_");
|
||||
strcat (result, display);
|
||||
free (display);
|
||||
|
||||
verbose ("session file: %s\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Display *
|
||||
open_x11 (void)
|
||||
{
|
||||
if (xdisplay != NULL)
|
||||
return xdisplay;
|
||||
|
||||
xdisplay = XOpenDisplay (NULL);
|
||||
if (xdisplay != NULL)
|
||||
{
|
||||
verbose ("Connected to X11 display '%s'\n", DisplayString (xdisplay));
|
||||
XSetIOErrorHandler (x_io_error_handler);
|
||||
}
|
||||
return xdisplay;
|
||||
}
|
||||
|
||||
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 int init = FALSE;
|
||||
char *atom_name;
|
||||
char *hostname;
|
||||
char *user_name;
|
||||
struct passwd *user;
|
||||
|
||||
if (init)
|
||||
return TRUE;
|
||||
|
||||
user = getpwuid (getuid ());
|
||||
if (user == NULL)
|
||||
{
|
||||
verbose ("Could not determine the user informations; aborting X11 integration.\n");
|
||||
return FALSE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
atom_name = malloc (strlen (hostname) + strlen (user_name) + 2 +
|
||||
MAX (strlen (selection_prefix),
|
||||
MAX (strlen (address_prefix),
|
||||
strlen (pid_prefix))));
|
||||
if (atom_name == NULL)
|
||||
{
|
||||
verbose ("Could not create X11 atoms; aborting X11 integration.\n");
|
||||
free (user_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create the selection atom */
|
||||
strcpy (atom_name, selection_prefix);
|
||||
strcat (atom_name, user_name);
|
||||
strcat (atom_name, "_");
|
||||
strcat (atom_name, hostname);
|
||||
selection_atom = XInternAtom (display, atom_name, FALSE);
|
||||
|
||||
/* create the address property atom */
|
||||
strcpy (atom_name, address_prefix);
|
||||
address_atom = XInternAtom (display, atom_name, FALSE);
|
||||
|
||||
/* create the PID property atom */
|
||||
strcpy (atom_name, pid_prefix);
|
||||
pid_atom = XInternAtom (display, atom_name, FALSE);
|
||||
|
||||
free (atom_name);
|
||||
free (user_name);
|
||||
init = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the daemon address from the X11 display.
|
||||
* Returns FALSE if there was an error. Returning
|
||||
* TRUE does not mean the address exists.
|
||||
*/
|
||||
int
|
||||
x11_get_address (char **paddress, pid_t *pid, long *wid)
|
||||
{
|
||||
Atom type;
|
||||
Window owner;
|
||||
int format;
|
||||
unsigned long items;
|
||||
unsigned long after;
|
||||
char *data;
|
||||
|
||||
*paddress = NULL;
|
||||
|
||||
/* locate the selection owner */
|
||||
owner = XGetSelectionOwner (xdisplay, selection_atom);
|
||||
if (owner == None)
|
||||
return TRUE; /* no owner */
|
||||
if (wid != NULL)
|
||||
*wid = (long) owner;
|
||||
|
||||
/* get the bus address */
|
||||
XGetWindowProperty (xdisplay, owner, address_atom, 0, 1024, False,
|
||||
XA_STRING, &type, &format, &items, &after,
|
||||
(unsigned char **) &data);
|
||||
if (type == None || after != 0 || data == NULL || format != 8)
|
||||
return FALSE; /* error */
|
||||
|
||||
*paddress = xstrdup (data);
|
||||
XFree (data);
|
||||
|
||||
/* get the PID */
|
||||
if (pid != NULL)
|
||||
{
|
||||
*pid = 0;
|
||||
XGetWindowProperty (xdisplay, owner, pid_atom, 0, sizeof pid, False,
|
||||
XA_CARDINAL, &type, &format, &items, &after,
|
||||
(unsigned char **) &data);
|
||||
if (type != None && after == 0 && data != NULL && format == 32)
|
||||
*pid = (pid_t) *(long*) data;
|
||||
XFree (data);
|
||||
}
|
||||
|
||||
return TRUE; /* success */
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the address in the X11 display. Returns 0 on success.
|
||||
* If an error occurs, returns -1. If the selection already exists,
|
||||
* returns 1. (i.e. another daemon is already running)
|
||||
*/
|
||||
static Window
|
||||
set_address_in_x11(char *address, pid_t pid)
|
||||
{
|
||||
char *current_address;
|
||||
Window wid;
|
||||
|
||||
/* lock the X11 display to make sure we're doing this atomically */
|
||||
XGrabServer (xdisplay);
|
||||
|
||||
if (!x11_get_address (¤t_address, NULL, NULL))
|
||||
{
|
||||
/* error! */
|
||||
XUngrabServer (xdisplay);
|
||||
return None;
|
||||
}
|
||||
|
||||
if (current_address != NULL)
|
||||
{
|
||||
/* someone saved the address in the meantime */
|
||||
XUngrabServer (xdisplay);
|
||||
free (current_address);
|
||||
return None;
|
||||
}
|
||||
|
||||
/* Create our window */
|
||||
wid = XCreateSimpleWindow (xdisplay, RootWindow (xdisplay, 0), -20, -20, 10, 10,
|
||||
0, WhitePixel (xdisplay, 0),
|
||||
BlackPixel (xdisplay, 0));
|
||||
verbose ("Created window %d\n", wid);
|
||||
|
||||
/* Save the property in the window */
|
||||
XChangeProperty (xdisplay, wid, address_atom, XA_STRING, 8, PropModeReplace,
|
||||
(unsigned char *)address, strlen (address));
|
||||
XChangeProperty (xdisplay, wid, pid_atom, XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char *)&pid, sizeof(pid) / 4);
|
||||
|
||||
/* Now grab the selection */
|
||||
XSetSelectionOwner (xdisplay, selection_atom, wid, CurrentTime);
|
||||
|
||||
/* Ungrab the server to let other people use it too */
|
||||
XUngrabServer (xdisplay);
|
||||
|
||||
XFlush (xdisplay);
|
||||
|
||||
return wid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the session address in session file. Returns TRUE on
|
||||
* success, FALSE if an error occurs.
|
||||
*/
|
||||
static int
|
||||
set_address_in_file (char *address, pid_t pid, Window wid)
|
||||
{
|
||||
char *session_file;
|
||||
FILE *f;
|
||||
|
||||
session_file = get_session_file();
|
||||
if (session_file == NULL)
|
||||
return FALSE;
|
||||
|
||||
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);
|
||||
|
||||
fclose (f);
|
||||
free (session_file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
x11_save_address (char *address, pid_t pid, long *wid)
|
||||
{
|
||||
Window id = set_address_in_x11 (address, pid);
|
||||
if (id != None)
|
||||
{
|
||||
if (!set_address_in_file (address, pid, id))
|
||||
return FALSE;
|
||||
|
||||
if (wid != NULL)
|
||||
*wid = (long) id;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
x11_init (void)
|
||||
{
|
||||
return open_x11 () != NULL && init_x_atoms (xdisplay);
|
||||
}
|
||||
|
||||
void
|
||||
x11_handle_event (void)
|
||||
{
|
||||
if (xdisplay != NULL)
|
||||
{
|
||||
while (XPending (xdisplay))
|
||||
{
|
||||
XEvent ignored;
|
||||
XNextEvent (xdisplay, &ignored);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void dummy_dbus_launch_x11 (void) { }
|
||||
#endif
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
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] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
|
||||
.B dbus-launch [\-\-version] [\-\-sh-syntax] [\-\-csh-syntax] [\-\-auto-syntax] [\-\-exit-with-session] [\-\-autolaunch] [\-\-config-file=FILENAME] [PROGRAM] [ARGS...]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
|
|
@ -89,6 +89,13 @@ created that watches stdin for HUP and tries to connect to the X
|
|||
server. If this process gets a HUP on stdin or loses its X connection,
|
||||
it kills the message bus daemon.
|
||||
|
||||
.TP
|
||||
.I "--autolaunch"
|
||||
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.
|
||||
|
||||
.TP
|
||||
.I "--sh-syntax"
|
||||
Emit Bourne-shell compatible code to set up environment variables.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <config.h>
|
||||
#include "dbus-launch.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -32,22 +32,14 @@
|
|||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/select.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
#include <X11/Xlib.h>
|
||||
extern Display *xdisplay;
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
static void
|
||||
void
|
||||
verbose (const char *format,
|
||||
...)
|
||||
{
|
||||
|
|
@ -95,7 +87,7 @@ version (void)
|
|||
exit (0);
|
||||
}
|
||||
|
||||
static char *
|
||||
char *
|
||||
xstrdup (const char *str)
|
||||
{
|
||||
int len;
|
||||
|
|
@ -276,8 +268,8 @@ do_waitpid (pid_t pid)
|
|||
|
||||
static pid_t bus_pid_to_kill = -1;
|
||||
|
||||
static void
|
||||
kill_bus_and_exit (void)
|
||||
void
|
||||
kill_bus_and_exit (int exitcode)
|
||||
{
|
||||
verbose ("Killing message bus and exiting babysitter\n");
|
||||
|
||||
|
|
@ -290,18 +282,38 @@ kill_bus_and_exit (void)
|
|||
sleep (3);
|
||||
kill (bus_pid_to_kill, SIGKILL);
|
||||
|
||||
exit (0);
|
||||
exit (exitcode);
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
static int
|
||||
x_io_error_handler (Display *xdisplay)
|
||||
static void
|
||||
print_variables (const char *bus_address, pid_t bus_pid, long bus_wid,
|
||||
int c_shell_syntax, int bourne_shell_syntax,
|
||||
int binary_syntax)
|
||||
{
|
||||
verbose ("X IO error\n");
|
||||
kill_bus_and_exit ();
|
||||
return 0;
|
||||
if (binary_syntax)
|
||||
{
|
||||
write (1, bus_address, strlen (bus_address) + 1);
|
||||
write (1, &bus_pid, sizeof bus_pid);
|
||||
write (1, &bus_wid, sizeof bus_wid);
|
||||
return;
|
||||
}
|
||||
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_wid)
|
||||
printf ("set DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
|
||||
if (bourne_shell_syntax)
|
||||
printf ("export DBUS_SESSION_BUS_ADDRESS;\n");
|
||||
printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
|
||||
if (bus_wid)
|
||||
printf ("DBUS_SESSION_BUS_WINDOWID=%ld;\n", (long) bus_wid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int got_sighup = FALSE;
|
||||
|
||||
|
|
@ -326,9 +338,6 @@ kill_bus_when_session_ends (void)
|
|||
fd_set err_set;
|
||||
struct sigaction act;
|
||||
sigset_t empty_mask;
|
||||
#ifdef DBUS_BUILD_X11
|
||||
Display *xdisplay;
|
||||
#endif
|
||||
|
||||
/* install SIGHUP handler */
|
||||
got_sighup = FALSE;
|
||||
|
|
@ -340,17 +349,14 @@ kill_bus_when_session_ends (void)
|
|||
sigaction (SIGTERM, &act, NULL);
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
xdisplay = XOpenDisplay (NULL);
|
||||
x11_init();
|
||||
if (xdisplay != NULL)
|
||||
{
|
||||
verbose ("Successfully opened X display\n");
|
||||
x_fd = ConnectionNumber (xdisplay);
|
||||
XSetIOErrorHandler (x_io_error_handler);
|
||||
}
|
||||
else
|
||||
x_fd = -1;
|
||||
#else
|
||||
verbose ("Compiled without X11 support\n");
|
||||
x_fd = -1;
|
||||
#endif
|
||||
|
||||
|
|
@ -393,7 +399,7 @@ kill_bus_when_session_ends (void)
|
|||
if (got_sighup)
|
||||
{
|
||||
verbose ("Got SIGHUP, exiting\n");
|
||||
kill_bus_and_exit ();
|
||||
kill_bus_and_exit (0);
|
||||
}
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
|
|
@ -405,15 +411,7 @@ kill_bus_when_session_ends (void)
|
|||
verbose ("X fd condition reading = %d error = %d\n",
|
||||
FD_ISSET (x_fd, &read_set),
|
||||
FD_ISSET (x_fd, &err_set));
|
||||
|
||||
if (xdisplay != NULL)
|
||||
{
|
||||
while (XPending (xdisplay))
|
||||
{
|
||||
XEvent ignored;
|
||||
XNextEvent (xdisplay, &ignored);
|
||||
}
|
||||
}
|
||||
x11_handle_event ();
|
||||
#endif
|
||||
|
||||
if (tty_fd >= 0)
|
||||
|
|
@ -431,7 +429,7 @@ kill_bus_when_session_ends (void)
|
|||
bytes_read, errno);
|
||||
|
||||
if (bytes_read == 0)
|
||||
kill_bus_and_exit (); /* EOF */
|
||||
kill_bus_and_exit (0); /* EOF */
|
||||
else if (bytes_read < 0 && errno != EINTR)
|
||||
{
|
||||
/* This shouldn't happen I don't think; to avoid
|
||||
|
|
@ -439,14 +437,14 @@ kill_bus_when_session_ends (void)
|
|||
*/
|
||||
fprintf (stderr, "dbus-launch: error reading from stdin: %s\n",
|
||||
strerror (errno));
|
||||
kill_bus_and_exit ();
|
||||
kill_bus_and_exit (0);
|
||||
}
|
||||
}
|
||||
else if (FD_ISSET (tty_fd, &err_set))
|
||||
{
|
||||
verbose ("TTY has error condition\n");
|
||||
|
||||
kill_bus_and_exit ();
|
||||
kill_bus_and_exit (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -455,19 +453,14 @@ kill_bus_when_session_ends (void)
|
|||
static void
|
||||
babysit (int exit_with_session,
|
||||
pid_t child_pid,
|
||||
int read_bus_pid_fd, /* read pid from here */
|
||||
int write_bus_pid_fd) /* forward pid to here */
|
||||
int read_bus_pid_fd) /* read pid from here */
|
||||
{
|
||||
int ret;
|
||||
#define MAX_PID_LEN 64
|
||||
char buf[MAX_PID_LEN];
|
||||
long val;
|
||||
char *end;
|
||||
int dev_null_fd;
|
||||
const char *s;
|
||||
|
||||
verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d, write_bus_pid_fd = %d\n",
|
||||
exit_with_session, (long) child_pid, read_bus_pid_fd, write_bus_pid_fd);
|
||||
verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d\n",
|
||||
exit_with_session, (long) child_pid, read_bus_pid_fd);
|
||||
|
||||
/* We chdir ("/") since we are persistent and daemon-like, and fork
|
||||
* again so dbus-launch can reap the parent. However, we don't
|
||||
|
|
@ -536,41 +529,26 @@ babysit (int exit_with_session,
|
|||
/* Child continues */
|
||||
verbose ("=== Babysitter process created\n");
|
||||
|
||||
verbose ("Reading PID from daemon\n");
|
||||
/* Now read data */
|
||||
switch (read_line (read_bus_pid_fd, buf, MAX_PID_LEN))
|
||||
verbose ("Reading PID from bus\n");
|
||||
|
||||
switch (read_pid (read_bus_pid_fd, &bus_pid_to_kill))
|
||||
{
|
||||
case READ_STATUS_OK:
|
||||
break;
|
||||
case READ_STATUS_EOF:
|
||||
fprintf (stderr, "EOF reading PID from bus daemon\n");
|
||||
fprintf (stderr, "EOF in dbus-launch reading PID from bus daemon\n");
|
||||
exit (1);
|
||||
break;
|
||||
case READ_STATUS_ERROR:
|
||||
fprintf (stderr, "Error reading PID from bus daemon: %s\n",
|
||||
strerror (errno));
|
||||
fprintf (stderr, "Error in dbus-launch reading PID from bus daemon: %s\n",
|
||||
strerror (errno));
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
|
||||
end = NULL;
|
||||
val = strtol (buf, &end, 0);
|
||||
if (buf == end || end == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n",
|
||||
buf, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
bus_pid_to_kill = val;
|
||||
|
||||
verbose ("Got PID %ld from daemon\n",
|
||||
(long) bus_pid_to_kill);
|
||||
|
||||
/* Write data to launcher */
|
||||
write_pid (write_bus_pid_fd, bus_pid_to_kill);
|
||||
close (write_bus_pid_fd);
|
||||
|
||||
if (exit_with_session)
|
||||
{
|
||||
/* Bus is now started and launcher has needed info;
|
||||
|
|
@ -597,9 +575,11 @@ main (int argc, char **argv)
|
|||
const char *runprog = NULL;
|
||||
int remaining_args = 0;
|
||||
int exit_with_session;
|
||||
int binary_syntax = FALSE;
|
||||
int c_shell_syntax = FALSE;
|
||||
int bourne_shell_syntax = FALSE;
|
||||
int auto_shell_syntax = FALSE;
|
||||
int autolaunch = FALSE;
|
||||
int i;
|
||||
int ret;
|
||||
int bus_pid_to_launcher_pipe[2];
|
||||
|
|
@ -628,10 +608,14 @@ main (int argc, char **argv)
|
|||
else if (strcmp (arg, "-s") == 0 ||
|
||||
strcmp (arg, "--sh-syntax") == 0)
|
||||
bourne_shell_syntax = TRUE;
|
||||
else if (strcmp (arg, "--binary-syntax") == 0)
|
||||
binary_syntax = TRUE;
|
||||
else if (strcmp (arg, "--version") == 0)
|
||||
version ();
|
||||
else if (strcmp (arg, "--exit-with-session") == 0)
|
||||
exit_with_session = TRUE;
|
||||
else if (strcmp (arg, "--autolaunch") == 0)
|
||||
autolaunch = TRUE;
|
||||
else if (strstr (arg, "--config-file=") == arg)
|
||||
{
|
||||
const char *file;
|
||||
|
|
@ -672,9 +656,6 @@ main (int argc, char **argv)
|
|||
++i;
|
||||
}
|
||||
|
||||
if (exit_with_session)
|
||||
verbose ("--exit-with-session enabled\n");
|
||||
|
||||
if (auto_shell_syntax)
|
||||
{
|
||||
if ((shname = getenv ("SHELL")) != NULL)
|
||||
|
|
@ -688,8 +669,52 @@ main (int argc, char **argv)
|
|||
bourne_shell_syntax = TRUE;
|
||||
}
|
||||
|
||||
if (exit_with_session)
|
||||
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");
|
||||
exit (1);
|
||||
#else
|
||||
char *address;
|
||||
pid_t pid;
|
||||
long wid;
|
||||
|
||||
verbose ("Autolaunch enabled (using X11).\n");
|
||||
if (!exit_with_session)
|
||||
{
|
||||
verbose ("--exit-with-session automatically enabled\n");
|
||||
exit_with_session = TRUE;
|
||||
}
|
||||
|
||||
if (!x11_init ())
|
||||
{
|
||||
fprintf (stderr, "Autolaunch error: X11 initialization failed.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!x11_get_address (&address, &pid, &wid))
|
||||
{
|
||||
fprintf (stderr, "Autolaunch error: X11 communication error.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
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);
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pipe (bus_pid_to_launcher_pipe) < 0 ||
|
||||
pipe (bus_address_to_launcher_pipe) < 0)
|
||||
pipe (bus_address_to_launcher_pipe) < 0 ||
|
||||
pipe (bus_pid_to_babysitter_pipe) < 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to create pipe: %s\n",
|
||||
|
|
@ -697,9 +722,6 @@ main (int argc, char **argv)
|
|||
exit (1);
|
||||
}
|
||||
|
||||
bus_pid_to_babysitter_pipe[READ_END] = -1;
|
||||
bus_pid_to_babysitter_pipe[WRITE_END] = -1;
|
||||
|
||||
ret = fork ();
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
@ -716,17 +738,9 @@ main (int argc, char **argv)
|
|||
char write_address_fd_as_string[MAX_FD_LEN];
|
||||
|
||||
verbose ("=== Babysitter's intermediate parent created\n");
|
||||
|
||||
|
||||
/* Fork once more to create babysitter */
|
||||
|
||||
if (pipe (bus_pid_to_babysitter_pipe) < 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Failed to create pipe: %s\n",
|
||||
strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ret = fork ();
|
||||
if (ret < 0)
|
||||
{
|
||||
|
|
@ -741,6 +755,7 @@ main (int argc, char **argv)
|
|||
verbose ("=== Babysitter's intermediate parent continues\n");
|
||||
|
||||
close (bus_pid_to_launcher_pipe[READ_END]);
|
||||
close (bus_pid_to_launcher_pipe[WRITE_END]);
|
||||
close (bus_address_to_launcher_pipe[READ_END]);
|
||||
close (bus_address_to_launcher_pipe[WRITE_END]);
|
||||
close (bus_pid_to_babysitter_pipe[WRITE_END]);
|
||||
|
|
@ -750,8 +765,7 @@ main (int argc, char **argv)
|
|||
* daemon
|
||||
*/
|
||||
babysit (exit_with_session, ret,
|
||||
bus_pid_to_babysitter_pipe[READ_END],
|
||||
bus_pid_to_launcher_pipe[WRITE_END]);
|
||||
bus_pid_to_babysitter_pipe[READ_END]);
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
|
@ -763,10 +777,10 @@ main (int argc, char **argv)
|
|||
close (bus_pid_to_launcher_pipe[READ_END]);
|
||||
close (bus_address_to_launcher_pipe[READ_END]);
|
||||
close (bus_pid_to_babysitter_pipe[READ_END]);
|
||||
close (bus_pid_to_launcher_pipe[WRITE_END]);
|
||||
close (bus_pid_to_babysitter_pipe[WRITE_END]);
|
||||
|
||||
sprintf (write_pid_fd_as_string,
|
||||
"%d", bus_pid_to_babysitter_pipe[WRITE_END]);
|
||||
"%d", bus_pid_to_launcher_pipe[WRITE_END]);
|
||||
|
||||
sprintf (write_address_fd_as_string,
|
||||
"%d", bus_address_to_launcher_pipe[WRITE_END]);
|
||||
|
|
@ -809,14 +823,20 @@ main (int argc, char **argv)
|
|||
else
|
||||
{
|
||||
/* Parent */
|
||||
#define MAX_ADDR_LEN 512
|
||||
#define MAX_PID_LEN 64
|
||||
pid_t bus_pid;
|
||||
char bus_address[MAX_ADDR_LEN];
|
||||
char buf[MAX_PID_LEN];
|
||||
char *end;
|
||||
long wid = 0;
|
||||
long val;
|
||||
int ret2;
|
||||
|
||||
verbose ("=== Parent dbus-launch continues\n");
|
||||
|
||||
close (bus_pid_to_launcher_pipe[WRITE_END]);
|
||||
close (bus_address_to_launcher_pipe[WRITE_END]);
|
||||
close (bus_pid_to_babysitter_pipe[READ_END]);
|
||||
|
||||
verbose ("Waiting for babysitter's intermediate parent\n");
|
||||
|
||||
|
|
@ -851,25 +871,70 @@ main (int argc, char **argv)
|
|||
|
||||
close (bus_address_to_launcher_pipe[READ_END]);
|
||||
|
||||
verbose ("Reading PID from babysitter\n");
|
||||
|
||||
switch (read_pid (bus_pid_to_launcher_pipe[READ_END], &bus_pid))
|
||||
{
|
||||
case READ_STATUS_OK:
|
||||
break;
|
||||
case READ_STATUS_EOF:
|
||||
fprintf (stderr, "EOF in dbus-launch reading address from bus daemon\n");
|
||||
exit (1);
|
||||
break;
|
||||
case READ_STATUS_ERROR:
|
||||
fprintf (stderr, "Error in dbus-launch reading address from bus daemon: %s\n",
|
||||
strerror (errno));
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
verbose ("Reading PID from daemon\n");
|
||||
/* Now read data */
|
||||
switch (read_line (bus_pid_to_launcher_pipe[READ_END], buf, MAX_PID_LEN))
|
||||
{
|
||||
case READ_STATUS_OK:
|
||||
break;
|
||||
case READ_STATUS_EOF:
|
||||
fprintf (stderr, "EOF reading PID from bus daemon\n");
|
||||
exit (1);
|
||||
break;
|
||||
case READ_STATUS_ERROR:
|
||||
fprintf (stderr, "Error reading PID from bus daemon: %s\n",
|
||||
strerror (errno));
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
|
||||
end = NULL;
|
||||
val = strtol (buf, &end, 0);
|
||||
if (buf == end || end == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to parse bus PID \"%s\": %s\n",
|
||||
buf, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
bus_pid = val;
|
||||
|
||||
close (bus_pid_to_launcher_pipe[READ_END]);
|
||||
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
ret2 = x11_save_address (bus_address, bus_pid, &wid);
|
||||
if (ret2 == 0)
|
||||
{
|
||||
/* another window got added. Return its address */
|
||||
char *address;
|
||||
pid_t pid;
|
||||
long wid;
|
||||
|
||||
if (x11_get_address (&address, &pid, &wid) && 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);
|
||||
free (address);
|
||||
|
||||
bus_pid_to_kill = bus_pid;
|
||||
kill_bus_and_exit (0);
|
||||
}
|
||||
|
||||
/* if failed, fall through */
|
||||
}
|
||||
if (ret2 <= 0)
|
||||
{
|
||||
fprintf (stderr, "Error saving bus information.\n");
|
||||
bus_pid_to_kill = bus_pid;
|
||||
kill_bus_and_exit (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Forward the pid to the babysitter */
|
||||
write_pid (bus_pid_to_babysitter_pipe[WRITE_END], bus_pid);
|
||||
close (bus_pid_to_babysitter_pipe[WRITE_END]);
|
||||
|
||||
if (runprog)
|
||||
{
|
||||
char *envvar;
|
||||
|
|
@ -904,18 +969,8 @@ main (int argc, char **argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (c_shell_syntax)
|
||||
printf ("setenv DBUS_SESSION_BUS_ADDRESS '%s';\n", bus_address);
|
||||
else
|
||||
{
|
||||
printf ("DBUS_SESSION_BUS_ADDRESS='%s';\n", bus_address);
|
||||
if (bourne_shell_syntax)
|
||||
printf ("export DBUS_SESSION_BUS_ADDRESS;\n");
|
||||
}
|
||||
if (c_shell_syntax)
|
||||
printf ("set DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
|
||||
else
|
||||
printf ("DBUS_SESSION_BUS_PID=%ld;\n", (long) bus_pid);
|
||||
print_variables (bus_address, bus_pid, wid, c_shell_syntax,
|
||||
bourne_shell_syntax, binary_syntax);
|
||||
}
|
||||
|
||||
verbose ("dbus-launch exiting\n");
|
||||
|
|
|
|||
56
tools/dbus-launch.h
Normal file
56
tools/dbus-launch.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- mode: C; c-file-style: "gnu" -*- */
|
||||
/* dbus-launch.h dbus-launch utility
|
||||
*
|
||||
* Copyright (C) 2006 Thiago Macieira <thiago@kde.org>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DBUS_LAUNCH_H
|
||||
#define DBUS_LAUNCH_H
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define MAX_ADDR_LEN 512
|
||||
|
||||
/* defined in dbus-launch.c */
|
||||
void verbose (const char *format, ...);
|
||||
char *xstrdup (const char *str);
|
||||
void kill_bus_and_exit (int exitcode);
|
||||
|
||||
#ifdef DBUS_BUILD_X11
|
||||
/* defined in dbus-launch-x11.c */
|
||||
int x11_init (void);
|
||||
int x11_get_address (char **paddress, pid_t *pid, long *wid);
|
||||
int x11_save_address (char *address, pid_t pid, long *wid);
|
||||
void x11_handle_event (void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue