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
old build system removed
code cleanup
pgrep and pkill get "-o" (oldest matching process)
procps-3.0.3 --> procps-3.0.4

1
TODO
View File

@ -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
View File

@ -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
View File

@ -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;
@ -494,13 +506,20 @@ 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)) {
int match = 1;
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) {