From 163555c7ab56132ee27e3e7d9a26eb985682c1b5 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 17 Aug 2007 16:43:57 +0000 Subject: 2007-08-17 Havoc Pennington * tools/dbus-launch-x11.c (set_address_in_x11): fix from Michael Lorenz to use long not int with XChangeProperty format 32 * dbus/dbus-sysdeps-util-unix.c (_dbus_write_pid_to_file_and_pipe): factor this out, and use the same code in _dbus_become_daemon (where the parent writes the pid file and to the pid pipe) and in bus_context_new (where the daemon writes its own pid file and to its own pid pipe) * bus/bus.c (bus_context_new): close the pid pipe after we print to it. Also, don't write the pid to the pipe twice when we fork, someone reported this bug a long time ago. --- dbus/dbus-sysdeps-util-unix.c | 144 ++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 53 deletions(-) (limited to 'dbus/dbus-sysdeps-util-unix.c') diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c index 38b7b756..df967a38 100644 --- a/dbus/dbus-sysdeps-util-unix.c +++ b/dbus/dbus-sysdeps-util-unix.c @@ -62,6 +62,7 @@ * @{ */ + /** * Does the chdir, fork, setsid, etc. to become a daemon process. * @@ -123,68 +124,27 @@ _dbus_become_daemon (const DBusString *pidfile, /* Get a predictable umask */ _dbus_verbose ("setting umask\n"); umask (022); + + _dbus_verbose ("calling setsid()\n"); + if (setsid () == -1) + _dbus_assert_not_reached ("setsid() failed"); + break; default: - if (pidfile) + if (!_dbus_write_pid_to_file_and_pipe (pidfile, print_pid_pipe, + child_pid, error)) { - _dbus_verbose ("parent writing pid file\n"); - if (!_dbus_write_pid_file (pidfile, - child_pid, - error)) - { - _dbus_verbose ("pid file write failed, killing child\n"); - kill (child_pid, SIGTERM); - return FALSE; - } + _dbus_verbose ("pid file or pipe write failed: %s\n", + error->message); + kill (child_pid, SIGTERM); + return FALSE; } - /* Write PID if requested */ - if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe)) - { - DBusString pid; - int bytes; - - if (!_dbus_string_init (&pid)) - { - _DBUS_SET_OOM (error); - kill (child_pid, SIGTERM); - return FALSE; - } - - if (!_dbus_string_append_int (&pid, child_pid) || - !_dbus_string_append (&pid, "\n")) - { - _dbus_string_free (&pid); - _DBUS_SET_OOM (error); - kill (child_pid, SIGTERM); - return FALSE; - } - - bytes = _dbus_string_get_length (&pid); - if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes) - { - /* _dbus_pipe_write sets error only on failure, not short write */ - if (error != NULL && !dbus_error_is_set(error)) - { - dbus_set_error (error, DBUS_ERROR_FAILED, - "Printing message bus PID: did not write enough bytes\n"); - } - _dbus_string_free (&pid); - kill (child_pid, SIGTERM); - return FALSE; - } - - _dbus_string_free (&pid); - } _dbus_verbose ("parent exiting\n"); _exit (0); break; } - - _dbus_verbose ("calling setsid()\n"); - if (setsid () == -1) - _dbus_assert_not_reached ("setsid() failed"); return TRUE; } @@ -198,7 +158,7 @@ _dbus_become_daemon (const DBusString *pidfile, * @param error return location for errors * @returns #FALSE on failure */ -dbus_bool_t +static dbus_bool_t _dbus_write_pid_file (const DBusString *filename, unsigned long pid, DBusError *error) @@ -248,6 +208,84 @@ _dbus_write_pid_file (const DBusString *filename, return TRUE; } +/** + * Writes the given pid_to_write to a pidfile (if non-NULL) and/or to a + * pipe (if non-NULL). Does nothing if pidfile and print_pid_pipe are both + * NULL. + * + * @param pidfile the file to write to or #NULL + * @param print_pid_pipe the pipe to write to or #NULL + * @param pid_to_write the pid to write out + * @param error error on failure + * @returns FALSE if error is set + */ +dbus_bool_t +_dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + dbus_pid_t pid_to_write, + DBusError *error) +{ + if (pidfile) + { + _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile)); + if (!_dbus_write_pid_file (pidfile, + pid_to_write, + error)) + { + _dbus_verbose ("pid file write failed\n"); + _DBUS_ASSERT_ERROR_IS_SET(error); + return FALSE; + } + } + else + { + _dbus_verbose ("No pid file requested\n"); + } + + if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe)) + { + DBusString pid; + int bytes; + + _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle); + + if (!_dbus_string_init (&pid)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!_dbus_string_append_int (&pid, pid_to_write) || + !_dbus_string_append (&pid, "\n")) + { + _dbus_string_free (&pid); + _DBUS_SET_OOM (error); + return FALSE; + } + + bytes = _dbus_string_get_length (&pid); + if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes) + { + /* _dbus_pipe_write sets error only on failure, not short write */ + if (error != NULL && !dbus_error_is_set(error)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Printing message bus PID: did not write enough bytes\n"); + } + _dbus_string_free (&pid); + return FALSE; + } + + _dbus_string_free (&pid); + } + else + { + _dbus_verbose ("No pid pipe to write to\n"); + } + + return TRUE; +} + /** * Verify that after the fork we can successfully change to this user. * -- cgit