From 0a5f326cd24818e9660f381fc30bc1689edc2839 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 20 Mar 2005 11:42:26 +0000 Subject: [PATCH] - Introduce an '-o' option which allows to match oldest of the matching processes. This option can be also found in Solaris and Linux. - Use timercmp(9) macro for timeval comparsion. - Include time.h directly, don't depend on stat.h doing it for us. Reviewed by: gad (first point) MFC after: 3 days --- usr.bin/pkill/pkill.1 | 10 ++++++---- usr.bin/pkill/pkill.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/usr.bin/pkill/pkill.1 b/usr.bin/pkill/pkill.1 index 7a272b21a39f..f4180af7a563 100644 --- a/usr.bin/pkill/pkill.1 +++ b/usr.bin/pkill/pkill.1 @@ -44,7 +44,7 @@ .Nd find or signal processes by name .Sh SYNOPSIS .Nm pgrep -.Op Fl Sfilnvx +.Op Fl Sfilnovx .Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core @@ -60,7 +60,7 @@ .Ar pattern ... .Nm pkill .Op Fl Ar signal -.Op Fl finvx +.Op Fl finovx .Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core @@ -146,8 +146,10 @@ print the process ID and the full argument list for each matching process. This option can only be used with the .Nm pgrep command. -.It Fl n -Match only the most recently created process, if any. +.It Fl n +Select only the newest (most recently started) of the matching processes. +.It Fl o +Select only the oldest (least recently started) of the matching processes. .It Fl s Ar sid Restrict matches to processes with a session ID in the comma-separated list diff --git a/usr.bin/pkill/pkill.c b/usr.bin/pkill/pkill.c index 132de3e717d3..16ee3854f74d 100644 --- a/usr.bin/pkill/pkill.c +++ b/usr.bin/pkill/pkill.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -99,6 +100,7 @@ int nproc; int pgrep; int signum = SIGTERM; int newest; +int oldest; int inverse; int longfmt; int matchargs; @@ -177,7 +179,7 @@ main(int argc, char **argv) pidfromfile = -1; execf = coref = _PATH_DEVNULL; - while ((ch = getopt(argc, argv, "DF:G:M:N:P:SU:d:fg:ij:lns:t:u:vx")) != -1) + while ((ch = getopt(argc, argv, "DF:G:M:N:P:SU:d:fg:ij:lnos:t:u:vx")) != -1) switch (ch) { case 'D': debug_opt++; @@ -237,6 +239,10 @@ main(int argc, char **argv) newest = 1; criteria = 1; break; + case 'o': + oldest = 1; + criteria = 1; + break; case 's': makelist(&sidlist, LT_SID, optarg); criteria = 1; @@ -266,6 +272,8 @@ main(int argc, char **argv) criteria = 1; if (!criteria) usage(); + if (newest && oldest) + errx(STATUS_ERROR, "-n and -o are mutually exclusive"); mypid = getpid(); @@ -434,7 +442,7 @@ main(int argc, char **argv) selected[i] = 1; } - if (newest) { + if (newest || oldest) { best_tval.tv_sec = 0; best_tval.tv_usec = 0; bestidx = -1; @@ -443,13 +451,22 @@ main(int argc, char **argv) if (!selected[i]) continue; - if (kp->ki_start.tv_sec > best_tval.tv_sec || - (kp->ki_start.tv_sec == best_tval.tv_sec - && kp->ki_start.tv_usec > best_tval.tv_usec)) { - best_tval.tv_sec = kp->ki_start.tv_sec; - best_tval.tv_usec = kp->ki_start.tv_usec; - bestidx = i; + if (bestidx == -1) { + /* The first entry of the list which matched. */ + ; + } else if (timercmp(&kp->ki_start, &best_tval, >)) { + /* This entry is newer than previous "best". */ + if (oldest) /* but we want the oldest */ + continue; + } else { + /* This entry is older than previous "best". */ + if (newest) /* but we want the newest */ + continue; } + /* This entry is better than previous "best" entry. */ + best_tval.tv_sec = kp->ki_start.tv_sec; + best_tval.tv_usec = kp->ki_start.tv_usec; + bestidx = i; } memset(selected, 0, nproc); @@ -481,9 +498,9 @@ usage(void) const char *ustr; if (pgrep) - ustr = "[-Sfilnvx] [-d delim]"; + ustr = "[-Sfilnovx] [-d delim]"; else - ustr = "[-signal] [-finvx]"; + ustr = "[-signal] [-finovx]"; fprintf(stderr, "usage: %s %s [-F pidfile] [-G gid] [-M core] [-N system]\n"