diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-07-27 10:15:36 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-07-27 10:15:36 +0000 |
| commit | eddd8aa99ca84c85faea5761af800b5b089d6ba1 (patch) | |
| tree | ac8db8dcf6cd20bb973bc0e0c76e0d678e675b62 | |
| parent | c8f5e6819d4d81906c4a1641b5c9f02d8730481c (diff) | |
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
| -rw-r--r-- | bin/pwait/pwait.1 | 13 | ||||
| -rw-r--r-- | 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"); } |
