From d5276eb5877d278ed35659e8e834cbc47a83c8ae Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 11 Sep 2014 10:59:32 +0100 Subject: [PATCH] dbus-spawn: do not forget the exec() errno when the grandchild exits As is already noted in a comment in _dbus_babysitter_set_child_exit_error(), if the grandchild fails to exec() the desired process, we get both CHILD_EXEC_FAILED (with an errno) and CHILD_EXITED (with a status), and we want to report the former, since it is more informative. However, clearing sitter->errnum meant we lose the errno value. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=24821 --- dbus/dbus-spawn.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/dbus/dbus-spawn.c b/dbus/dbus-spawn.c index b95cad6..dd01130 100644 --- a/dbus/dbus-spawn.c +++ b/dbus/dbus-spawn.c @@ -454,9 +454,25 @@ read_data (DBusBabysitter *sitter, { if (what == CHILD_EXITED) { + /* Do not reset sitter->errnum to 0 here. We get here if + * the babysitter reports that the grandchild process has + * exited, and there are two ways that can happen: + * + * 1. grandchild successfully exec()s the desired process, + * but then the desired process exits or is terminated + * by a signal. The babysitter observes this and reports + * CHILD_EXITED. + * + * 2. grandchild fails to exec() the desired process, + * attempts to report the exec() failure (which + * we will receive as CHILD_EXEC_FAILED), and then + * exits itself (which will prompt the babysitter to + * send CHILD_EXITED). We want the CHILD_EXEC_FAILED + * to take precedence (and have its errno logged), + * which _dbus_babysitter_set_child_exit_error() does. + */ sitter->have_child_status = TRUE; sitter->status = arg; - sitter->errnum = 0; _dbus_verbose ("recorded child status exited = %d signaled = %d exitstatus = %d termsig = %d\n", WIFEXITED (sitter->status), WIFSIGNALED (sitter->status), WEXITSTATUS (sitter->status), WTERMSIG (sitter->status)); -- 2.1.0