pgrep: Allow older than selection
Re-work merge request !79 of @edneville to permit older than selection using the new library API. References: procps-ng/procps!79
This commit is contained in:
parent
eeb8cf00a4
commit
9f751a7538
1
NEWS
1
NEWS
@ -3,6 +3,7 @@ procps-ng NEXT
|
|||||||
* kill: Pass int to signalled process merge #32
|
* kill: Pass int to signalled process merge #32
|
||||||
* pgrep: Pass int to signalled process merge #32
|
* pgrep: Pass int to signalled process merge #32
|
||||||
* pgrep: Check sanity of SG_ARG_MAX issue #152
|
* pgrep: Check sanity of SG_ARG_MAX issue #152
|
||||||
|
* pgrep: Add older than selection merge #79
|
||||||
* pidof: show worker threads Redhat #1803640
|
* pidof: show worker threads Redhat #1803640
|
||||||
* ps.1: Mention stime alias issue #164
|
* ps.1: Mention stime alias issue #164
|
||||||
* sysctl: Match systemd directory order
|
* sysctl: Match systemd directory order
|
||||||
|
5
pgrep.1
5
pgrep.1
@ -7,7 +7,7 @@
|
|||||||
.\" the Free Software Foundation; either version 2 of the License, or
|
.\" the Free Software Foundation; either version 2 of the License, or
|
||||||
.\" (at your option) any later version.
|
.\" (at your option) any later version.
|
||||||
.\"
|
.\"
|
||||||
.TH PGREP "1" "2020-04-24" "procps-ng" "User Commands"
|
.TH PGREP "1" "2020-05-17" "procps-ng" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
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
|
||||||
@ -100,6 +100,9 @@ Select only the newest (most recently started) of the matching processes.
|
|||||||
\fB\-o\fR, \fB\-\-oldest\fR
|
\fB\-o\fR, \fB\-\-oldest\fR
|
||||||
Select only the oldest (least recently started) of the matching processes.
|
Select only the oldest (least recently started) of the matching processes.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-O\fR, \fB\-\-older\fR \fIsecs\fP
|
||||||
|
Select processes older than secs.
|
||||||
|
.TP
|
||||||
\fB\-P\fR, \fB\-\-parent\fR \fIppid\fP,...
|
\fB\-P\fR, \fB\-\-parent\fR \fIppid\fP,...
|
||||||
Only match processes whose parent process ID is listed.
|
Only match processes whose parent process ID is listed.
|
||||||
.TP
|
.TP
|
||||||
|
27
pgrep.c
27
pgrep.c
@ -36,6 +36,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
/* EXIT_SUCCESS is 0 */
|
/* EXIT_SUCCESS is 0 */
|
||||||
/* EXIT_FAILURE is 1 */
|
/* EXIT_FAILURE is 1 */
|
||||||
@ -63,11 +64,12 @@ enum pids_item Items[] = {
|
|||||||
PIDS_TTY_NAME,
|
PIDS_TTY_NAME,
|
||||||
PIDS_CMD,
|
PIDS_CMD,
|
||||||
PIDS_CMDLINE,
|
PIDS_CMDLINE,
|
||||||
PIDS_STATE
|
PIDS_STATE,
|
||||||
|
PIDS_TIME_ELAPSED
|
||||||
};
|
};
|
||||||
enum rel_items {
|
enum rel_items {
|
||||||
EU_PID, EU_PPID, EU_PGRP, EU_EUID, EU_RUID, EU_RGID, EU_SESSION,
|
EU_PID, EU_PPID, EU_PGRP, EU_EUID, EU_RUID, EU_RGID, EU_SESSION,
|
||||||
EU_TGID, EU_STARTTIME, EU_TTYNAME, EU_CMD, EU_CMDLINE, EU_STA
|
EU_TGID, EU_STARTTIME, EU_TTYNAME, EU_CMD, EU_CMDLINE, EU_STA, EU_ELAPSED
|
||||||
};
|
};
|
||||||
#define grow_size(x) do { \
|
#define grow_size(x) do { \
|
||||||
if ((x) < 0 || (size_t)(x) >= INT_MAX / 5 / sizeof(struct el)) \
|
if ((x) < 0 || (size_t)(x) >= INT_MAX / 5 / sizeof(struct el)) \
|
||||||
@ -88,6 +90,7 @@ static int opt_full = 0;
|
|||||||
static int opt_long = 0;
|
static int opt_long = 0;
|
||||||
static int opt_longlong = 0;
|
static int opt_longlong = 0;
|
||||||
static int opt_oldest = 0;
|
static int opt_oldest = 0;
|
||||||
|
static int opt_older = 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;
|
||||||
@ -145,6 +148,7 @@ static int __attribute__ ((__noreturn__)) usage(int opt)
|
|||||||
fputs(_(" -i, --ignore-case match case insensitively\n"), fp);
|
fputs(_(" -i, --ignore-case match case insensitively\n"), fp);
|
||||||
fputs(_(" -n, --newest select most recently started\n"), fp);
|
fputs(_(" -n, --newest select most recently started\n"), fp);
|
||||||
fputs(_(" -o, --oldest select least recently started\n"), fp);
|
fputs(_(" -o, --oldest select least recently started\n"), fp);
|
||||||
|
fputs(_(" -O, --older <seconds> select where older than seconds\n"), fp);
|
||||||
fputs(_(" -P, --parent <PPID,...> match only child processes of the given parent\n"), fp);
|
fputs(_(" -P, --parent <PPID,...> match only child processes of the given parent\n"), fp);
|
||||||
fputs(_(" -s, --session <SID,...> match session IDs\n"), fp);
|
fputs(_(" -s, --session <SID,...> match session IDs\n"), fp);
|
||||||
fputs(_(" -t, --terminal <tty,...> match by controlling terminal\n"), fp);
|
fputs(_(" -t, --terminal <tty,...> match by controlling terminal\n"), fp);
|
||||||
@ -525,9 +529,15 @@ static struct el * select_procs (int *num)
|
|||||||
char *cmdoutput = xmalloc(cmdlen);
|
char *cmdoutput = xmalloc(cmdlen);
|
||||||
char *task_cmdline;
|
char *task_cmdline;
|
||||||
enum pids_fetch_type which;
|
enum pids_fetch_type which;
|
||||||
|
time_t now;
|
||||||
|
double uptime_secs;
|
||||||
|
|
||||||
preg = do_regcomp();
|
preg = do_regcomp();
|
||||||
|
|
||||||
|
now = time(NULL);
|
||||||
|
if (procps_uptime(&uptime_secs, NULL) < 0)
|
||||||
|
xerrx(EXIT_FAILURE, "uptime");
|
||||||
|
|
||||||
if (opt_newest) saved_start_time = 0ULL;
|
if (opt_newest) saved_start_time = 0ULL;
|
||||||
else saved_start_time = ~0ULL;
|
else saved_start_time = ~0ULL;
|
||||||
|
|
||||||
@ -538,7 +548,7 @@ static struct el * select_procs (int *num)
|
|||||||
_("Error reading reference namespace information\n"));
|
_("Error reading reference namespace information\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (procps_pids_new(&info, Items, 13) < 0)
|
if (procps_pids_new(&info, Items, 14) < 0)
|
||||||
xerrx(EXIT_FATAL,
|
xerrx(EXIT_FATAL,
|
||||||
_("Unable to create pid info structure"));
|
_("Unable to create pid info structure"));
|
||||||
which = PIDS_FETCH_TASKS_ONLY;
|
which = PIDS_FETCH_TASKS_ONLY;
|
||||||
@ -570,9 +580,11 @@ static struct el * select_procs (int *num)
|
|||||||
match = 0;
|
match = 0;
|
||||||
else if (opt_ns_pid && ! match_ns (PIDS_GETINT(PID), &nsp))
|
else if (opt_ns_pid && ! match_ns (PIDS_GETINT(PID), &nsp))
|
||||||
match = 0;
|
match = 0;
|
||||||
|
else if (opt_older && PIDS_GETULL(ELAPSED) < opt_older)
|
||||||
|
match = 0;
|
||||||
else if (opt_term)
|
else if (opt_term)
|
||||||
match = match_strlist(PIDS_GETSTR(TTYNAME), opt_term);
|
match = match_strlist(PIDS_GETSTR(TTYNAME), opt_term);
|
||||||
else if (opt_runstates && ! strchr(opt_runstates, PIDS_GETSCH(STA)))
|
else if (opt_runstates && ! strchr(opt_runstates, PIDS_GETSCH(STA)))
|
||||||
match = 0;
|
match = 0;
|
||||||
|
|
||||||
task_cmdline = PIDS_GETSTR(CMDLINE);
|
task_cmdline = PIDS_GETSTR(CMDLINE);
|
||||||
@ -686,6 +698,7 @@ static void parse_opts (int argc, char **argv)
|
|||||||
{"ignore-case", no_argument, NULL, 'i'},
|
{"ignore-case", no_argument, NULL, 'i'},
|
||||||
{"newest", no_argument, NULL, 'n'},
|
{"newest", no_argument, NULL, 'n'},
|
||||||
{"oldest", no_argument, NULL, 'o'},
|
{"oldest", no_argument, NULL, 'o'},
|
||||||
|
{"older", required_argument, NULL, 'O'},
|
||||||
{"parent", required_argument, NULL, 'P'},
|
{"parent", required_argument, NULL, 'P'},
|
||||||
{"session", required_argument, NULL, 's'},
|
{"session", required_argument, NULL, 's'},
|
||||||
{"terminal", required_argument, NULL, 't'},
|
{"terminal", required_argument, NULL, 't'},
|
||||||
@ -719,7 +732,7 @@ static void parse_opts (int argc, char **argv)
|
|||||||
strcat (opts, "lad:vw");
|
strcat (opts, "lad:vw");
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat (opts, "LF:cfinoxP:g:s:u:U:G:t:r:?Vh");
|
strcat (opts, "LF:cfinoxP:O:g:s:u:U:G:t:r:?Vh");
|
||||||
|
|
||||||
while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) {
|
while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
@ -815,6 +828,10 @@ static void parse_opts (int argc, char **argv)
|
|||||||
opt_oldest = 1;
|
opt_oldest = 1;
|
||||||
++criteria_count;
|
++criteria_count;
|
||||||
break;
|
break;
|
||||||
|
case 'O':
|
||||||
|
opt_older = atoi (optarg);
|
||||||
|
++criteria_count;
|
||||||
|
break;
|
||||||
case 's': /* Solaris: match by session ID -- zero means self */
|
case 's': /* Solaris: match by session ID -- zero means self */
|
||||||
opt_sid = split_list (optarg, conv_sid);
|
opt_sid = split_list (optarg, conv_sid);
|
||||||
if (opt_sid == NULL)
|
if (opt_sid == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user