]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
dbus-spawn: do not forget the exec() errno when the grandchild exits
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Thu, 11 Sep 2014 09:59:32 +0000 (10:59 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 29 Oct 2014 14:16:58 +0000 (14:16 +0000)
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
Reviewed-by: Ross Lagerwall
dbus/dbus-spawn.c

index b95cad6e3fb4b82e936cb6dfa567943b2b903b19..dd011302478de41d0757f2b8b0b4a040faf11002 100644 (file)
@@ -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));