_dbus_babysitter_unref: avoid infinite loop if waitpid() returns EINTR
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Wed, 4 Sep 2013 16:53:23 +0000 (17:53 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Thu, 5 Sep 2013 15:31:13 +0000 (16:31 +0100)
If waitpid() failed with EINTR, we'd go back for another go, but
because ret is nonzero, we'd skip the waitpid() and just keep looping.

Also avoid an unnecessary "goto" in favour of a proper loop, to make it
more clearly correct.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68945
Reviewed-by: Colin Walters <walters@verbum.org>
dbus/dbus-spawn.c

index ef00801..6e42f55 100644 (file)
@@ -308,15 +308,18 @@ _dbus_babysitter_unref (DBusBabysitter *sitter)
           if (ret == 0)
             kill (sitter->sitter_pid, SIGKILL);
 
-        again:
           if (ret == 0)
-            ret = waitpid (sitter->sitter_pid, &status, 0);
+            {
+              do
+                {
+                  ret = waitpid (sitter->sitter_pid, &status, 0);
+                }
+              while (_DBUS_UNLIKELY (ret < 0 && errno == EINTR));
+            }
 
           if (ret < 0)
             {
-              if (errno == EINTR)
-                goto again;
-              else if (errno == ECHILD)
+              if (errno == ECHILD)
                 _dbus_warn ("Babysitter process not available to be reaped; should not happen\n");
               else
                 _dbus_warn ("Unexpected error %d in waitpid() for babysitter: %s\n",