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

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

1
TODO

@ -1,6 +1,7 @@
-------------------------- general ------------------------
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?
killall pstree fuser lsof who

12
pgrep.1

@ -7,13 +7,13 @@
pgrep, pkill \- look up or signal processes based on name and other attributes
.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
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
.br
[\-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
[\-s \fIsid\fP,...] [\-u \fIeuid\fP,...] [\-U \fIuid\fP,...] [\-G \fIgid\fP,...]
.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
processes.
.TP
\-o
Select only the oldest (least recently started) of the matching
processes.
.TP
\-P \fIppid\fP,...
Only match processes whose parent process ID is listed.
.TP
@ -137,8 +141,8 @@ The running \fBpgrep\fP or \fBpkill\fP process will never report
itself as a match.
.SH BUGS
The options \-n and \-v can not be combined. Let me know if you need
to do this.
The options \-n and \-o and \-v can not be combined. Let me know if
you need to do this.
Defunct processes are reported.

49
pgrep.c

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