diff options
author | Thiago Macieira <thiago@kde.org> | 2007-03-03 10:36:46 +0000 |
---|---|---|
committer | Thiago Macieira <thiago@kde.org> | 2007-03-03 10:36:46 +0000 |
commit | 4ceb86d29a68ebe52b20c8c090bc90c68a58f8c8 (patch) | |
tree | 78657dc8500feea09a71e25688fc14b073a68b14 | |
parent | aa2f74f551b00158baaaf2031a986639f593942b (diff) |
* dbus/dbus-sysdeps-unix.c: capture the dbus-launch stderr
output and add it to the DBusError message we return.
* tools/dbus-launch.1:
* tools/dbus-launch.c: Add option --close-stderr to, well,
close stderr before starting dbus-daemon.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-unix.c | 53 | ||||
-rw-r--r-- | tools/dbus-launch.1 | 7 | ||||
-rw-r--r-- | tools/dbus-launch.c | 31 |
4 files changed, 92 insertions, 8 deletions
@@ -1,3 +1,12 @@ +2007-03-03 Thiago Macieira <thiago@kde.org> + + * dbus/dbus-sysdeps-unix.c: capture the dbus-launch stderr + output and add it to the DBusError message we return. + + * tools/dbus-launch.1: + * tools/dbus-launch.c: Add option --close-stderr to, well, + close stderr before starting dbus-daemon. + 2007-01-31 Havoc Pennington <hp@redhat.com> * bus/dbus-daemon.1.in: write a section in the man page on running diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 26fa5f94..ebb269c1 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2434,8 +2434,9 @@ dbus_bool_t _dbus_get_autolaunch_address (DBusString *address, DBusError *error) { - static char *argv[5]; - int address_pipe[2]; + static char *argv[6]; + int address_pipe[2] = { -1, -1 }; + int errors_pipe[2] = { -1, -1 }; pid_t pid; int ret; int status; @@ -2464,6 +2465,8 @@ _dbus_get_autolaunch_address (DBusString *address, ++i; argv[i] = "--binary-syntax"; ++i; + argv[i] = "--close-stderr"; + ++i; argv[i] = NULL; ++i; @@ -2482,6 +2485,15 @@ _dbus_get_autolaunch_address (DBusString *address, _dbus_strerror (errno)); goto out; } + if (pipe (errors_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)); + goto out; + } pid = fork (); if (pid < 0) @@ -2504,6 +2516,7 @@ _dbus_get_autolaunch_address (DBusString *address, /* set-up stdXXX */ close (address_pipe[READ_END]); + close (errors_pipe[READ_END]); close (0); /* close stdin */ close (1); /* close stdout */ close (2); /* close stderr */ @@ -2512,11 +2525,12 @@ _dbus_get_autolaunch_address (DBusString *address, _exit (1); if (dup2 (address_pipe[WRITE_END], 1) == -1) _exit (1); - if (dup2 (fd, 2) == -1) + if (dup2 (errors_pipe[WRITE_END], 2) == -1) _exit (1); close (fd); close (address_pipe[WRITE_END]); + close (errors_pipe[WRITE_END]); execv (DBUS_BINDIR "/dbus-launch", argv); @@ -2529,6 +2543,10 @@ _dbus_get_autolaunch_address (DBusString *address, /* parent process */ close (address_pipe[WRITE_END]); + close (errors_pipe[WRITE_END]); + address_pipe[WRITE_END] = -1; + errors_pipe[WRITE_END] = -1; + ret = 0; do { @@ -2549,9 +2567,23 @@ _dbus_get_autolaunch_address (DBusString *address, _dbus_string_get_length (address) == orig_len) { /* The process ended with error */ + DBusString error_message; + _dbus_string_init (&error_message); + ret = 0; + do + { + ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); + } + while (ret > 0); + _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"); + if (_dbus_string_get_length (&error_message) > 0) + dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, + "dbus-launch failed to autolaunch D-Bus session: %s", + _dbus_string_get_data (&error_message)); + else + dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, + "Failed to execute dbus-launch to autolaunch D-Bus session"); goto out; } @@ -2562,7 +2594,16 @@ _dbus_get_autolaunch_address (DBusString *address, _DBUS_ASSERT_ERROR_IS_CLEAR (error); else _DBUS_ASSERT_ERROR_IS_SET (error); - + + if (address_pipe[0] != -1) + close (address_pipe[0]); + if (address_pipe[1] != -1) + close (address_pipe[1]); + if (errors_pipe[0] != -1) + close (errors_pipe[0]); + if (errors_pipe[1] != -1) + close (errors_pipe[1]); + _dbus_string_free (&uuid); return retval; } diff --git a/tools/dbus-launch.1 b/tools/dbus-launch.1 index 68adb2ca..0ea19495 100644 --- a/tools/dbus-launch.1 +++ b/tools/dbus-launch.1 @@ -136,6 +136,13 @@ 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 "--close-stderr" +Close the standard error output stream before starting the D-Bus +daemon. This is useful if you want to capture dbus-launch error +messages but you don't want dbus-daemon to keep the stream open to +your application. + +.TP .I "--config-file=FILENAME" Pass \-\-config-file=FILENAME to the bus daemon, instead of passing it the \-\-session argument. See the man page for dbus-daemon diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c index 7e53e7e2..d3072782 100644 --- a/tools/dbus-launch.c +++ b/tools/dbus-launch.c @@ -596,6 +596,27 @@ babysit (int exit_with_session, exit (0); } +static void do_close_stderr (void) +{ + fflush (stderr); + + /* dbus-launch is a Unix-only program, so we can rely on /dev/null being there. + * We're including unistd.h and we're dealing with sh/csh launch sequences... + */ + int fd = open ("/dev/null", O_RDWR); + if (fd == -1) + { + fprintf (stderr, "Internal error: cannot open /dev/null: %s", strerror (errno)); + exit (1); + } + + close (2); + if (dup2 (fd, 2) == -1) + // error; we can't report an error anymore... + exit (1); + close (fd); +} + #define READ_END 0 #define WRITE_END 1 @@ -613,7 +634,8 @@ main (int argc, char **argv) int auto_shell_syntax = FALSE; int autolaunch = FALSE; int requires_arg = FALSE; - int i; + int close_stderr = FALSE; + int i; int ret; int bus_pid_to_launcher_pipe[2]; int bus_pid_to_babysitter_pipe[2]; @@ -647,6 +669,8 @@ main (int argc, char **argv) version (); else if (strcmp (arg, "--exit-with-session") == 0) exit_with_session = TRUE; + else if (strcmp (arg, "--close-stderr") == 0) + close_stderr = TRUE; else if (strstr (arg, "--autolaunch=") == arg) { const char *s; @@ -837,6 +861,9 @@ main (int argc, char **argv) char write_pid_fd_as_string[MAX_FD_LEN]; char write_address_fd_as_string[MAX_FD_LEN]; + if (close_stderr) + do_close_stderr (); + verbose ("=== Babysitter's intermediate parent created\n"); /* Fork once more to create babysitter */ @@ -859,7 +886,7 @@ main (int argc, char **argv) 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 |