svn commit: r324619 - in head/usr.bin/procstat: . tests
Oliver Pinter
oliver.pinter at hardenedbsd.org
Mon Nov 13 23:14:58 UTC 2017
On Saturday, October 14, 2017, Brooks Davis <brooks at freebsd.org> wrote:
> Author: brooks
> Date: Sat Oct 14 18:38:36 2017
> New Revision: 324619
> URL: https://svnweb.freebsd.org/changeset/base/324619
>
> Log:
> Switch procstat from subcommand flags to verbs
>
> - Use an enumerated value instead of separate flags for commands
> - Look for a verb if no command flag is set
> - Lookup the "xocontainer" value based on the command
> - Document the new command verbs in the man-page
>
> Submitted by: kdrakehp at zoho.com <javascript:;>
> Differential Revision: https://reviews.freebsd.org/D10916
+= Release notes?
>
> Modified:
> head/usr.bin/procstat/procstat.1
> head/usr.bin/procstat/procstat.c
> head/usr.bin/procstat/procstat.h
> head/usr.bin/procstat/procstat_args.c
> head/usr.bin/procstat/procstat_auxv.c
> head/usr.bin/procstat/procstat_basic.c
> head/usr.bin/procstat/procstat_bin.c
> head/usr.bin/procstat/procstat_cred.c
> head/usr.bin/procstat/procstat_cs.c
> head/usr.bin/procstat/procstat_files.c
> head/usr.bin/procstat/procstat_kstack.c
> head/usr.bin/procstat/procstat_ptlwpinfo.c
> head/usr.bin/procstat/procstat_rlimit.c
> head/usr.bin/procstat/procstat_rusage.c
> head/usr.bin/procstat/procstat_sigs.c
> head/usr.bin/procstat/procstat_threads.c
> head/usr.bin/procstat/procstat_vm.c
> head/usr.bin/procstat/tests/procstat_test.sh
>
> Modified: head/usr.bin/procstat/procstat.1
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat.1 Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat.1 Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -25,7 +25,7 @@
> .\"
> .\" $FreeBSD$
> .\"
> -.Dd October 3, 2017
> +.Dd October 14, 2017
> .Dt PROCSTAT 1
> .Os
> .Sh NAME
> @@ -34,14 +34,75 @@
> .Sh SYNOPSIS
> .Nm
> .Op Fl -libxo
> -.Op Fl CHhn
> +.Op Fl h
> .Op Fl M Ar core
> .Op Fl N Ar system
> .Op Fl w Ar interval
> -.Op Fl b | c | e | f | i | j | k | l | L | r | s | S | t | v | x
> -.Op Fl a | Ar pid | Ar core ...
> +.Ar command
> +.Op Ar pid ... | Ar core ...
> +.Nm
> +.Op Fl -libxo
> +.Fl a
> +.Op Fl h
> +.Op Fl M Ar core
> +.Op Fl N Ar system
> +.Op Fl w Ar interval
> +.Ar command
> +.Nm
> +.Op Fl -libxo
> +.Op Fl h
> +.Op Fl M Ar core
> +.Op Fl N Ar system
> +.Op Fl w Ar interval
> +.Oo
> +.Fl b |
> +.Fl c |
> +.Fl e |
> +.Fl f Oo Fl C Oc |
> +.Fl i Oo Fl n Oc |
> +.Fl j Oo Fl n Oc |
> +.Fl k Oo Fl k Oc |
> +.Fl l |
> +.Fl r Oo Fl H Oc |
> +.Fl s |
> +.Fl S |
> +.Fl t |
> +.Fl v |
> +.Fl x
> +.Oc
> +.Op Ar pid ... | Ar core ...
> +.Nm
> +.Op Fl -libxo
> +.Fl a
> +.Op Fl h
> +.Op Fl M Ar core
> +.Op Fl N Ar system
> +.Op Fl w Ar interval
> +.Oo
> +.Fl b |
> +.Fl c |
> +.Fl e |
> +.Fl f Oo Fl C Oc |
> +.Fl i Oo Fl n Oc |
> +.Fl j Oo Fl n Oc |
> +.Fl k Oo Fl k Oc |
> +.Fl l |
> +.Fl r Oo Fl H Oc |
> +.Fl s |
> +.Fl S |
> +.Fl t |
> +.Fl v |
> +.Fl x
> +.Oc
> +.Nm
> +.Op Fl -libxo
> +.Fl L
> +.Op Fl h
> +.Op Fl M Ar core
> +.Op Fl N Ar system
> +.Op Fl w Ar interval
> +.Ar core ...
> .Sh DESCRIPTION
> -The
> .Nm
> utility displays detailed information about the processes identified by
> the
> .Ar pid
> @@ -51,49 +112,89 @@ flag is used, all processes.
> It can also display information extracted from a process core file, if
> the core file is specified as the argument.
> .Pp
> -By default, basic process statistics are printed; one of the following
> -options may be specified in order to select more detailed process
> information
> -for printing:
> -.Bl -tag -width indent
> -.It Fl -libxo
> -Generate output via
> +If the
> +.Fl -libxo
> +flag is specified the output is generated via
> .Xr libxo 3
> in a selection of different human and machine readable formats.
> See
> .Xr xo_parse_args 3
> for details on command line arguments.
> -.It Fl b
> +.Pp
> +The following commands are available:
> +.Bl -tag -width indent
> +.It Ar basic
> +Print basic process statistics (this is the default).
> +.It Ar binary | Fl b
> Display binary information for the process.
> -.It Fl c
> +.Pp
> +Substring commands are accepted.
> +.It Ar argument(s) | Fl c
> Display command line arguments for the process.
> -.It Fl e
> +.Pp
> +Substring commands are accepted.
> +.It Ar environment | Fl e
> Display environment variables for the process.
> -.It Fl f
> +.Pp
> +Substring commands are accepted.
> +.It Ar file(s) | Ar fd(s) | Fl f
> Display file descriptor information for the process.
> -.It Fl i
> +.Pp
> +If the
> +.Fl C
> +subcommand flag is used then additional capability information is printed.
> +.It Ar signal(s) | Fl i
> Display signal pending and disposition information for the process.
> -.It Fl j
> +.Pp
> +If the
> +.Fl n
> +subcommand option is used, the signal numbers are shown instead of signal
> +names.
> +.Pp
> +Substring commands are accepted.
> +.It Ar tsignal(s) | Fl j
> Display signal pending and blocked information for the process's threads.
> -.It Fl k
> +.Pp
> +If the
> +.Fl n
> +subcommand option is used, the signal numbers are shown instead of signal
> +names.
> +.Pp
> +Substring commands are accepted.
> +.It Ar kstack | Fl k
> Display the stacks of kernel threads in the process, excluding stacks of
> threads currently running on a CPU and threads with stacks swapped to
> disk.
> -If the flag is repeated, function offsets as well as function names are
> -printed.
> -.It Fl l
> +.Pp
> +If the
> +.Fl v
> +subcommand option is used (or the command flag is repeated), function
> +offsets as well as function names are printed.
> +.It Ar rlimit | Fl l
> Display resource limits for the process.
> -.It Fl L
> +.It Ar ptlwpinfo | Fl L
> Display LWP info for the process pertaining to its signal driven exit.
> -.It Fl r
> +.It Ar rusage | Fl r
> Display resource usage information for the process.
> -.It Fl s
> +.Pp
> +If the
> +.Fl v
> +.Pq or Fl H
> +subcommand flag
> +is used then per-thread statistics are printed, rather than per-process
> +statistics.
> +The second field in the table will list the thread ID to which the row of
> +information corresponds.
> +.It Ar credential(s) | Fl s
> Display security credential information for the process.
> -.It Fl S
> +.Pp
> +Substring commands are accepted.
> +.It Ar cpuset | Ar cs | Fl S
> Display the cpuset information for the thread.
> -.It Fl t
> +.It Ar thread(s) | Fl t
> Display thread information for the process.
> -.It Fl v
> +.It Ar vm | Fl v
> Display virtual memory mappings for the process.
> -.It Fl x
> +.It Ar auxv | Fl x
> Display ELF auxiliary vector for the process.
> .El
> .Pp
> @@ -110,23 +211,6 @@ of the requested process information.
> If the
> .Fl w
> flag is not specified, the output will not repeat.
> -.Pp
> -The
> -.Fl C
> -flag requests the printing of additional capability information in the
> file
> -descriptor view.
> -.Pp
> -The
> -.Fl H
> -flag may be used to request per-thread statistics rather than per-process
> -statistics for some options.
> -For those options, the second field in the table will list the thread ID
> -to which the row of information corresponds.
> -The
> -.Fl H
> -flag is implied for the
> -.Fl S
> -mode.
> .Pp
> Information for VM, file descriptor, and cpuset options is available
> only to the owner of a process or the superuser.
>
> Modified: head/usr.bin/procstat/procstat.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -42,37 +42,111 @@
>
> #include "procstat.h"
>
> -static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag;
> -static int lflag, Lflag, rflag, sflag, tflag, vflag, xflag, Sflag;
> -int hflag, nflag, Cflag, Hflag;
> +enum {
> + PS_CMP_NORMAL = 0x00,
> + PS_CMP_PLURAL = 0x01,
> + PS_CMP_SUBSTR = 0x02
> +};
>
> +struct procstat_cmd {
> + const char *command;
> + const char *xocontainer;
> + const char *usage;
> + void (*cmd)(struct procstat *, struct kinfo_proc *);
> + void (*opt)(int, char * const *);
> + int cmp;
> +};
> +
> +int procstat_opts = 0;
> +
> +static void cmdopt_none(int argc, char * const argv[]);
> +static void cmdopt_verbose(int argc, char * const argv[]);
> +static void cmdopt_signals(int argc, char * const argv[]);
> +static void cmdopt_rusage(int argc, char * const argv[]);
> +static void cmdopt_files(int argc, char * const argv[]);
> +static void cmdopt_cpuset(int argc, char * const argv[]);
> +
> +static const struct procstat_cmd cmd_table[] = {
> + { "argument", "arguments", NULL, &procstat_args, &cmdopt_none,
> + PS_CMP_PLURAL | PS_CMP_SUBSTR },
> + { "auxv", "auxv", NULL, &procstat_auxv, &cmdopt_none,
> PS_CMP_NORMAL },
> + { "basic", "basic", NULL, &procstat_basic, &cmdopt_none,
> + PS_CMP_NORMAL },
> + { "binary", "binary", NULL, &procstat_bin, &cmdopt_none,
> + PS_CMP_SUBSTR },
> + { "cpuset", "cs", NULL, &procstat_cs, &cmdopt_cpuset,
> PS_CMP_NORMAL },
> + { "cs", "cs", NULL, &procstat_cs, &cmdopt_cpuset, PS_CMP_NORMAL },
> + { "credential", "credentials", NULL, &procstat_cred, &cmdopt_none,
> + PS_CMP_PLURAL | PS_CMP_SUBSTR },
> + { "environment", "environment", NULL, &procstat_env, &cmdopt_none,
> + PS_CMP_SUBSTR },
> + { "fd", "files", "[-C]", &procstat_files, &cmdopt_files,
> + PS_CMP_PLURAL },
> + { "file", "files", "[-C]", &procstat_files, &cmdopt_files,
> + PS_CMP_PLURAL },
> + { "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose,
> + PS_CMP_NORMAL },
> + { "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo,
> &cmdopt_none,
> + PS_CMP_NORMAL },
> + { "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none,
> + PS_CMP_NORMAL },
> + { "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage,
> + PS_CMP_NORMAL },
> + { "signal", "signals", "[-n]", &procstat_sigs, &cmdopt_signals,
> + PS_CMP_PLURAL | PS_CMP_SUBSTR },
> + { "thread", "threads", NULL, &procstat_threads, &cmdopt_none,
> + PS_CMP_PLURAL },
> + { "tsignal", "thread_signals", "[-n]", &procstat_threads_sigs,
> + &cmdopt_signals, PS_CMP_PLURAL | PS_CMP_SUBSTR },
> + { "vm", "vm", NULL, &procstat_vm, &cmdopt_none, PS_CMP_NORMAL }
> +};
> +
> static void
> usage(void)
> {
> + size_t i, l;
> + int multi;
>
> - xo_error(
> - "usage: procstat [--libxo] [-Hhn] [-M core] "
> - "[-N system] [-w interval]\n"
> - " [-S | -b | -c | -e | -i | -j | -k | -kk | "
> - "-l | -r | -s | \n"
> - " -t | -v | -x]\n"
> - " [-a | pid ... | core ...]\n"
> - " procstat [--libxo] -Cf [-hn] [-M core] "
> - "[-N system] [-a | pid ... | core ...]\n"
> - " [-S | -b | -c | -e | -i | -j | -k | -kk | "
> - "-l | -r | -s | \n"
> - " procstat [--libxo] -L [-hn] [-M core] "
> - "[-N system] [-w interval]\n"
> - " [-S | -b | -c | -e | -i | -j | -k | -kk | "
> - "-l | -r | -s | \n"
> - " -t | -v | -x]\n"
> - " [core ...]\n");
> + xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]"
> + " [-w interval] command\n"
> + " [pid ... | core ...]\n"
> + " procstat [--libxo] -a [-h] [-M core] [-N system] "
> + " [-w interval] command\n"
> + " procstat [--libxo] [-h] [-M core] [-N system]"
> + " [-w interval]\n"
> + " [-S | -b | -c | -e | -f [-C] | -i [-n] | "
> + "-j [-n] | -k [-k] |\n"
> + " -l | -r [-H] | -s | -t | -v | -x] "
> + "[pid ... | core ...]\n"
> + " procstat [--libxo] -a [-h] [-M core] [-N system]"
> + " [-w interval]\n"
> + " [-S | -b | -c | -e | -f [-C] | -i [-n] | "
> + "-j [-n] | -k [-k] |\n"
> + " -l | -r [-H] | -s | -t | -v | -x]\n"
> + " procstat [--libxo] -L [-h] [-M core] [-N system] core
> ...\n"
> + "Available commands:\n");
> + for (i = 0, l = nitems(cmd_table); i < l; i++) {
> + multi = i + 1 < l && cmd_table[i].cmd == cmd_table[i +
> 1].cmd;
> + xo_error(" %s%s%s", multi ? "[" : "",
> + cmd_table[i].command, (cmd_table[i].cmp &
> PS_CMP_PLURAL) ?
> + "(s)" : "");
> + for (; i + 1 < l && cmd_table[i].cmd == cmd_table[i +
> 1].cmd;
> + i++)
> + xo_error(" | %s%s", cmd_table[i + 1].command,
> + (cmd_table[i].cmp & PS_CMP_PLURAL) ? "(s)" :
> "");
> + if (multi)
> + xo_error("]");
> + if (cmd_table[i].usage != NULL)
> + xo_error(" %s", cmd_table[i].usage);
> + xo_error("\n");
> + }
> xo_finish();
> exit(EX_USAGE);
> }
>
> static void
> -procstat(struct procstat *prstat, struct kinfo_proc *kipp)
> +procstat(const struct procstat_cmd *cmd, struct procstat *prstat,
> + struct kinfo_proc *kipp)
> {
> char *pidstr = NULL;
>
> @@ -80,40 +154,7 @@ procstat(struct procstat *prstat, struct kinfo_proc *k
> if (pidstr == NULL)
> xo_errc(1, ENOMEM, "Failed to allocate memory in
> procstat()");
> xo_open_container(pidstr);
> -
> - if (bflag)
> - procstat_bin(prstat, kipp);
> - else if (cflag)
> - procstat_args(prstat, kipp);
> - else if (eflag)
> - procstat_env(prstat, kipp);
> - else if (fflag)
> - procstat_files(prstat, kipp);
> - else if (iflag)
> - procstat_sigs(prstat, kipp);
> - else if (jflag)
> - procstat_threads_sigs(prstat, kipp);
> - else if (kflag)
> - procstat_kstack(prstat, kipp, kflag);
> - else if (lflag)
> - procstat_rlimit(prstat, kipp);
> - else if (Lflag)
> - procstat_ptlwpinfo(prstat);
> - else if (rflag)
> - procstat_rusage(prstat, kipp);
> - else if (sflag)
> - procstat_cred(prstat, kipp);
> - else if (tflag)
> - procstat_threads(prstat, kipp);
> - else if (vflag)
> - procstat_vm(prstat, kipp);
> - else if (xflag)
> - procstat_auxv(prstat, kipp);
> - else if (Sflag)
> - procstat_cs(prstat, kipp);
> - else
> - procstat_basic(kipp);
> -
> + cmd->cmd(prstat, kipp);
> xo_close_container(pidstr);
> free(pidstr);
> }
> @@ -157,122 +198,158 @@ kinfo_proc_thread_name(const struct kinfo_proc
> *kipp)
> return (name);
> }
>
> +static const struct procstat_cmd *
> +getcmd(const char *str)
> +{
> + const struct procstat_cmd *cmd;
> + size_t i, l;
> + int cmp, s;
> +
> + if (str == NULL)
> + return (NULL);
> + cmd = NULL;
> + if ((l = strlen(str)) == 0)
> + return (getcmd("basic"));
> + s = l > 1 && strcasecmp(str + l - 1, "s") == 0;
> + for (i = 0; i < nitems(cmd_table); i++) {
> + /*
> + * After the first match substring matches are disabled,
> + * allowing subsequent full matches to take precedence.
> + */
> + if (cmd == NULL && (cmd_table[i].cmp & PS_CMP_SUBSTR))
> + cmp = strncasecmp(str, cmd_table[i].command, l -
> + ((cmd_table[i].cmp & PS_CMP_PLURAL) && s ? 1 :
> 0));
> + else if ((cmd_table[i].cmp & PS_CMP_PLURAL) && s &&
> + l == strlen(cmd_table[i].command) + 1)
> + cmp = strncasecmp(str, cmd_table[i].command, l -
> 1);
> + else
> + cmp = strcasecmp(str, cmd_table[i].command);
> + if (cmp == 0)
> + cmd = &cmd_table[i];
> + }
> + return (cmd);
> +}
> +
> int
> main(int argc, char *argv[])
> {
> - int ch, interval, tmp;
> + int ch, interval;
> int i;
> struct kinfo_proc *p;
> + const struct procstat_cmd *cmd;
> struct procstat *prstat, *cprstat;
> long l;
> pid_t pid;
> char *dummy;
> char *nlistf, *memf;
> - const char *xocontainer;
> + int aflag;
> int cnt;
>
> interval = 0;
> + cmd = NULL;
> memf = nlistf = NULL;
> + aflag = 0;
> argc = xo_parse_args(argc, argv);
> - xocontainer = "basic";
>
> while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) !=
> -1) {
> switch (ch) {
> - case 'C':
> - Cflag++;
> - break;
> -
> - case 'H':
> - Hflag++;
> - break;
> -
> - case 'M':
> - memf = optarg;
> - break;
> - case 'N':
> - nlistf = optarg;
> - break;
> - case 'S':
> - Sflag++;
> - xocontainer = "cs";
> - break;
> case 'a':
> aflag++;
> break;
> -
> case 'b':
> - bflag++;
> - xocontainer = "binary";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("binary");
> break;
> -
> + case 'C':
> + procstat_opts |= PS_OPT_CAPABILITIES;
> + break;
> case 'c':
> - cflag++;
> - xocontainer = "arguments";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("arguments");
> break;
> -
> case 'e':
> - eflag++;
> - xocontainer = "environment";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("environment");
> break;
> -
> case 'f':
> - fflag++;
> - xocontainer = "files";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("files");
> break;
> -
> + case 'H':
> + procstat_opts |= PS_OPT_PERTHREAD;
> + break;
> + case 'h':
> + procstat_opts |= PS_OPT_NOHEADER;
> + break;
> case 'i':
> - iflag++;
> - xocontainer = "signals";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("signals");
> break;
> -
> case 'j':
> - jflag++;
> - xocontainer = "thread_signals";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("tsignals");
> break;
> -
> case 'k':
> - kflag++;
> - xocontainer = "kstack";
> + if (cmd->cmd == procstat_kstack) {
> + if ((procstat_opts & PS_OPT_VERBOSE) != 0)
> + usage();
> + procstat_opts |= PS_OPT_VERBOSE;
> + } else {
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("kstack");
> + }
> break;
> -
> + case 'L':
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("ptlwpinfo");
> + break;
> case 'l':
> - lflag++;
> - xocontainer = "rlimit";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("rlimit");
> break;
> -
> - case 'L':
> - Lflag++;
> - xocontainer = "ptlwpinfo";
> + case 'M':
> + memf = optarg;
> break;
> -
> + case 'N':
> + nlistf = optarg;
> + break;
> case 'n':
> - nflag++;
> + procstat_opts |= PS_OPT_SIGNUM;
> break;
> -
> - case 'h':
> - hflag++;
> - break;
> -
> case 'r':
> - rflag++;
> - xocontainer = "rusage";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("rusage");
> break;
> -
> + case 'S':
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("cpuset");
> + break;
> case 's':
> - sflag++;
> - xocontainer = "credentials";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("credentials");
> break;
> -
> case 't':
> - tflag++;
> - xocontainer = "threads";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("threads");
> break;
> -
> case 'v':
> - vflag++;
> - xocontainer = "vm";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("vm");
> break;
> -
> case 'w':
> l = strtol(optarg, &dummy, 10);
> if (*dummy != '\0')
> @@ -281,12 +358,11 @@ main(int argc, char *argv[])
> usage();
> interval = l;
> break;
> -
> case 'x':
> - xflag++;
> - xocontainer = "auxv";
> + if (cmd != NULL)
> + usage();
> + cmd = getcmd("auxv");
> break;
> -
> case '?':
> default:
> usage();
> @@ -296,24 +372,31 @@ main(int argc, char *argv[])
> argc -= optind;
> argv += optind;
>
> - /* We require that either 0 or 1 mode flags be set. */
> - tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 :
> 0) +
> - lflag + rflag + sflag + tflag + vflag + xflag + Sflag;
> - if (!(tmp == 0 || tmp == 1))
> - usage();
> + if (cmd == NULL && argv[0] != NULL && (cmd = getcmd(argv[0])) !=
> NULL) {
> + if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0)
> + usage();
> + if (cmd->opt != NULL) {
> + optreset = 1;
> + optind = 1;
> + cmd->opt(argc, argv);
> + argc -= optind;
> + argv += optind;
> + } else {
> + argc -= 1;
> + argv += 1;
> + }
> + } else {
> + if (cmd == NULL)
> + cmd = getcmd("basic");
> + if (cmd->cmd != procstat_files &&
> + (procstat_opts & PS_OPT_CAPABILITIES) != 0)
> + usage();
> + }
>
> - /* We allow -k to be specified up to twice, but not more. */
> - if (kflag > 2)
> - usage();
> -
> /* Must specify either the -a flag or a list of pids. */
> if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
> usage();
>
> - /* Only allow -C with -f. */
> - if (Cflag && !fflag)
> - usage();
> -
> if (memf != NULL)
> prstat = procstat_open_kvm(nlistf, memf);
> else
> @@ -323,7 +406,7 @@ main(int argc, char *argv[])
> do {
> xo_set_version(PROCSTAT_XO_VERSION);
> xo_open_container("procstat");
> - xo_open_container(xocontainer);
> + xo_open_container(cmd->xocontainer);
>
> if (aflag) {
> p = procstat_getprocs(prstat, KERN_PROC_PROC, 0,
> &cnt);
> @@ -331,10 +414,10 @@ main(int argc, char *argv[])
> xo_errx(1, "procstat_getprocs()");
> kinfo_proc_sort(p, cnt);
> for (i = 0; i < cnt; i++) {
> - procstat(prstat, &p[i]);
> + procstat(cmd, prstat, &p[i]);
>
> /* Suppress header after first process. */
> - hflag = 1;
> + procstat_opts |= PS_OPT_NOHEADER;
> xo_flush();
> }
> procstat_freeprocs(prstat, p);
> @@ -351,7 +434,7 @@ main(int argc, char *argv[])
> if (p == NULL)
> xo_errx(1, "procstat_getprocs()");
> if (cnt != 0)
> - procstat(prstat, p);
> + procstat(cmd, prstat, p);
> procstat_freeprocs(prstat, p);
> } else {
> cprstat = procstat_open_core(argv[i]);
> @@ -364,15 +447,15 @@ main(int argc, char *argv[])
> if (p == NULL)
> xo_errx(1, "procstat_getprocs()");
> if (cnt != 0)
> - procstat(cprstat, p);
> + procstat(cmd, cprstat, p);
> procstat_freeprocs(cprstat, p);
> procstat_close(cprstat);
> }
> /* Suppress header after first process. */
> - hflag = 1;
> + procstat_opts |= PS_OPT_NOHEADER;
> }
>
> - xo_close_container(xocontainer);
> + xo_close_container(cmd->xocontainer);
> xo_close_container("procstat");
> xo_finish();
> if (interval)
> @@ -382,4 +465,96 @@ main(int argc, char *argv[])
> procstat_close(prstat);
>
> exit(0);
> +}
> +
> +void
> +cmdopt_none(int argc, char * const argv[])
> +{
> + int ch;
> +
> + while ((ch = getopt(argc, argv, "")) != -1) {
> + switch (ch) {
> + case '?':
> + default:
> + usage();
> + }
> + }
> +}
> +
> +void
> +cmdopt_verbose(int argc, char * const argv[])
> +{
> + int ch;
> +
> + while ((ch = getopt(argc, argv, "v")) != -1) {
> + switch (ch) {
> + case 'v':
> + procstat_opts |= PS_OPT_VERBOSE;
> + break;
> + case '?':
> + default:
> + usage();
> + }
> + }
> +}
> +
> +void
> +cmdopt_signals(int argc, char * const argv[])
> +{
> + int ch;
> +
> + while ((ch = getopt(argc, argv, "n")) != -1) {
> + switch (ch) {
> + case 'n':
> + procstat_opts |= PS_OPT_SIGNUM;
> + break;
> + case '?':
> + default:
> + usage();
> + }
> + }
> +}
> +
> +void
> +cmdopt_rusage(int argc, char * const argv[])
> +{
> + int ch;
> +
> + while ((ch = getopt(argc, argv, "Ht")) != -1) {
> + switch (ch) {
> + case 'H':
> + /* FALLTHROUGH */
> + case 't':
> + procstat_opts |= PS_OPT_PERTHREAD;
> + break;
> + case '?':
> + default:
> + usage();
> + }
> + }
> +}
> +
> +void
> +cmdopt_files(int argc, char * const argv[])
> +{
> + int ch;
> +
> + while ((ch = getopt(argc, argv, "C")) != -1) {
> + switch (ch) {
> + case 'C':
> + procstat_opts |= PS_OPT_CAPABILITIES;
> + break;
> + case '?':
> + default:
> + usage();
> + }
> + }
> +}
> +
> +void
> +cmdopt_cpuset(int argc, char * const argv[])
> +{
> +
> + procstat_opts |= PS_OPT_PERTHREAD;
> + cmdopt_none(argc, argv);
> }
>
> Modified: head/usr.bin/procstat/procstat.h
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat.h Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat.h Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -35,23 +35,34 @@
>
> #define PROCSTAT_XO_VERSION "1"
>
> -extern int hflag, nflag, Cflag, Hflag;
> +enum {
> + PS_OPT_CAPABILITIES = 0x01,
> + PS_OPT_NOHEADER = 0x02,
> + PS_OPT_PERTHREAD = 0x04,
> + PS_OPT_SIGNUM = 0x08,
> + PS_OPT_VERBOSE = 0x10
> +};
>
> +#define PS_SUBCOMMAND_OPTS \
> + (PS_OPT_CAPABILITIES | PS_OPT_SIGNUM | \
> + PS_OPT_PERTHREAD | PS_OPT_VERBOSE)
> +
> +extern int procstat_opts;
> +
> struct kinfo_proc;
> void kinfo_proc_sort(struct kinfo_proc *kipp, int count);
> const char * kinfo_proc_thread_name(const struct kinfo_proc *kipp);
>
> void procstat_args(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_auxv(struct procstat *prstat, struct kinfo_proc *kipp);
> -void procstat_basic(struct kinfo_proc *kipp);
> +void procstat_basic(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_bin(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_cred(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_cs(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_env(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_files(struct procstat *prstat, struct kinfo_proc *kipp);
> -void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp,
> - int kflag);
> -void procstat_ptlwpinfo(struct procstat *prstat);
> +void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp);
> +void procstat_ptlwpinfo(struct procstat *prstat, struct kinfo_proc
> *kipp);
> void procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp);
> void procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp);
>
> Modified: head/usr.bin/procstat/procstat_args.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_args.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_args.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -47,7 +47,7 @@ procstat_args(struct procstat *procstat, struct kinfo_
> int i;
> char **args;
>
> - if (!hflag) {
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0) {
> xo_emit("{T:/%5s %-16s %-53s}\n", "PID", "COMM", "ARGS");
> }
>
> @@ -74,7 +74,7 @@ procstat_env(struct procstat *procstat, struct kinfo_p
> int i;
> char **envs;
>
> - if (!hflag) {
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0) {
> xo_emit("{T:/%5s %-16s %-53s}\n", "PID", "COMM",
> "ENVIRONMENT");
> }
>
>
> Modified: head/usr.bin/procstat/procstat_auxv.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_auxv.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_auxv.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -51,7 +51,7 @@ procstat_auxv(struct procstat *procstat, struct kinfo_
> u_int count, i;
> static char prefix[256];
>
> - if (!hflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0)
> xo_emit("{T:/%5s %-16s %-16s %-16s}\n", "PID", "COMM",
> "AUXV",
> "VALUE");
>
>
> Modified: head/usr.bin/procstat/procstat_basic.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_basic.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_basic.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -39,10 +39,10 @@
> #include "procstat.h"
>
> void
> -procstat_basic(struct kinfo_proc *kipp)
> +procstat_basic(struct procstat *procstat __unused, struct kinfo_proc
> *kipp)
> {
>
> - if (!hflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0)
> xo_emit("{T:/%5s %5s %5s %5s %5s %3s %-8s %-9s %-13s
> %-12s}\n",
> "PID", "PPID", "PGID", "SID", "TSID", "THR", "LOGIN",
> "WCHAN", "EMUL", "COMM");
>
> Modified: head/usr.bin/procstat/procstat_bin.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_bin.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_bin.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -46,7 +46,7 @@ procstat_bin(struct procstat *prstat, struct kinfo_pro
> int osrel;
> static char pathname[PATH_MAX];
>
> - if (!hflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0)
> xo_emit("{T:/%5s %-16s %8s %s}\n", "PID", "COMM", "OSREL",
> "PATH");
>
>
> Modified: head/usr.bin/procstat/procstat_cred.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_cred.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_cred.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -48,7 +48,7 @@ procstat_cred(struct procstat *procstat, struct kinfo_
> unsigned int i, ngroups;
> gid_t *groups;
>
> - if (!hflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0)
> xo_emit("{T:/%5s %-16s %5s %5s %5s %5s %5s %5s %5s %5s
> %-15s}\n",
> "PID", "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID",
> "SVGID", "UMASK", "FLAGS", "GROUPS");
>
> Modified: head/usr.bin/procstat/procstat_cs.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_cs.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_cs.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -52,7 +52,7 @@ procstat_cs(struct procstat *procstat, struct kinfo_pr
> unsigned int count, i;
> int once, twice, lastcpu, cpu;
>
> - if (!hflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0)
> xo_emit("{T:/%5s %6s %-19s %-19s %2s %4s %-7s}\n", "PID",
> "TID", "COMM", "TDNAME", "CPU", "CSID", "CPU MASK");
>
>
> Modified: head/usr.bin/procstat/procstat_files.c
> ============================================================
> ==================
> --- head/usr.bin/procstat/procstat_files.c Sat Oct 14 17:51:25 2017
> (r324618)
> +++ head/usr.bin/procstat/procstat_files.c Sat Oct 14 18:38:36 2017
> (r324619)
> @@ -303,7 +303,8 @@ procstat_files(struct procstat *procstat, struct kinfo
> */
> capwidth = 0;
> head = procstat_getfiles(procstat, kipp, 0);
> - if (head != NULL && Cflag) {
> + if (head != NULL &&
> + (procstat_opts & PS_OPT_CAPABILITIES) != 0) {
> STAILQ_FOREACH(fst, head, next) {
> width = width_capability(&fst->fs_cap_rights);
> if (width > capwidth)
> @@ -313,8 +314,8 @@ procstat_files(struct procstat *procstat, struct kinfo
> capwidth = strlen("CAPABILITIES");
> }
>
> - if (!hflag) {
> - if (Cflag)
> + if ((procstat_opts & PS_OPT_NOHEADER) == 0) {
> + if ((procstat_opts & PS_OPT_CAPABILITIES) != 0)
> xo_emit("{T:/%5s %-16s %5s %1s %-8s %-*s "
> "%-3s %-12s}\n", "PID", "COMM", "FD", "T",
> "FLAGS", capwidth, "CAPABILITIES", "PRO",
> @@ -417,7 +418,7 @@ procstat_files(struct procstat *procstat, struct kinfo
> break;
> }
> xo_emit("{d:fd_type/%1s/%s} ", str);
> - if (!Cflag) {
> + if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) {
> str = "-";
> if (fst->fs_type == PS_FST_TYPE_VNODE) {
> error = procstat_get_vnode_info(procstat,
> fst,
> @@ -514,7 +515,7 @@ procstat_files(struct procstat *procstat, struct kinfo
> xo_emit("{elq:fd_flags/lock_held}");
> xo_close_list("fd_flags");
>
> - if (!Cflag) {
> + if ((procstat_opts & PS_OPT_CAPABILITIES) == 0) {
> if (fst->fs_ref_count > -1)
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> _______________________________________________
> svn-src-head at freebsd.org <javascript:;> mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscribe at freebsd.org
> <javascript:;>"
>
More information about the svn-src-all
mailing list