git: eddd8aa99ca8 - main - pwait: Add a SIGINFO handler

Dag-Erling Smørgrav <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=eddd8aa99ca84c85faea5761af800b5b089d6ba1

commit eddd8aa99ca84c85faea5761af800b5b089d6ba1
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-07-27 10:15:36 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-07-27 10:15:36 +0000

    pwait: Add a SIGINFO handler
    
    On SIGINFO, print a space-separated list or remaining processes to
    standard error.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Sponsored by:   NetApp, Inc.
    Reviewed by:    kib, markj
    Differential Revision:  https://reviews.freebsd.org/D58386
---
 bin/pwait/pwait.1 | 13 +++++++++++++
 bin/pwait/pwait.c | 36 +++++++++++++++++++++++++++++-------
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1
index 2776d3439a31..4bd43257a82b 100644
--- a/bin/pwait/pwait.1
+++ b/bin/pwait/pwait.1
@@ -88,6 +88,18 @@ Print the exit status when each process terminates or
 .Ql timeout
 if the timer goes off earlier.
 .El
+.Pp
+If
+.Nm
+receives
+.Dv SIGINFO
+(see the
+.Sy status
+argument for
+.Xr stty 1 )
+signal,
+a space-separated list of processes still being waited on is printed
+to the standard error output.
 .Sh EXIT STATUS
 The
 .Nm
@@ -148,6 +160,7 @@ $ echo $?
 .Xr kill 1 ,
 .Xr pkill 1 ,
 .Xr ps 1 ,
+.Xr stty 1 ,
 .Xr wait 1 ,
 .Xr kqueue 2
 .Sh NOTES
diff --git a/bin/pwait/pwait.c b/bin/pwait/pwait.c
index 36c6644f5474..a58dfbbcce4d 100644
--- a/bin/pwait/pwait.c
+++ b/bin/pwait/pwait.c
@@ -87,7 +87,7 @@ main(int argc, char *argv[])
 	size_t sz;
 	long pid;
 	pid_t mypid;
-	int i, kq, n, ndone, nleft, notes, opt, pid_max, ret, status;
+	int i, kq, n, ndone, nev, nleft, notes, opt, pid_max, ret, status;
 	bool oflag, pflag, rflag, tflag, verbose;
 
 	oflag = false;
@@ -165,10 +165,10 @@ main(int argc, char *argv[])
 	if (sysctlbyname("kern.pid_max", &pid_max, &sz, NULL, 0) != 0) {
 		pid_max = 99999;
 	}
-	if ((e = malloc((argc + tflag) * sizeof(*e))) == NULL) {
+	if ((e = malloc((argc + 1 + tflag) * sizeof(*e))) == NULL) {
 		err(EX_OSERR, "malloc");
 	}
-	ndone = nleft = 0;
+	ndone = nev = nleft = 0;
 	mypid = getpid();
 	notes = rflag ? NOTE_REAP : NOTE_EXIT;
 	if (verbose)
@@ -208,18 +208,28 @@ main(int argc, char *argv[])
 			ndone++;
 		} else {
 			nleft++;
+			nev++;
 		}
 	}
 
+	/*
+	 * Detect SIGINFO so we can print a status.
+	 */
+	EV_SET(e + nev, SIGINFO, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
+	if (kevent(kq, e + nev, 1, NULL, 0, NULL) == -1) {
+		err(EX_OSERR, "kevent");
+	}
+	nev++;
 	if ((ndone == 0 || !oflag) && nleft > 0 && tflag) {
 		/*
 		 * Explicitly detect SIGALRM so that an exit status of 124
 		 * can be returned rather than 142.
 		 */
-		EV_SET(e + nleft, SIGALRM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
-		if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1) {
+		EV_SET(e + nev, SIGALRM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL);
+		if (kevent(kq, e + nev, 1, NULL, 0, NULL) == -1) {
 			err(EX_OSERR, "kevent");
 		}
+		nev++;
 		/* Ignore SIGALRM to not interrupt kevent(2). */
 		signal(SIGALRM, SIG_IGN);
 		if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
@@ -227,13 +237,25 @@ main(int argc, char *argv[])
 		}
 	}
 	ret = EX_OK;
+	setvbuf(stderr, NULL, _IOLBF, 0);
 	while ((ndone == 0 || !oflag) && ret == EX_OK && nleft > 0) {
-		n = kevent(kq, NULL, 0, e, nleft + tflag, NULL);
+		n = kevent(kq, NULL, 0, e, nev, NULL);
 		if (n == -1) {
 			err(EX_OSERR, "kevent");
 		}
 		for (i = 0; i < n; i++) {
-			if (e[i].filter == EVFILT_SIGNAL) {
+			if (e[i].filter == EVFILT_SIGNAL &&
+			    e[i].ident == SIGINFO) {
+				p = RB_MIN(pidtree, &pids);
+				fprintf(stderr, "%d", p->pid);
+				while ((p = RB_NEXT(pidtree, &pids, p)) != NULL) {
+					fprintf(stderr, " %d", p->pid);
+				}
+				fprintf(stderr, "\n");
+				continue;
+			}
+			if (e[i].filter == EVFILT_SIGNAL &&
+			    e[i].ident == SIGALRM) {
 				if (verbose) {
 					printf("timeout\n");
 				}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.