From nobody Mon Aug 3 11:38:40 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hDF750WNCz6nCH7 for ; Mon, 03 Aug 2026 11:38:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hDF743c42z3RpP for ; Mon, 03 Aug 2026 11:38:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785757120; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fyRoM1kJiE5m8shaxpOiTm4rvVl5yT8OyDRts+Xtag0=; b=te145kQG85NMa6QgtA7dK9cyvdGw5cAoyDDLAUeaVAspqh32g7oQVGHZNETGLiuKcyBrmA Lm7IB0302hCrjfzxTjCFY9YLd08aHz1AGJ/nIYqu++WWutgIAoIcD2Sky75HRRV+mbjSYJ /Fc17HCjRCfyXCrHifOgDeslft3pLDy76zBmRBb1bg6kOw/a98hH7ZCrAANJq1k9PBEhrl 0Tmjq+Jnb9sfuX/INXUYrXj+9Rh7AY6alGuy9sleAuUeqWZmXp92OLsAbKjIgKlrBBOng3 ZZSB9DIkZKi8xxOpFioeGK9pbzRUyUqv/ZuXcn1E328l34QZ75P6YOlI99JhxA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785757120; a=rsa-sha256; cv=none; b=CtbMCgH6AMnYvaKpnfN5hSdKbnEWF96mDkfEPLOHrJuZZSjKNAjLwXnZbp/B6tUhYXtzVf rStLP2c2q58oW2rqk9Fgs4WEqWuVBsJkmEuommv6O8W2q7S7E86GHrZeEn5pdzIm8xXiso EJnqi1fUtLXKKxxKAJg6BfGazGHEkGVSjNuZxAPJOmjZVq9n3IXHtKEtrmaBsNWQ+OKJXj 0Wfg3i8myG+nWdiREzyVEQ0ODo1w6t7CMI/AHoL9xN/lqWirfFZZR72Fh6YQY39/baBFA9 Z0TwKmx5SfiAkB6Ybpa7Txy5G/Om4DAd3Ccjm8z4PagGIXEYowyXPFXYry1obQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785757120; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fyRoM1kJiE5m8shaxpOiTm4rvVl5yT8OyDRts+Xtag0=; b=M1S751UUKdFG1DiDl6S9CiHm0E+CWzIHjRLlaaZTJKlP62OPOsKWA7UQvEMM7Nh5bvRRS9 JNh1veP4+oQVHnyFL8AxgKOMbLN1od3DQ5ZTiquW3luaH6dzyBwWa4HdxF38JotIYmyFXD cx3a1TlYNSF5qvqU6ktR5+Mx/G917zBTArTbmaDqmaSf0vezGOspL7gnRvDhDozA2t4xBH gWoD8ojxGq69EPF3LbEMm+8g7WTEpIoCHO3cF97sCOOikI2gz37vZg/Fa5dedKCntGp2iF bf0UxfFGsDhcI4sXFeJmrziSIrMTOTUvNdvevxLtdQMDi03UJuMHOuFqC0h5HQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hDF742RBnzypm for ; Mon, 03 Aug 2026 11:38:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 19624 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 03 Aug 2026 11:38:40 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav Subject: git: 600d57daeaec - stable/15 - pwait: Optionally wait until process is reaped List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 600d57daeaec22c3b459a2a894e30ceca1a9c4cb Auto-Submitted: auto-generated Date: Mon, 03 Aug 2026 11:38:40 +0000 Message-Id: <6a707dc0.19624.36442487@gitrepo.freebsd.org> The branch stable/15 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=600d57daeaec22c3b459a2a894e30ceca1a9c4cb commit 600d57daeaec22c3b459a2a894e30ceca1a9c4cb Author: Dag-Erling Smørgrav AuthorDate: 2026-07-27 10:15:31 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2026-08-03 11:32:12 +0000 pwait: Optionally wait until process is reaped If the new -r option is specified, wait until the target process not only terminates but is reaped. MFC after: 1 week Sponsored by: Klara, Inc. Sponsored by: NetApp, Inc. Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D58314 (cherry picked from commit c8f5e6819d4d81906c4a1641b5c9f02d8730481c) --- bin/pwait/pwait.1 | 17 ++++++++++++++--- bin/pwait/pwait.c | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1 index d92b829b1d6a..2776d3439a31 100644 --- a/bin/pwait/pwait.1 +++ b/bin/pwait/pwait.1 @@ -30,7 +30,7 @@ .\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY .\" OF SUCH DAMAGE. .\" -.Dd October 22, 2025 +.Dd July 22, 2026 .Dt PWAIT 1 .Os .Sh NAME @@ -39,7 +39,7 @@ .Sh SYNOPSIS .Nm .Op Fl t Ar duration -.Op Fl opv +.Op Fl oprv .Ar pid \&... .Sh DESCRIPTION @@ -53,6 +53,17 @@ The following option is available: Exit when any of the given processes has terminated. .It Fl p On exit, print a list of processes that have not terminated. +.It Fl r +Do not exit until target processes have not only terminated, but been +reaped by a call to the +.Xr wait 2 +family of functions. +Without this flag, target processes may still exist as zombies when +.Nm +exits. +Beware of deadlocks if a target process's reaper (usually its parent) +is directly or indirectly blocked by +.Nm . .It Fl t Ar duration If any process is still running after .Ar duration , @@ -127,8 +138,8 @@ $ sleep 30 & sleep 40 & [2] 1675 $ pwait -v -t 60 1674 1675 1674: exited with status 0. -1675: exited with status 0. [1]- Done sleep 30 +1675: exited with status 0. [2]+ Done sleep 40 $ echo $? 0 diff --git a/bin/pwait/pwait.c b/bin/pwait/pwait.c index 59bf0eb93ced..34aa2b8f53ec 100644 --- a/bin/pwait/pwait.c +++ b/bin/pwait/pwait.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -66,7 +67,7 @@ RB_GENERATE_STATIC(pidtree, pid, entry, pidcmp); static void usage(void) { - fprintf(stderr, "usage: pwait [-t timeout] [-opv] pid ...\n"); + fprintf(stderr, "usage: pwait [-oprv] [-t timeout] pid ...\n"); exit(EX_USAGE); } @@ -84,16 +85,17 @@ main(int argc, char *argv[]) size_t sz; long pid; pid_t mypid; - int i, kq, n, ndone, nleft, opt, pid_max, ret, status; - bool oflag, pflag, tflag, verbose; + int i, kq, n, ndone, nleft, notes, opt, pid_max, ret, status; + bool oflag, pflag, rflag, tflag, verbose; oflag = false; pflag = false; + rflag = false; tflag = false; verbose = false; memset(&itv, 0, sizeof(itv)); - while ((opt = getopt(argc, argv, "opt:v")) != -1) { + while ((opt = getopt(argc, argv, "oprt:v")) != -1) { switch (opt) { case 'o': oflag = true; @@ -101,6 +103,9 @@ main(int argc, char *argv[]) case 'p': pflag = true; break; + case 'r': + rflag = true; + break; case 't': tflag = true; errno = 0; @@ -163,6 +168,9 @@ main(int argc, char *argv[]) } ndone = nleft = 0; mypid = getpid(); + notes = rflag ? NOTE_REAP : NOTE_EXIT; + if (verbose) + notes |= NOTE_EXIT; for (n = 0; n < argc; n++) { s = argv[n]; /* Undocumented Solaris compat */ @@ -188,7 +196,7 @@ main(int argc, char *argv[]) free(p); continue; } - EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); + EV_SET(e + nleft, pid, EVFILT_PROC, EV_ADD, notes, 0, NULL); if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) { if (errno != ESRCH) err(EX_OSERR, "kevent()"); @@ -228,9 +236,11 @@ main(int argc, char *argv[]) printf("timeout\n"); } ret = 124; + continue; } + assert(e[i].filter == EVFILT_PROC); pid = e[i].ident; - if (verbose) { + if ((e[i].fflags & NOTE_EXIT) && verbose) { status = e[i].data; if (WIFEXITED(status)) { printf("%ld: exited with status %d.\n", @@ -242,13 +252,20 @@ main(int argc, char *argv[]) printf("%ld: terminated.\n", pid); } } - k.pid = pid; - if ((p = RB_FIND(pidtree, &pids, &k)) != NULL) { - RB_REMOVE(pidtree, &pids, p); - free(p); - ndone++; + if ((e[i].fflags & NOTE_REAP) && verbose) { + printf("%ld: reaped.\n", pid); + } + if ((e[i].fflags & NOTE_REAP) || + (!rflag && (e[i].fflags & NOTE_EXIT))) { + /* this process is done */ + k.pid = pid; + if ((p = RB_FIND(pidtree, &pids, &k)) != NULL) { + RB_REMOVE(pidtree, &pids, p); + free(p); + ndone++; + } + --nleft; } - --nleft; } } if (pflag) {