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
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
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.
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
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;
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);
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) {
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':
{
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;
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)) {
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;
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) {