From owner-svn-src-all@FreeBSD.ORG Sun Feb 15 20:10:54 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BCAB16D9; Sun, 15 Feb 2015 20:10:54 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8DBF991; Sun, 15 Feb 2015 20:10:54 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1FKAshl028441; Sun, 15 Feb 2015 20:10:54 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1FKAspg028440; Sun, 15 Feb 2015 20:10:54 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <201502152010.t1FKAspg028440@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Sun, 15 Feb 2015 20:10:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r278810 - head/usr.bin/timeout X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Feb 2015 20:10:54 -0000 Author: emaste Date: Sun Feb 15 20:10:53 2015 New Revision: 278810 URL: https://svnweb.freebsd.org/changeset/base/278810 Log: timeout: handle zombie grandchildren timeout previously collected only one child status with wait(2). If this was one of the grandchildren timeout would return to sigsuspend and wait until the timeout expired. Instead, loop for all children. PR: kern/197608 Reviewed by: bapt, kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Modified: head/usr.bin/timeout/timeout.c Modified: head/usr.bin/timeout/timeout.c ============================================================================== --- head/usr.bin/timeout/timeout.c Sun Feb 15 20:03:42 2015 (r278809) +++ head/usr.bin/timeout/timeout.c Sun Feb 15 20:10:53 2015 (r278810) @@ -172,6 +172,7 @@ main(int argc, char **argv) double second_kill; bool timedout = false; bool do_second_kill = false; + bool child_done = false; struct sigaction signals; struct procctl_reaper_status info; struct procctl_reaper_kill killemall; @@ -187,7 +188,6 @@ main(int argc, char **argv) foreground = preserve = 0; second_kill = 0; - cpid = -1; const struct option longopts[] = { { "preserve-status", no_argument, &preserve, 1 }, @@ -281,20 +281,26 @@ main(int argc, char **argv) if (sig_chld) { sig_chld = 0; - while (((cpid = wait(&status)) < 0) && errno == EINTR) - continue; - if (cpid == pid) { - pstat = status; - if (!foreground) - break; + while ((cpid = waitpid(-1, &status, WNOHANG)) != 0) { + if (cpid < 0) { + if (errno == EINTR) + continue; + else + break; + } else if (cpid == pid) { + pstat = status; + child_done = true; + } } - if (!foreground) { - procctl(P_PID, getpid(), PROC_REAP_STATUS, - &info); - if (info.rs_children == 0) { - cpid = pid; + if (child_done) { + if (foreground) { break; + } else { + procctl(P_PID, getpid(), + PROC_REAP_STATUS, &info); + if (info.rs_children == 0) + break; } } } else if (sig_alrm) { @@ -336,7 +342,7 @@ main(int argc, char **argv) } } - while (cpid != pid && wait(&pstat) == -1) { + while (!child_done && wait(&pstat) == -1) { if (errno != EINTR) err(EX_OSERR, "waitpid()"); }