pgrep.c: Match based on process run state for issue 109
References: procps-ng/procps#109
This commit is contained in:
parent
866a27cdcd
commit
7b4ad698cc
3
pgrep.1
3
pgrep.1
@ -154,6 +154,9 @@ than
|
|||||||
\fB\-L\fR, \fB\-\-logpidfile\fR
|
\fB\-L\fR, \fB\-\-logpidfile\fR
|
||||||
Fail if pidfile (see -F) not locked.
|
Fail if pidfile (see -F) not locked.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-r\fR, \fB\-\-runstates\fR \fID,R,S,Z,\fP...
|
||||||
|
Match only processes which match the process state.
|
||||||
|
.TP
|
||||||
\fB\-\-ns \fIpid\fP
|
\fB\-\-ns \fIpid\fP
|
||||||
Match processes that belong to the same namespaces. Required to run as
|
Match processes that belong to the same namespaces. Required to run as
|
||||||
root to match processes from other users. See \-\-nslist for how to limit
|
root to match processes from other users. See \-\-nslist for how to limit
|
||||||
|
19
pgrep.c
19
pgrep.c
@ -63,11 +63,12 @@ enum pids_item Items[] = {
|
|||||||
PIDS_TIME_START,
|
PIDS_TIME_START,
|
||||||
PIDS_TTY_NAME,
|
PIDS_TTY_NAME,
|
||||||
PIDS_CMD,
|
PIDS_CMD,
|
||||||
PIDS_CMDLINE
|
PIDS_CMDLINE,
|
||||||
|
PIDS_STATE
|
||||||
};
|
};
|
||||||
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_TGID, EU_STARTTIME, EU_TTYNAME, EU_CMD, EU_CMDLINE, EU_STA
|
||||||
};
|
};
|
||||||
#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)) \
|
||||||
@ -111,6 +112,7 @@ static struct el *opt_ruid = NULL;
|
|||||||
static struct el *opt_nslist = NULL;
|
static struct el *opt_nslist = NULL;
|
||||||
static char *opt_pattern = NULL;
|
static char *opt_pattern = NULL;
|
||||||
static char *opt_pidfile = NULL;
|
static char *opt_pidfile = NULL;
|
||||||
|
static char *opt_runstates = NULL;
|
||||||
|
|
||||||
/* by default, all namespaces will be checked */
|
/* by default, all namespaces will be checked */
|
||||||
static int ns_flags = 0x3f;
|
static int ns_flags = 0x3f;
|
||||||
@ -149,6 +151,7 @@ static int __attribute__ ((__noreturn__)) usage(int opt)
|
|||||||
fputs(_(" -x, --exact match exactly with the command name\n"), fp);
|
fputs(_(" -x, --exact match exactly with the command name\n"), fp);
|
||||||
fputs(_(" -F, --pidfile <file> read PIDs from file\n"), fp);
|
fputs(_(" -F, --pidfile <file> read PIDs from file\n"), fp);
|
||||||
fputs(_(" -L, --logpidfile fail if PID file is not locked\n"), fp);
|
fputs(_(" -L, --logpidfile fail if PID file is not locked\n"), fp);
|
||||||
|
fputs(_(" -r, --runstates <state> match runstates [D,S,Z,...]\n"), fp);
|
||||||
fputs(_(" --ns <PID> match the processes that belong to the same\n"
|
fputs(_(" --ns <PID> match the processes that belong to the same\n"
|
||||||
" namespace as <pid>\n"), fp);
|
" namespace as <pid>\n"), fp);
|
||||||
fputs(_(" --nslist <ns,...> list which namespaces will be considered for\n"
|
fputs(_(" --nslist <ns,...> list which namespaces will be considered for\n"
|
||||||
@ -482,6 +485,7 @@ static struct el * select_procs (int *num)
|
|||||||
#define PIDS_GETUNT(e) PIDS_VAL(EU_ ## e, u_int, stack, info)
|
#define PIDS_GETUNT(e) PIDS_VAL(EU_ ## e, u_int, stack, info)
|
||||||
#define PIDS_GETULL(e) PIDS_VAL(EU_ ## e, ull_int, stack, info)
|
#define PIDS_GETULL(e) PIDS_VAL(EU_ ## e, ull_int, stack, info)
|
||||||
#define PIDS_GETSTR(e) PIDS_VAL(EU_ ## e, str, stack, info)
|
#define PIDS_GETSTR(e) PIDS_VAL(EU_ ## e, str, stack, info)
|
||||||
|
#define PIDS_GETSCH(e) PIDS_VAL(EU_ ## e, s_ch, stack, info)
|
||||||
struct pids_info *info=NULL;
|
struct pids_info *info=NULL;
|
||||||
struct procps_namespaces nsp;
|
struct procps_namespaces nsp;
|
||||||
struct pids_stack *stack;
|
struct pids_stack *stack;
|
||||||
@ -509,7 +513,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, 12) < 0)
|
if (procps_pids_new(&info, Items, 13) < 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;
|
||||||
@ -543,6 +547,8 @@ static struct el * select_procs (int *num)
|
|||||||
match = 0;
|
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)))
|
||||||
|
match = 0;
|
||||||
|
|
||||||
task_cmdline = PIDS_GETSTR(CMDLINE);
|
task_cmdline = PIDS_GETSTR(CMDLINE);
|
||||||
task_cmdline[CMDSTRSIZE -1] = '\0';
|
task_cmdline[CMDSTRSIZE -1] = '\0';
|
||||||
@ -666,6 +672,7 @@ static void parse_opts (int argc, char **argv)
|
|||||||
{"echo", no_argument, NULL, 'e'},
|
{"echo", no_argument, NULL, 'e'},
|
||||||
{"ns", required_argument, NULL, NS_OPTION},
|
{"ns", required_argument, NULL, NS_OPTION},
|
||||||
{"nslist", required_argument, NULL, NSLIST_OPTION},
|
{"nslist", required_argument, NULL, NSLIST_OPTION},
|
||||||
|
{"runstates", required_argument, NULL, 'r'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
@ -684,7 +691,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:?Vh");
|
strcat (opts, "LF:cfinoxP: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) {
|
||||||
@ -818,6 +825,10 @@ static void parse_opts (int argc, char **argv)
|
|||||||
usage ('?');
|
usage ('?');
|
||||||
++criteria_count;
|
++criteria_count;
|
||||||
break;
|
break;
|
||||||
|
case 'r': /* match by runstate */
|
||||||
|
opt_runstates = xstrdup (optarg);
|
||||||
|
++criteria_count;
|
||||||
|
break;
|
||||||
case NSLIST_OPTION:
|
case NSLIST_OPTION:
|
||||||
opt_nslist = split_list (optarg, conv_ns);
|
opt_nslist = split_list (optarg, conv_ns);
|
||||||
if (opt_nslist == NULL)
|
if (opt_nslist == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user