]> granicus.if.org Git - procps-ng/commitdiff
new -o option: only the oldest that matches
authoralbert <>
Wed, 23 Oct 2002 07:53:16 +0000 (07:53 +0000)
committeralbert <>
Wed, 23 Oct 2002 07:53:16 +0000 (07:53 +0000)
NEWS
TODO
pgrep.1
pgrep.c

diff --git a/NEWS b/NEWS
index a43935bd6a38d8806fa8f35ed258afa375ca3069..77f0732e6d3af08ddbf12f5e4d77cc0fb3958e5f 100644 (file)
--- a/NEWS
+++ b/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
 
diff --git a/TODO b/TODO
index fcfc1715455763cdb6181d8e27581f19eb1e0c62..b0f584dca0f868021a2e63eb02b322c529963987 100644 (file)
--- a/TODO
+++ b/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
diff --git a/pgrep.1 b/pgrep.1
index 346c5d0896e5a90de08d1522950ed03615bb612a..70e8ce2e7a189c8c7561ebce9cda177662ef5220 100644 (file)
--- a/pgrep.1
+++ b/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.
 
diff --git a/pgrep.c b/pgrep.c
index 36ecc9afd3c121b1123e0d3b90f9bb280a22f0cf..5f3657d70cc81d04e91cd7d230429e9431eba1b4 100644 (file)
--- a/pgrep.c
+++ b/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;
+                               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;
-                               newest_start_time = task.start_time;
-                               newest_pid = task.pid;
+                               saved_start_time = task.start_time;
+                               saved_pid = task.pid;
                                matches = 0;
                        }
                        if (opt_long) {