2003-05-04 Havoc Pennington <hp@pobox.com>

* tools/dbus-launch.c: implement

	* bus/main.c (main), bus/bus.c (bus_context_new):
	implement --print-pid and --fork
This commit is contained in:
Havoc Pennington 2003-05-04 08:54:24 +00:00
parent c0158234d0
commit df01c98cc7
10 changed files with 824 additions and 19 deletions

View file

@ -1,3 +1,10 @@
2003-05-04 Havoc Pennington <hp@pobox.com>
* tools/dbus-launch.c: implement
* bus/main.c (main), bus/bus.c (bus_context_new):
implement --print-pid and --fork
2003-05-03 Havoc Pennington <hp@redhat.com>
* dbus/dbus-address.c (dbus_parse_address): fix bug when a key in

View file

@ -280,7 +280,9 @@ setup_server (BusContext *context,
BusContext*
bus_context_new (const DBusString *config_file,
dbus_bool_t force_fork,
int print_addr_fd,
int print_pid_fd,
DBusError *error)
{
BusContext *context;
@ -540,7 +542,7 @@ bus_context_new (const DBusString *config_file,
_dbus_assert (context->policy != NULL);
/* Now become a daemon if appropriate */
if (bus_config_parser_get_fork (parser))
if (force_fork || bus_config_parser_get_fork (parser))
{
DBusString u;
@ -567,6 +569,42 @@ bus_context_new (const DBusString *config_file,
/* keep around the pid filename so we can delete it later */
context->pidfile = _dbus_strdup (pidfile);
/* Write PID if requested */
if (print_pid_fd >= 0)
{
DBusString pid;
int bytes;
if (!_dbus_string_init (&pid))
{
BUS_SET_OOM (error);
goto failed;
}
if (!_dbus_string_append_int (&pid, _dbus_getpid ()) ||
!_dbus_string_append (&pid, "\n"))
{
_dbus_string_free (&pid);
BUS_SET_OOM (error);
goto failed;
}
bytes = _dbus_string_get_length (&pid);
if (_dbus_write (print_pid_fd, &pid, 0, bytes) != bytes)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Printing message bus PID: %s\n",
_dbus_strerror (errno));
_dbus_string_free (&pid);
goto failed;
}
if (print_pid_fd > 2)
_dbus_close (print_pid_fd, NULL);
_dbus_string_free (&pid);
}
/* Here we change our credentials if required,
* as soon as we've set up our sockets and pidfile
*/

View file

@ -57,7 +57,9 @@ typedef struct
} BusLimits;
BusContext* bus_context_new (const DBusString *config_file,
dbus_bool_t force_fork,
int print_addr_fd,
int print_pid_fd,
DBusError *error);
void bus_context_shutdown (BusContext *context);
void bus_context_ref (BusContext *context);

View file

@ -9,7 +9,7 @@ dbus-daemon-1 \- Message bus daemon
.PP
.B dbus-daemon-1
dbus-daemon-1 [\-\-version] [\-\-session] [\-\-system] [\-\-config-file=FILE]
[\-\-print-address[=DESCRIPTOR]]
[\-\-print-address[=DESCRIPTOR]] [\-\-print-pid[=DESCRIPTOR]] [\-\-fork]
.SH DESCRIPTION
@ -62,11 +62,22 @@ The following options are supported:
.I "--config-file=FILE"
Use the given configuration file.
.TP
.I "--fork"
Force the message bus to fork and become a daemon, even if
the configuration file does not specify that it should.
In most contexts the configuration file already gets this
right, though.
.TP
.I "--print-address[=DESCRIPTOR]"
Print the address of the message bus to standard output, or
to the given file descriptor. This is used by programs that
launch the message bus.
.TP
.I "--print-pid[=DESCRIPTOR]"
Print the process ID of the message bus to standard output, or
to the given file descriptor. This is used by programs that
launch the message bus.
.TP
.I "--session"
Use the standard configuration file for the per-login-session message
bus.
@ -185,7 +196,8 @@ privileges for writing.
.PP
If present, the bus daemon becomes a real daemon (forks
into the background, etc.).
into the background, etc.). This is generally used
rather than the \-\-fork command line option.
.TP
.I "<listen>"

View file

@ -47,7 +47,7 @@ signal_handler (int sig)
static void
usage (void)
{
fprintf (stderr, "dbus-daemon-1 [--version] [--session] [--system] [--config-file=FILE] [--print-address[=DESCRIPTOR]]\n");
fprintf (stderr, "dbus-daemon-1 [--version] [--session] [--system] [--config-file=FILE] [--print-address[=DESCRIPTOR]] [--print-pid[=DESCRIPTOR]] [--fork]\n");
exit (1);
}
@ -86,24 +86,45 @@ check_two_addr_descriptors (const DBusString *addr_fd,
}
}
static void
check_two_pid_descriptors (const DBusString *pid_fd,
const char *extra_arg)
{
if (_dbus_string_get_length (pid_fd) > 0)
{
fprintf (stderr, "--%s specified but printing pid to %s already requested\n",
extra_arg, _dbus_string_get_const_data (pid_fd));
exit (1);
}
}
int
main (int argc, char **argv)
{
DBusError error;
DBusString config_file;
DBusString addr_fd;
DBusString pid_fd;
const char *prev_arg;
int print_addr_fd;
int print_pid_fd;
int i;
dbus_bool_t print_address;
dbus_bool_t print_pid;
dbus_bool_t force_fork;
if (!_dbus_string_init (&config_file))
return 1;
if (!_dbus_string_init (&addr_fd))
return 1;
if (!_dbus_string_init (&pid_fd))
return 1;
print_address = FALSE;
print_pid = FALSE;
force_fork = FALSE;
prev_arg = NULL;
i = 1;
@ -117,6 +138,8 @@ main (int argc, char **argv)
usage ();
else if (strcmp (arg, "--version") == 0)
version ();
else if (strcmp (arg, "--fork") == 0)
force_fork = TRUE;
else if (strcmp (arg, "--system") == 0)
{
check_two_config_files (&config_file, "system");
@ -179,6 +202,32 @@ main (int argc, char **argv)
}
else if (strcmp (arg, "--print-address") == 0)
print_address = TRUE; /* and we'll get the next arg if appropriate */
else if (strstr (arg, "--print-pid=") == arg)
{
const char *desc;
check_two_pid_descriptors (&pid_fd, "print-pid");
desc = strchr (arg, '=');
++desc;
if (!_dbus_string_append (&pid_fd, desc))
exit (1);
print_pid = TRUE;
}
else if (prev_arg &&
strcmp (prev_arg, "--print-pid") == 0)
{
check_two_pid_descriptors (&pid_fd, "print-pid");
if (!_dbus_string_append (&pid_fd, arg))
exit (1);
print_pid = TRUE;
}
else if (strcmp (arg, "--print-pid") == 0)
print_pid = TRUE; /* and we'll get the next arg if appropriate */
else
usage ();
@ -213,9 +262,32 @@ main (int argc, char **argv)
print_addr_fd = val;
}
}
print_pid_fd = -1;
if (print_pid)
{
print_pid_fd = 1; /* stdout */
if (_dbus_string_get_length (&pid_fd) > 0)
{
long val;
int end;
if (!_dbus_string_parse_int (&pid_fd, 0, &val, &end) ||
end != _dbus_string_get_length (&pid_fd) ||
val < 0 || val > _DBUS_INT_MAX)
{
fprintf (stderr, "Invalid file descriptor: \"%s\"\n",
_dbus_string_get_const_data (&pid_fd));
exit (1);
}
print_pid_fd = val;
}
}
dbus_error_init (&error);
context = bus_context_new (&config_file, print_addr_fd, &error);
context = bus_context_new (&config_file, force_fork,
print_addr_fd, print_pid_fd,
&error);
_dbus_string_free (&config_file);
if (context == NULL)
{

View file

@ -377,7 +377,7 @@ bus_context_new_test (const DBusString *test_data_dir,
}
dbus_error_init (&error);
context = bus_context_new (&config_file, -1, &error);
context = bus_context_new (&config_file, FALSE, -1, -1, &error);
if (context == NULL)
{
_DBUS_ASSERT_ERROR_IS_SET (&error);

View file

@ -440,10 +440,6 @@ AC_SUBST(DBUS_QT_LIBS)
### X11 detection
AC_PATH_XTRA
DBUS_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
DBUS_X_CFLAGS="$X_CFLAGS"
AC_SUBST(DBUS_X_CFLAGS)
AC_SUBST(DBUS_X_LIBS)
## for now enable_x11 just tracks have_x11,
## there's no --enable-x11
@ -457,8 +453,16 @@ fi
if test x$enable_x11 = xyes ; then
AC_DEFINE(DBUS_BUILD_X11,1,[Build X11-dependent code])
DBUS_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
DBUS_X_CFLAGS="$X_CFLAGS"
else
DBUS_X_LIBS=
DBUS_X_CFLAGS=
fi
AC_SUBST(DBUS_X_CFLAGS)
AC_SUBST(DBUS_X_LIBS)
### Documentation
AC_PATH_PROG(DOXYGEN, doxygen, no)

View file

@ -19,7 +19,8 @@ dbus_launch_SOURCES= \
dbus_send_LDADD= $(top_builddir)/dbus/libdbus-1.la
dbus_monitor_LDADD= $(top_builddir)/glib/libdbus-glib-1.la
dbus_launch_LDADD= $(top_builddir)/dbus/libdbus-1.la
## dbus-launch doesn't link to anything
dbus_launch_LDADD= $(DBUS_X_LIBS)
man_MANS = dbus-send.1 dbus-monitor.1 dbus-launch.1
EXTRA_DIST = $(man_MANS)

View file

@ -24,14 +24,19 @@ about D-BUS. See also the man page for \fIdbus-daemon-1\fP.
.PP
Here is an example of how to use \fIdbus-launch\fP with an
sh-compatible shell:
sh-compatible shell to start the per-session bus daemon:
.nf
VARIABLES=`dbus-launch`
eval $VARIABLES
echo "D-BUS per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
## test for an existing bus daemon, just to be safe
if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
## if not found, launch a new one
eval `dbus-launch --exit-with-session`
echo "D-BUS per-session daemon address is: $DBUS_SESSION_BUS_ADDRESS"
export DBUS_SESSION_BUS_ADDRESS
fi
.fi
You might run something like that in your login scripts.
.SH OPTIONS
The following options are supported:

View file

@ -21,7 +21,6 @@
*
*/
#include <config.h>
#include <dbus/dbus.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
@ -30,10 +29,53 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>
#ifdef DBUS_BUILD_X11
#include <X11/Xlib.h>
#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
verbose (const char *format,
...)
{
va_list args;
static int verbose = TRUE;
static int verbose_initted = FALSE;
/* things are written a bit oddly here so that
* in the non-verbose case we just have the one
* conditional and return immediately.
*/
if (!verbose)
return;
if (!verbose_initted)
{
verbose = getenv ("DBUS_VERBOSE") != NULL;
verbose_initted = TRUE;
if (!verbose)
return;
}
fprintf (stderr, "%lu: ", (unsigned long) getpid ());
va_start (args, format);
vfprintf (stderr, format, args);
va_end (args);
}
static void
usage (void)
{
@ -52,13 +94,462 @@ version (void)
exit (0);
}
typedef enum
{
READ_STATUS_OK, /**< Read succeeded */
READ_STATUS_ERROR, /**< Some kind of error */
READ_STATUS_EOF /**< EOF returned */
} ReadStatus;
static ReadStatus
read_line (int fd,
char *buf,
size_t maxlen)
{
size_t bytes = 0;
ReadStatus retval;
memset (buf, '\0', maxlen);
maxlen -= 1; /* ensure nul term */
retval = READ_STATUS_OK;
while (TRUE)
{
size_t chunk;
size_t to_read;
again:
to_read = maxlen - bytes;
if (to_read == 0)
break;
chunk = read (fd,
buf + bytes,
to_read);
if (chunk < 0 && errno == EINTR)
goto again;
if (chunk < 0)
{
retval = READ_STATUS_ERROR;
break;
}
else if (chunk == 0)
{
retval = READ_STATUS_EOF;
break; /* EOF */
}
else /* chunk > 0 */
bytes += chunk;
}
if (retval == READ_STATUS_EOF &&
bytes > 0)
retval = READ_STATUS_OK;
/* whack newline */
if (retval != READ_STATUS_ERROR &&
bytes > 0 &&
buf[bytes-1] == '\n')
buf[bytes-1] = '\0';
return retval;
}
static ReadStatus
read_pid (int fd,
pid_t *buf)
{
size_t bytes = 0;
ReadStatus retval;
retval = READ_STATUS_OK;
while (TRUE)
{
size_t chunk;
size_t to_read;
again:
to_read = sizeof (pid_t) - bytes;
if (to_read == 0)
break;
chunk = read (fd,
((char*)buf) + bytes,
to_read);
if (chunk < 0 && errno == EINTR)
goto again;
if (chunk < 0)
{
retval = READ_STATUS_ERROR;
break;
}
else if (chunk == 0)
{
retval = READ_STATUS_EOF;
break; /* EOF */
}
else /* chunk > 0 */
bytes += chunk;
}
return retval;
}
static void
do_write (int fd, const void *buf, size_t count)
{
size_t bytes_written;
int ret;
bytes_written = 0;
again:
ret = write (fd, ((const char*)buf) + bytes_written, count - bytes_written);
if (ret < 0)
{
if (errno == EINTR)
goto again;
else
{
fprintf (stderr, "Failed to write data to pipe!\n");
exit (1); /* give up, we suck */
}
}
else
bytes_written += ret;
if (bytes_written < count)
goto again;
}
static void
write_pid (int fd,
pid_t pid)
{
do_write (fd, &pid, sizeof (pid));
}
static int
do_waitpid (pid_t pid)
{
int ret;
again:
ret = waitpid (pid, NULL, 0);
if (ret < 0 &&
errno == EINTR)
goto again;
return ret;
}
static pid_t bus_pid_to_kill = -1;
static void
kill_bus_and_exit (void)
{
verbose ("Killing message bus and exiting babysitter\n");
/* in case these point to any NFS mounts, get rid of them immediately */
close (0);
close (1);
close (2);
kill (bus_pid_to_kill, SIGTERM);
sleep (3);
kill (bus_pid_to_kill, SIGKILL);
exit (0);
}
#ifdef DBUS_BUILD_X11
static int
x_io_error_handler (Display *xdisplay)
{
verbose ("X IO error\n");
kill_bus_and_exit ();
}
#endif
static int got_sighup = FALSE;
static void
signal_handler (int sig)
{
switch (sig)
{
case SIGHUP:
got_sighup = TRUE;
break;
}
}
static void
kill_bus_when_session_ends (void)
{
int tty_fd;
int x_fd;
fd_set read_set;
fd_set err_set;
int ret;
struct sigaction act;
sigset_t empty_mask;
#ifdef DBUS_BUILD_X11
Display *xdisplay;
#endif
/* install SIGHUP handler */
got_sighup = FALSE;
sigemptyset (&empty_mask);
act.sa_handler = signal_handler;
act.sa_mask = empty_mask;
act.sa_flags = 0;
sigaction (SIGHUP, &act, 0);
#ifdef DBUS_BUILD_X11
xdisplay = XOpenDisplay (NULL);
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
if (isatty (0))
tty_fd = 0;
else
tty_fd = -1;
if (tty_fd >= 0)
verbose ("stdin isatty(), monitoring it\n");
else
verbose ("stdin was not a TTY, not monitoring it\n");
if (tty_fd < 0 && x_fd < 0)
{
fprintf (stderr, "No terminal on standard input and no X display; cannot attach message bus to session lifetime\n");
exit (1);
}
while (TRUE)
{
FD_ZERO (&read_set);
FD_ZERO (&err_set);
if (tty_fd >= 0)
{
FD_SET (tty_fd, &read_set);
FD_SET (tty_fd, &err_set);
}
if (x_fd >= 0)
{
FD_SET (x_fd, &read_set);
FD_SET (x_fd, &err_set);
}
ret = select (MAX (tty_fd, x_fd) + 1,
&read_set, NULL, &err_set, NULL);
if (got_sighup)
{
verbose ("Got SIGHUP, exiting\n");
kill_bus_and_exit ();
}
#ifdef DBUS_BUILD_X11
/* Dump events on the floor, and let
* IO error handler run if we lose
* the X connection
*/
if (x_fd >= 0)
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);
}
}
#endif
if (tty_fd >= 0)
{
if (FD_ISSET (tty_fd, &read_set))
{
int bytes_read;
char discard[512];
verbose ("TTY ready for reading\n");
bytes_read = read (tty_fd, discard, sizeof (discard));
verbose ("Read %d bytes from TTY errno = %d\n",
bytes_read, errno);
if (bytes_read == 0)
kill_bus_and_exit (); /* EOF */
else if (bytes_read < 0 && errno != EINTR)
{
/* This shouldn't happen I don't think; to avoid
* spinning on the fd forever we exit.
*/
fprintf (stderr, "dbus-launch: error reading from stdin: %s\n",
strerror (errno));
kill_bus_and_exit ();
}
}
else if (FD_ISSET (tty_fd, &err_set))
{
verbose ("TTY has error condition\n");
kill_bus_and_exit ();
}
}
}
}
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 ret;
#define MAX_PID_LEN 64
char buf[MAX_PID_LEN];
long val;
char *end;
/* We chdir ("/") since we are persistent and daemon-like, and fork
* again so dbus-launch can reap the parent. However, we don't
* setsid() or close fd 0,1,2 because the idea is to remain attached
* to the tty and the X server in order to kill the message bus
* when the session ends.
*/
if (chdir ("/") < 0)
{
fprintf (stderr, "Could not change to root directory: %s\n",
strerror (errno));
exit (1);
}
ret = fork ();
if (ret < 0)
{
fprintf (stderr, "fork() failed in babysitter: %s\n",
strerror (errno));
exit (1);
}
if (ret > 0)
{
/* Parent reaps pre-fork part of bus daemon, then exits and is
* reaped so the babysitter isn't a zombie
*/
verbose ("=== Babysitter's intermediate parent continues again\n");
if (do_waitpid (child_pid) < 0)
{
/* shouldn't happen */
fprintf (stderr, "Failed waitpid() waiting for bus daemon's parent\n");
exit (1);
}
verbose ("Babysitter's intermediate parent exiting\n");
exit (0);
}
/* 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))
{
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_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;
* we connect to X display and tty and wait to
* kill bus if requested.
*/
kill_bus_when_session_ends ();
}
verbose ("Babysitter exiting\n");
exit (0);
}
#define READ_END 0
#define WRITE_END 1
int
main (int argc, char **argv)
{
const char *prev_arg;
dbus_bool_t exit_with_session;
int exit_with_session;
int i;
int ret;
int bus_pid_to_launcher_pipe[2];
int bus_pid_to_babysitter_pipe[2];
int bus_address_to_launcher_pipe[2];
exit_with_session = FALSE;
prev_arg = NULL;
@ -82,8 +573,181 @@ main (int argc, char **argv)
++i;
}
verbose ("--exit-with-session provided\n");
if (pipe (bus_pid_to_launcher_pipe) < 0 ||
pipe (bus_address_to_launcher_pipe) < 0)
{
fprintf (stderr,
"Failed to create pipe: %s\n",
strerror (errno));
exit (1);
}
bus_pid_to_babysitter_pipe[READ_END] = -1;
bus_pid_to_babysitter_pipe[WRITE_END] = -1;
ret = fork ();
if (ret < 0)
{
fprintf (stderr, "Failed to fork: %s\n",
strerror (errno));
exit (1);
}
if (ret == 0)
{
/* Child */
#define MAX_FD_LEN 64
char write_pid_fd_as_string[MAX_FD_LEN];
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)
{
fprintf (stderr, "Failed to fork: %s\n",
strerror (errno));
exit (1);
}
if (ret > 0)
{
/* In babysitter */
verbose ("=== Babysitter's intermediate parent continues\n");
close (bus_pid_to_launcher_pipe[READ_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]);
/* babysit() will fork *again*
* and will also reap the pre-forked bus
* daemon
*/
babysit (exit_with_session, ret,
bus_pid_to_babysitter_pipe[READ_END],
bus_pid_to_launcher_pipe[WRITE_END]);
exit (0);
}
verbose ("=== Bus exec process created\n");
/* Now we are the bus process (well, almost;
* dbus-daemon-1 itself forks again)
*/
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]);
sprintf (write_pid_fd_as_string,
"%d", bus_pid_to_babysitter_pipe[WRITE_END]);
sprintf (write_address_fd_as_string,
"%d", bus_address_to_launcher_pipe[WRITE_END]);
verbose ("Calling exec()\n");
execlp ("dbus-daemon-1",
"dbus-daemon-1",
"--fork",
"--session",
"--print-pid", write_pid_fd_as_string,
"--print-address", write_address_fd_as_string,
NULL);
fprintf (stderr,
"Failed to execute message bus daemon: %s\n",
strerror (errno));
exit (1);
}
else
{
/* Parent */
#define MAX_ADDR_LEN 512
pid_t bus_pid;
char bus_address[MAX_ADDR_LEN];
verbose ("=== Parent dbus-launch continues\n");
close (bus_pid_to_launcher_pipe[WRITE_END]);
close (bus_address_to_launcher_pipe[WRITE_END]);
verbose ("Waiting for babysitter's intermediate parent\n");
/* Immediately reap parent of babysitter
* (which was created just for us to reap)
*/
if (do_waitpid (ret) < 0)
{
fprintf (stderr, "Failed to waitpid() for babysitter intermediate process: %s\n",
strerror (errno));
exit (1);
}
verbose ("Reading address from bus\n");
/* Read the pipe data, print, and exit */
switch (read_line (bus_address_to_launcher_pipe[READ_END],
bus_address, MAX_ADDR_LEN))
{
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;
}
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;
}
close (bus_pid_to_launcher_pipe[READ_END]);
printf ("DBUS_SESSION_BUS_ADDRESS='%s'\n",
bus_address);
printf ("DBUS_SESSION_BUS_PID=%ld\n",
(long) bus_pid);
verbose ("dbus-launch exiting\n");
exit (0);
}
return 0;
}