Page MenuHomeFreeBSD

D58314.id182669.diff
No OneTemporary

D58314.id182669.diff

diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1
--- 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 @@
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 @@
[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
--- a/bin/pwait/pwait.c
+++ b/bin/pwait/pwait.c
@@ -40,6 +40,7 @@
#include <sys/tree.h>
#include <sys/wait.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
@@ -68,7 +69,7 @@
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);
}
@@ -86,16 +87,17 @@
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;
@@ -103,6 +105,9 @@
case 'p':
pflag = true;
break;
+ case 'r':
+ rflag = true;
+ break;
case 't':
tflag = true;
errno = 0;
@@ -165,6 +170,9 @@
}
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 */
@@ -190,7 +198,7 @@
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()");
@@ -230,9 +238,11 @@
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",
@@ -244,13 +254,20 @@
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) {

File Metadata

Mime Type
text/plain
Expires
Sat, Aug 1, 5:08 AM (10 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35736608
Default Alt Text
D58314.id182669.diff (3 KB)

Event Timeline