pgrep: add long options & new usage
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
e1bfc779f4
commit
4581ac2240
87
pgrep.c
87
pgrep.c
@ -26,6 +26,7 @@
|
|||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#include "proc/readproc.h"
|
#include "proc/readproc.h"
|
||||||
#include "proc/sig.h"
|
#include "proc/sig.h"
|
||||||
@ -71,24 +72,45 @@ static union el *opt_ruid = NULL;
|
|||||||
static char *opt_pattern = NULL;
|
static char *opt_pattern = NULL;
|
||||||
static char *opt_pidfile = NULL;
|
static char *opt_pidfile = NULL;
|
||||||
|
|
||||||
static int usage (int opt) NORETURN;
|
static int __attribute__ ((__noreturn__)) usage(int opt)
|
||||||
static int usage (int opt)
|
|
||||||
{
|
{
|
||||||
int err = (opt=='?'); /* getopt() uses '?' to mark an error */
|
int err = (opt == '?');
|
||||||
FILE *fp = err ? stderr : stdout;
|
FILE *fp = err ? stderr : stdout;
|
||||||
|
|
||||||
if (i_am_pkill)
|
fprintf(fp,
|
||||||
fprintf (fp, "Usage: pkill [-SIGNAL] [-fvx] ");
|
"\nUsage: %s [options] <pattern>\n" "\nOptions:\n", progname);
|
||||||
else
|
|
||||||
fprintf (fp, "Usage: pgrep [-cflvx] [-d DELIM] ");
|
|
||||||
fprintf (fp, "[-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST]\n"
|
|
||||||
"\t[-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] "
|
|
||||||
"[PATTERN]\n");
|
|
||||||
|
|
||||||
exit(err ? EXIT_USAGE : EXIT_SUCCESS);
|
if (i_am_pkill == 0)
|
||||||
|
fprintf(fp,
|
||||||
|
" -c, --count count of matching processes\n"
|
||||||
|
" -d, --delimeter <string> update delay in seconds\n"
|
||||||
|
" -l, --list-name list PID and process name\n");
|
||||||
|
if (i_am_pkill == 1)
|
||||||
|
fprintf(fp,
|
||||||
|
" -<sig>, --signal <sig> signal to send (either number or name)\n");
|
||||||
|
|
||||||
|
fprintf(fp,
|
||||||
|
" -f, --full use full process name to match\n"
|
||||||
|
" -g, --pgroup <id,...> match listed process group IDs\n"
|
||||||
|
" -G, --group <gid,...> match real group IDs\n"
|
||||||
|
" -n, --newest select most recently started\n"
|
||||||
|
" -o, --oldest select least recently started\n"
|
||||||
|
" -P, --parent <ppid,...> match only childs of given parent\n"
|
||||||
|
" -s, --session <sid,...> match session IDs\n"
|
||||||
|
" -t, --terminal <tty,...> match by controlling terminal\n"
|
||||||
|
" -u, --euid <id,...> match by effective IDs\n"
|
||||||
|
" -U, --uid <id,...> match by real IDs\n"
|
||||||
|
" -v, --inverse negates the matching\n"
|
||||||
|
" -x, --exact match exectly with command name\n"
|
||||||
|
" -F, --pidfile <file> read PIDs from file\n"
|
||||||
|
" -L, --logpidfile fail if PID file is not locked\n"
|
||||||
|
" -h, --help display this help text\n"
|
||||||
|
" -V, --version display version information and exit\n");
|
||||||
|
fprintf(fp, "\nFor more information see %s(1).\n", progname);
|
||||||
|
|
||||||
|
exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static union el *split_list (const char *restrict str, int (*convert)(const char *, union el *))
|
static union el *split_list (const char *restrict str, int (*convert)(const char *, union el *))
|
||||||
{
|
{
|
||||||
char *copy = strdup (str);
|
char *copy = strdup (str);
|
||||||
@ -547,6 +569,33 @@ static void parse_opts (int argc, char **argv)
|
|||||||
int opt;
|
int opt;
|
||||||
int criteria_count = 0;
|
int criteria_count = 0;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SIGNAL_OPTION = CHAR_MAX + 1
|
||||||
|
};
|
||||||
|
static const struct option longopts[] = {
|
||||||
|
{"signal", required_argument, NULL, SIGNAL_OPTION},
|
||||||
|
{"count", no_argument, NULL, 'c'},
|
||||||
|
{"delimeter", required_argument, NULL, 'd'},
|
||||||
|
{"list-name", no_argument, NULL, 'l'},
|
||||||
|
{"full", no_argument, NULL, 'f'},
|
||||||
|
{"pgroup", required_argument, NULL, 'g'},
|
||||||
|
{"group", required_argument, NULL, 'G'},
|
||||||
|
{"newest", no_argument, NULL, 'n'},
|
||||||
|
{"oldest", no_argument, NULL, 'o'},
|
||||||
|
{"parent", required_argument, NULL, 'P'},
|
||||||
|
{"session", required_argument, NULL, 's'},
|
||||||
|
{"terminal", required_argument, NULL, 't'},
|
||||||
|
{"euid", required_argument, NULL, 'u'},
|
||||||
|
{"uid", required_argument, NULL, 'U'},
|
||||||
|
{"inverse", no_argument, NULL, 'v'},
|
||||||
|
{"exact", no_argument, NULL, 'x'},
|
||||||
|
{"pidfile", required_argument, NULL, 'F'},
|
||||||
|
{"logpidfile", no_argument, NULL, 'L'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"version", no_argument, NULL, 'V'},
|
||||||
|
{NULL, 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
if (strstr (argv[0], "pkill")) {
|
if (strstr (argv[0], "pkill")) {
|
||||||
i_am_pkill = 1;
|
i_am_pkill = 1;
|
||||||
progname = "pkill";
|
progname = "pkill";
|
||||||
@ -566,13 +615,18 @@ static void parse_opts (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* These options are for pgrep only */
|
/* These options are for pgrep only */
|
||||||
strcat (opts, "ld:");
|
strcat (opts, "cld:");
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat (opts, "LF:cfnovxP:g:s:u:U:G:t:?V");
|
strcat (opts, "LF:fnovxP:g:s:u:U:G:t:?Vh");
|
||||||
|
|
||||||
while ((opt = getopt (argc, argv, opts)) != -1) {
|
while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case SIGNAL_OPTION:
|
||||||
|
opt_signal = signal_name_to_number (optarg);
|
||||||
|
if (opt_signal == -1 && isdigit (optarg[0]))
|
||||||
|
opt_signal = atoi (optarg);
|
||||||
|
break;
|
||||||
// case 'D': // FreeBSD: print info about non-matches for debugging
|
// case 'D': // FreeBSD: print info about non-matches for debugging
|
||||||
// break;
|
// break;
|
||||||
case 'F': // FreeBSD: the arg is a file containing a PID to match
|
case 'F': // FreeBSD: the arg is a file containing a PID to match
|
||||||
@ -683,6 +737,9 @@ static void parse_opts (int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
// case 'z': // Solaris: match by zone ID
|
// case 'z': // Solaris: match by zone ID
|
||||||
// break;
|
// break;
|
||||||
|
case 'h':
|
||||||
|
usage (opt);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
usage (optopt ? optopt : opt);
|
usage (optopt ? optopt : opt);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user