From owner-svn-src-all@freebsd.org Mon Nov 13 23:14:58 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AD805DD9B0C for ; Mon, 13 Nov 2017 23:14:58 +0000 (UTC) (envelope-from oliver.pinter@hardenedbsd.org) Received: from mail-wm0-x233.google.com (mail-wm0-x233.google.com [IPv6:2a00:1450:400c:c09::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EAD622CBC for ; Mon, 13 Nov 2017 23:14:57 +0000 (UTC) (envelope-from oliver.pinter@hardenedbsd.org) Received: by mail-wm0-x233.google.com with SMTP id r68so18505126wmr.3 for ; Mon, 13 Nov 2017 15:14:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hardenedbsd-org.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=o9VhmFJP6oHZxTpyazuAsTGh9egq4EMy+S925pwOPqo=; b=qabiDR99II3Qr36UiQmIxLG+r3tf8IKsk9tXj9GFAI0rK22wbY3lYOs+u1AXuwRMdY KugiT20gKGgoAOSALdvTdQ3f87e/PVB3Gxw6sOqxgn84VmrmSvrOKSxY3vXHq+5+AGUd GqZeVA3EBkbZd050JtTzq4aHm2L1v1+uSjz5YpseiIOVBVf7Rf1OLb/GvClfODtellDZ Q69tbZ2uhncKYhxR4nwf6q/I//ioW5OIHqpvYrVCmcvuRsvDZ+VPdjJ7iamNLIugwgQn 2EiM4Kx6q4Ic2IaFmhHe2hjwRUobl3q1txkvtZWm+w97BiyykbMM8w+TvmdTUZfLLxaA D34A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=o9VhmFJP6oHZxTpyazuAsTGh9egq4EMy+S925pwOPqo=; b=PRI+xqoMYLCxsyYD3qd+c6ysA7hOt44NpxwGM6nsw7wzo1CwSMlMOBRkIGU1Ue4UzO hDhsr2ELLaHeB33W1fdrLI2ql6/D6D+3AIgH0yEuNGoPYpj3nZcaAK5jHNHA42HeSlTt 5s5BSxqzS0Y/CRspVk7fJHVW/4nCM4KKhFdoyp49cP3/wFN4166AtGF6M+JYvyjAsEzv LUM1ZfA7PwGkdSK8dwMV81zMcNy/kbmBuW7Eg3h60JCMSulSRYpofRb/uUDJjMc9XZCn mRSmgcyiUzu4rCbaNiqWbhIIu10Aj6Z0m4NAIlNMq5zF/gfDT2Hph7SGZmyHrlnnXv8L OkKw== X-Gm-Message-State: AJaThX7x/ilTAWxzDhuOa383J8qqhp61sZV5cUJzfLGSXMnw1ZNfSIW8 xzLhtJy8h1GVXn5nhu8Yz+JnBZ9EjQ+7GzFXnTnpEw== X-Google-Smtp-Source: AGs4zMaPknMJD6S77BxcCPiGSFyjUNNKAfK72X9J93u5WzHwTEEo+uS2/D1KaZ6iJ7T5VIU6JkOFcwfhZjudjwl/shE= X-Received: by 10.80.181.71 with SMTP id z7mr14822615edd.201.1510614895335; Mon, 13 Nov 2017 15:14:55 -0800 (PST) MIME-Version: 1.0 Received: by 10.80.166.217 with HTTP; Mon, 13 Nov 2017 15:14:54 -0800 (PST) In-Reply-To: <201710141838.v9EIcaOQ047300@repo.freebsd.org> References: <201710141838.v9EIcaOQ047300@repo.freebsd.org> From: Oliver Pinter Date: Tue, 14 Nov 2017 00:14:54 +0100 Message-ID: Subject: Re: svn commit: r324619 - in head/usr.bin/procstat: . tests To: Brooks Davis Cc: "src-committers@freebsd.org" , "svn-src-all@freebsd.org" , "svn-src-head@freebsd.org" Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.25 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Nov 2017 23:14:58 -0000 On Saturday, October 14, 2017, Brooks Davis 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@zoho.com > 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@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/svn-src-head > To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org > " >