Merge branch 'edneville/procps-master'

References:
 procps-ng/procps!79
This commit is contained in:
Craig Small 2020-05-17 21:54:55 +10:00
commit cec87f4aee
2 changed files with 25 additions and 6 deletions

View File

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

28
pgrep.c
View File

@ -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 */
@ -72,6 +73,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;
@ -129,6 +131,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);
@ -438,7 +441,7 @@ static PROCTAB *do_openproc (void)
flags |= PROC_FILLCOM; flags |= PROC_FILLCOM;
if (opt_ruid || opt_rgid) if (opt_ruid || opt_rgid)
flags |= PROC_FILLSTATUS; flags |= PROC_FILLSTATUS;
if (opt_oldest || opt_newest || opt_pgrp || opt_sid || opt_term) if (opt_oldest || opt_newest || opt_pgrp || opt_sid || opt_term || opt_older)
flags |= PROC_FILLSTAT; flags |= PROC_FILLSTAT;
if (!(flags & PROC_FILLSTAT)) if (!(flags & PROC_FILLSTAT))
flags |= PROC_FILLSTATUS; /* FIXME: need one, and PROC_FILLANY broken */ flags |= PROC_FILLSTATUS; /* FIXME: need one, and PROC_FILLANY broken */
@ -526,10 +529,17 @@ static struct el * select_procs (int *num)
char *cmdsearch = xmalloc(cmdlen); char *cmdsearch = xmalloc(cmdlen);
char *cmdoutput = xmalloc(cmdlen); char *cmdoutput = xmalloc(cmdlen);
proc_t ns_task; proc_t ns_task;
time_t now;
int uptime_secs;
ptp = do_openproc(); ptp = do_openproc();
preg = do_regcomp(); preg = do_regcomp();
now = time(NULL);
if ((uptime_secs=uptime(0,0)) == 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;
@ -544,7 +554,6 @@ static struct el * select_procs (int *num)
memset(&task, 0, sizeof (task)); memset(&task, 0, sizeof (task));
memset(&subtask, 0, sizeof (subtask)); memset(&subtask, 0, sizeof (subtask));
while(readproc(ptp, &task)) { while(readproc(ptp, &task)) {
/* printf( "Process state %c\n", task.state ); */
int match = 1; int match = 1;
if (task.XXXID == myself) if (task.XXXID == myself)
@ -579,6 +588,8 @@ static struct el * select_procs (int *num)
match = match_strlist (tty, opt_term); match = match_strlist (tty, opt_term);
} }
} }
else if (opt_older)
if(now - uptime_secs + (task.start_time / Hertz) + opt_older > now) match = 0;
else if (opt_runstates) { else if (opt_runstates) {
match = 0; match = 0;
if (strchr(opt_runstates, task.state)) match = 1; if (strchr(opt_runstates, task.state)) match = 1;
@ -615,6 +626,7 @@ static struct el * select_procs (int *num)
cmdoutput[cmdlen - 1] = '\0'; cmdoutput[cmdlen - 1] = '\0';
} }
if (match && opt_pattern) { if (match && opt_pattern) {
if (opt_full && task.cmdline) if (opt_full && task.cmdline)
strncpy (cmdsearch, cmdline, cmdlen - 1); strncpy (cmdsearch, cmdline, cmdlen - 1);
@ -662,7 +674,7 @@ static struct el * select_procs (int *num)
// control is free // control is free
if (opt_threads && !i_am_pkill) { if (opt_threads && !i_am_pkill) {
while (readtask(ptp, &task, &subtask)){ while (readtask(ptp, &task, &subtask)){
// don't add redundand tasks // don't add redundant tasks
if (task.XXXID == subtask.XXXID) if (task.XXXID == subtask.XXXID)
continue; continue;
@ -732,6 +744,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'},
@ -765,7 +778,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) {
@ -861,6 +874,9 @@ 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);
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)
@ -971,7 +987,7 @@ int main (int argc, char **argv)
procs = select_procs (&num); procs = select_procs (&num);
if (i_am_pkill) { if (i_am_pkill) {
int i; int i;
int kill_count = 0; int kill_count = 0;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (execute_kill (procs[i].num, opt_signal) != -1) { if (execute_kill (procs[i].num, opt_signal) != -1) {
if (opt_echo) if (opt_echo)
@ -986,7 +1002,7 @@ int main (int argc, char **argv)
} }
if (opt_count) if (opt_count)
fprintf(stdout, "%d\n", num); fprintf(stdout, "%d\n", num);
return !kill_count; return !kill_count;
} else { } else {
if (opt_count) { if (opt_count) {
fprintf(stdout, "%d\n", num); fprintf(stdout, "%d\n", num);