new -o option: only the oldest that matches

This commit is contained in:
albert 2002-10-23 07:53:16 +00:00
parent 7f68f2504c
commit 501e740a31
4 changed files with 48 additions and 15 deletions

1
NEWS
View File

@ -5,6 +5,7 @@ better (?) RPM generation
XConsole and top.desktop removed XConsole and top.desktop removed
old build system removed old build system removed
code cleanup code cleanup
pgrep and pkill get "-o" (oldest matching process)
procps-3.0.3 --> procps-3.0.4 procps-3.0.3 --> procps-3.0.4

1
TODO
View File

@ -1,6 +1,7 @@
-------------------------- general ------------------------ -------------------------- general ------------------------
Implement /usr/proc/bin tools like Solaris has. Implement /usr/proc/bin tools like Solaris has.
The prstat command is interesting, like top in batch mode.
Don't these really belong in the procps package? Don't these really belong in the procps package?
killall pstree fuser lsof who killall pstree fuser lsof who

12
pgrep.1
View File

@ -7,13 +7,13 @@
pgrep, pkill \- look up or signal processes based on name and other attributes pgrep, pkill \- look up or signal processes based on name and other attributes
.SH SYNOPSIS .SH SYNOPSIS
pgrep [\-flnvx] [\-d \fIdelimiter\fP] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...] pgrep [\-flvx] [\-d \fIdelimiter\fP] [\-n|\-o] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
.br .br
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...] [\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
.br .br
[\-t \fIterm\fP,...] [\fIpattern\fP] [\-t \fIterm\fP,...] [\fIpattern\fP]
pkill [\-\fIsignal\fP] [\-fnvx] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...] pkill [\-\fIsignal\fP] [\-fvx] [\-n|\-o] [\-P \fIppid\fP,...] [\-g \fIpgrp\fP,...]
.br .br
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...] [\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
.br .br
@ -61,6 +61,10 @@ List the process name as well as the process ID. (\fBpgrep\fP only.)
Select only the newest (most recently started) of the matching Select only the newest (most recently started) of the matching
processes. processes.
.TP .TP
\-o
Select only the oldest (least recently started) of the matching
processes.
.TP
\-P \fIppid\fP,... \-P \fIppid\fP,...
Only match processes whose parent process ID is listed. Only match processes whose parent process ID is listed.
.TP .TP
@ -137,8 +141,8 @@ The running \fBpgrep\fP or \fBpkill\fP process will never report
itself as a match. itself as a match.
.SH BUGS .SH BUGS
The options \-n and \-v can not be combined. Let me know if you need The options \-n and \-o and \-v can not be combined. Let me know if
to do this. you need to do this.
Defunct processes are reported. Defunct processes are reported.

49
pgrep.c
View File

@ -11,6 +11,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
@ -39,6 +40,7 @@ union el {
static int opt_full = 0; static int opt_full = 0;
static int opt_long = 0; static int opt_long = 0;
static int opt_oldest = 0;
static int opt_newest = 0; static int opt_newest = 0;
static int opt_negate = 0; static int opt_negate = 0;
static int opt_exact = 0; static int opt_exact = 0;
@ -72,10 +74,10 @@ static int
usage (int opt) usage (int opt)
{ {
if (i_am_pkill) if (i_am_pkill)
fprintf (stderr, "Usage: pkill [-SIGNAL] [-fnvx] "); fprintf (stderr, "Usage: pkill [-SIGNAL] [-fvx] ");
else else
fprintf (stderr, "Usage: pgrep [-flnvx] [-d DELIM] "); fprintf (stderr, "Usage: pgrep [-flvx] [-d DELIM] ");
fprintf (stderr, "[-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]\n" fprintf (stderr, "[-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]\n"
"\t[-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] " "\t[-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] "
"[PATTERN]\n"); "[PATTERN]\n");
exit (opt == '?' ? 0 : 2); exit (opt == '?' ? 0 : 2);
@ -111,7 +113,7 @@ parse_opts (int argc, char **argv)
strcat (opts, "ld:"); strcat (opts, "ld:");
} }
strcat (opts, "fnvxP:g:s:u:U:G:t:?V"); strcat (opts, "fnovxP:g:s:u:U:G:t:?V");
while ((opt = getopt (argc, argv, opts)) != -1) { while ((opt = getopt (argc, argv, opts)) != -1) {
switch (opt) { switch (opt) {
@ -122,10 +124,20 @@ parse_opts (int argc, char **argv)
opt_long = 1; opt_long = 1;
break; break;
case 'n': case 'n':
if (opt_oldest|opt_negate|opt_newest)
usage (opt);
opt_newest = 1; opt_newest = 1;
++criteria_count; ++criteria_count;
break; break;
case 'o':
if (opt_oldest|opt_negate|opt_newest)
usage (opt);
opt_oldest = 1;
++criteria_count;
break;
case 'v': case 'v':
if (opt_oldest|opt_negate|opt_newest)
usage (opt);
opt_negate = 1; opt_negate = 1;
break; break;
case 'x': case 'x':
@ -478,8 +490,8 @@ select_procs (void)
{ {
PROCTAB *ptp; PROCTAB *ptp;
proc_t task; proc_t task;
unsigned long long newest_start_time = 0; unsigned long long saved_start_time; // for new/old support
pid_t newest_pid = 0; pid_t saved_pid = 0; // for new/old support
int matches = 0; int matches = 0;
int size = 32; int size = 32;
regex_t *preg; regex_t *preg;
@ -494,13 +506,20 @@ select_procs (void)
ptp = do_openproc (); ptp = do_openproc ();
preg = do_regcomp (); preg = do_regcomp ();
if (opt_newest) saved_start_time = 0ULL;
if (opt_oldest) saved_start_time = ~0ULL;
if (opt_newest) saved_pid = 0;
if (opt_oldest) saved_pid = INT_MAX;
memset (&task, 0, sizeof (task)); memset (&task, 0, sizeof (task));
while (readproc (ptp, &task)) { while (readproc (ptp, &task)) {
int match = 1; int match = 1;
if (task.pid == myself) if (task.pid == myself)
continue; continue;
else if (opt_newest && task.start_time < newest_start_time) else if (opt_newest && task.start_time < saved_start_time)
match = 0;
else if (opt_oldest && task.start_time > saved_start_time)
match = 0; match = 0;
else if (opt_ppid && ! match_numlist (task.ppid, opt_ppid)) else if (opt_ppid && ! match_numlist (task.ppid, opt_ppid))
match = 0; match = 0;
@ -553,11 +572,19 @@ select_procs (void)
if (match ^ opt_negate) { /* Exclusive OR is neat */ if (match ^ opt_negate) { /* Exclusive OR is neat */
if (opt_newest) { if (opt_newest) {
if (newest_start_time == task.start_time && if (saved_start_time == task.start_time &&
newest_pid > task.pid) saved_pid > task.pid)
continue; continue;
newest_start_time = task.start_time; saved_start_time = task.start_time;
newest_pid = task.pid; saved_pid = task.pid;
matches = 0;
}
if (opt_oldest) {
if (saved_start_time == task.start_time &&
saved_pid < task.pid)
continue;
saved_start_time = task.start_time;
saved_pid = task.pid;
matches = 0; matches = 0;
} }
if (opt_long) { if (opt_long) {