Index: bin/pwait/pwait.1 =================================================================== --- bin/pwait/pwait.1 +++ bin/pwait/pwait.1 @@ -32,7 +32,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 1, 2009 +.Dd February 20, 2017 .Dt PWAIT 1 .Os .Sh NAME @@ -40,6 +40,7 @@ .Nd wait for processes to terminate .Sh SYNOPSIS .Nm +.Op Fl t Ar duration .Op Fl v .Ar pid \&... @@ -50,13 +51,23 @@ .Pp The following option is available: .Bl -tag -width indent +.It Fl t Ar duration +If any process is still running after +.Ar duration +seconds, +.Nm +will exit. .It Fl v Print the exit status when each process terminates. .El -.Sh DIAGNOSTICS +.Sh EXIT STATUS The .Nm -utility returns 0 on success, and >0 if an error occurs. +utility exits 0 on success, and >0 if an error occurs. +.Pp +If the +.Fl t +flag is specified and a timeout occurs, the exit status will be 124. .Pp Invalid pids elicit a warning message but are otherwise ignored. .Sh SEE ALSO Index: bin/pwait/pwait.c =================================================================== --- bin/pwait/pwait.c +++ bin/pwait/pwait.c @@ -57,21 +57,42 @@ exit(EX_USAGE); } +static double +parse_duration(const char *duration) +{ + char *end; + double ret; + + ret = strtod(duration, &end); + if (ret == 0 && end == duration) + errx(EX_DATAERR, "invalid duration"); + if (end == NULL || *end == '\0') + return (ret); + errx(EX_DATAERR, "invalid duration"); +} + /* * pwait - wait for processes to terminate */ int main(int argc, char *argv[]) { + struct timespec tspec; int kq; struct kevent *e; - int verbose = 0; + int tflag, verbose; int opt, nleft, n, i, duplicate, status; long pid; char *s, *end; - while ((opt = getopt(argc, argv, "v")) != -1) { + tflag = verbose = 0; + tspec.tv_sec = tspec.tv_nsec = 0; + while ((opt = getopt(argc, argv, "t:v")) != -1) { switch (opt) { + case 't': + tflag = 1; + tspec.tv_sec = parse_duration(optarg); + break; case 'v': verbose = 1; break; @@ -120,9 +141,11 @@ } while (nleft > 0) { - n = kevent(kq, NULL, 0, e, nleft, NULL); + n = kevent(kq, NULL, 0, e, nleft, tflag == 1 ? &tspec : NULL); if (n == -1) err(1, "kevent"); + else if (n == 0) + exit(124); if (verbose) for (i = 0; i < n; i++) { status = e[i].data;