Add pargs, penv, pwdx commands and aliases to procstat(1).
Intent is to mimic Solaris commands with the same names. Submitted by: Juraj Lutter <juraj@lutter.sk> MFC after: 1 week Differential revision: https://reviews.freebsd.org/D26310
This commit is contained in:
parent
d99cb9802b
commit
085e04945c
@ -13,15 +13,25 @@ SRCS= procstat.c \
|
|||||||
procstat_cs.c \
|
procstat_cs.c \
|
||||||
procstat_files.c \
|
procstat_files.c \
|
||||||
procstat_kstack.c \
|
procstat_kstack.c \
|
||||||
|
procstat_penv.c \
|
||||||
procstat_ptlwpinfo.c \
|
procstat_ptlwpinfo.c \
|
||||||
|
procstat_pwdx.c \
|
||||||
procstat_rlimit.c \
|
procstat_rlimit.c \
|
||||||
procstat_rusage.c \
|
procstat_rusage.c \
|
||||||
procstat_sigs.c \
|
procstat_sigs.c \
|
||||||
procstat_threads.c \
|
procstat_threads.c \
|
||||||
procstat_vm.c
|
procstat_vm.c
|
||||||
|
|
||||||
|
MLINKS+= procstat.1 pargs.1
|
||||||
|
MLINKS+= procstat.1 penv.1
|
||||||
|
MLINKS+= procstat.1 pwdx.1
|
||||||
|
|
||||||
LIBADD+= procstat xo util sbuf
|
LIBADD+= procstat xo util sbuf
|
||||||
|
|
||||||
|
LINKS+= ${BINDIR}/procstat ${BINDIR}/pargs
|
||||||
|
LINKS+= ${BINDIR}/procstat ${BINDIR}/penv
|
||||||
|
LINKS+= ${BINDIR}/procstat ${BINDIR}/pwdx
|
||||||
|
|
||||||
HAS_TESTS=
|
HAS_TESTS=
|
||||||
SUBDIR.${MK_TESTS}+= tests
|
SUBDIR.${MK_TESTS}+= tests
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 4, 2019
|
.Dd September 14, 2020
|
||||||
.Dt PROCSTAT 1
|
.Dt PROCSTAT 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -102,6 +102,15 @@
|
|||||||
.Op Fl N Ar system
|
.Op Fl N Ar system
|
||||||
.Op Fl w Ar interval
|
.Op Fl w Ar interval
|
||||||
.Ar core ...
|
.Ar core ...
|
||||||
|
.Nm pargs
|
||||||
|
.Op Fl -libxo
|
||||||
|
.Ar pid ...
|
||||||
|
.Nm penv
|
||||||
|
.Op Fl -libxo
|
||||||
|
.Ar pid ...
|
||||||
|
.Nm pwdx
|
||||||
|
.Op Fl -libxo
|
||||||
|
.Ar pid ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
utility displays detailed information about the processes identified by the
|
utility displays detailed information about the processes identified by the
|
||||||
@ -112,6 +121,17 @@ flag is used, all processes.
|
|||||||
It can also display information extracted from a process core file, if
|
It can also display information extracted from a process core file, if
|
||||||
the core file is specified as the argument.
|
the core file is specified as the argument.
|
||||||
.Pp
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm pargs ,
|
||||||
|
.Nm penv
|
||||||
|
and
|
||||||
|
.Nm pwdx
|
||||||
|
utilities display the arguments, environment, and current working directory,
|
||||||
|
respectively of the process specified by
|
||||||
|
.Ar pid
|
||||||
|
argument.
|
||||||
|
They mimic the behavior of Solaris utilities of the same names.
|
||||||
|
.Pp
|
||||||
If the
|
If the
|
||||||
.Fl -libxo
|
.Fl -libxo
|
||||||
flag is specified the output is generated via
|
flag is specified the output is generated via
|
||||||
@ -121,7 +141,8 @@ See
|
|||||||
.Xr xo_parse_args 3
|
.Xr xo_parse_args 3
|
||||||
for details on command line arguments.
|
for details on command line arguments.
|
||||||
.Pp
|
.Pp
|
||||||
The following commands are available:
|
The following commands are available for
|
||||||
|
.Nm :
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Ar basic
|
.It Ar basic
|
||||||
Print basic process statistics (this is the default).
|
Print basic process statistics (this is the default).
|
||||||
@ -196,6 +217,12 @@ Display thread information for the process.
|
|||||||
Display virtual memory mappings for the process.
|
Display virtual memory mappings for the process.
|
||||||
.It Ar auxv | Fl x
|
.It Ar auxv | Fl x
|
||||||
Display ELF auxiliary vector for the process.
|
Display ELF auxiliary vector for the process.
|
||||||
|
.It Ar pargs
|
||||||
|
Display arguments for the process.
|
||||||
|
.It Ar penv
|
||||||
|
Display environment variables for the process.
|
||||||
|
.It Ar pwdx
|
||||||
|
Display current working directory for the process.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
All options generate output in the format of a table, the first field of
|
All options generate output in the format of a table, the first field of
|
||||||
@ -430,7 +457,7 @@ process signal disposition details, three symbols
|
|||||||
if signal is pending in the global process queue; - otherwise.
|
if signal is pending in the global process queue; - otherwise.
|
||||||
.It I
|
.It I
|
||||||
if signal delivery disposition is
|
if signal delivery disposition is
|
||||||
.Dv SIG_IGN;
|
.Dv SIG_IGN ;
|
||||||
- otherwise.
|
- otherwise.
|
||||||
.It C
|
.It C
|
||||||
if the signal will be caught; - otherwise.
|
if the signal will be caught; - otherwise.
|
||||||
@ -711,6 +738,10 @@ support was added by
|
|||||||
.An -nosplit
|
.An -nosplit
|
||||||
Allan Jude
|
Allan Jude
|
||||||
.Aq Mt allanjude@FreeBSD.org .
|
.Aq Mt allanjude@FreeBSD.org .
|
||||||
|
.br
|
||||||
|
.An Juraj Lutter
|
||||||
|
.Aq Mt juraj@lutter.sk
|
||||||
|
added the pargs, penv and pwdx functionality.
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
The display of open file or memory mapping pathnames is implemented using the
|
The display of open file or memory mapping pathnames is implemented using the
|
||||||
kernel's name cache.
|
kernel's name cache.
|
||||||
|
@ -68,6 +68,23 @@ static void cmdopt_rusage(int argc, char * const argv[]);
|
|||||||
static void cmdopt_files(int argc, char * const argv[]);
|
static void cmdopt_files(int argc, char * const argv[]);
|
||||||
static void cmdopt_cpuset(int argc, char * const argv[]);
|
static void cmdopt_cpuset(int argc, char * const argv[]);
|
||||||
|
|
||||||
|
static const char *progname;
|
||||||
|
|
||||||
|
/* aliased program parameters and arguments
|
||||||
|
* - usage field is abused to hold the pointer to the function
|
||||||
|
* displaying program usage
|
||||||
|
*/
|
||||||
|
static const struct procstat_cmd pacmd_table[] = {
|
||||||
|
/* arguments are the same as for pwdx: pid or core file */
|
||||||
|
{ "pargs", "args", NULL, &procstat_pargs, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL | PS_MODE_COMPAT },
|
||||||
|
{ "penv", "env", NULL, &procstat_penv, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL | PS_MODE_COMPAT },
|
||||||
|
{ "pwdx", "pwd", NULL, &procstat_pwdx, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL | PS_MODE_COMPAT }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* procstat parameters and arguments */
|
||||||
static const struct procstat_cmd cmd_table[] = {
|
static const struct procstat_cmd cmd_table[] = {
|
||||||
{ "argument", "arguments", NULL, &procstat_args, &cmdopt_none,
|
{ "argument", "arguments", NULL, &procstat_args, &cmdopt_none,
|
||||||
PS_CMP_PLURAL | PS_CMP_SUBSTR },
|
PS_CMP_PLURAL | PS_CMP_SUBSTR },
|
||||||
@ -88,8 +105,14 @@ static const struct procstat_cmd cmd_table[] = {
|
|||||||
PS_CMP_PLURAL },
|
PS_CMP_PLURAL },
|
||||||
{ "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose,
|
{ "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose,
|
||||||
PS_CMP_NORMAL },
|
PS_CMP_NORMAL },
|
||||||
|
{ "pargs", "args", NULL, &procstat_pargs, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL },
|
||||||
|
{ "penv", "env", NULL, &procstat_penv, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL },
|
||||||
{ "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo, &cmdopt_none,
|
{ "ptlwpinfo", "ptlwpinfo", NULL, &procstat_ptlwpinfo, &cmdopt_none,
|
||||||
PS_CMP_NORMAL },
|
PS_CMP_NORMAL },
|
||||||
|
{ "pwdx", "pwd", NULL, &procstat_pwdx, &cmdopt_none,
|
||||||
|
PS_CMP_NORMAL },
|
||||||
{ "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none,
|
{ "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none,
|
||||||
PS_CMP_NORMAL },
|
PS_CMP_NORMAL },
|
||||||
{ "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage,
|
{ "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage,
|
||||||
@ -106,43 +129,49 @@ static const struct procstat_cmd cmd_table[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(const struct procstat_cmd *cmd)
|
||||||
{
|
{
|
||||||
size_t i, l;
|
size_t i, l;
|
||||||
int multi;
|
int multi;
|
||||||
|
|
||||||
xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]"
|
if (cmd == NULL || (cmd->cmp & PS_MODE_COMPAT) == 0) {
|
||||||
" [-w interval] command\n"
|
xo_error("usage: procstat [--libxo] [-h] [-M core] [-N system]"
|
||||||
" [pid ... | core ...]\n"
|
" [-w interval] command\n"
|
||||||
" procstat [--libxo] -a [-h] [-M core] [-N system] "
|
" [pid ... | core ...]\n"
|
||||||
" [-w interval] command\n"
|
" procstat [--libxo] -a [-h] [-M core] [-N system] "
|
||||||
" procstat [--libxo] [-h] [-M core] [-N system]"
|
" [-w interval] command\n"
|
||||||
" [-w interval]\n"
|
" procstat [--libxo] [-h] [-M core] [-N system]"
|
||||||
" [-S | -b | -c | -e | -f [-C] | -i [-n] | "
|
" [-w interval]\n"
|
||||||
"-j [-n] | -k [-k] |\n"
|
" [-S | -b | -c | -e | -f [-C] | -i [-n] | "
|
||||||
" -l | -r [-H] | -s | -t | -v | -x] "
|
"-j [-n] | -k [-k] |\n"
|
||||||
"[pid ... | core ...]\n"
|
" -l | -r [-H] | -s | -t | -v | -x] "
|
||||||
" procstat [--libxo] -a [-h] [-M core] [-N system]"
|
"[pid ... | core ...]\n"
|
||||||
" [-w interval]\n"
|
" procstat [--libxo] -a [-h] [-M core] [-N system]"
|
||||||
" [-S | -b | -c | -e | -f [-C] | -i [-n] | "
|
" [-w interval]\n"
|
||||||
"-j [-n] | -k [-k] |\n"
|
" [-S | -b | -c | -e | -f [-C] | -i [-n] | "
|
||||||
" -l | -r [-H] | -s | -t | -v | -x]\n"
|
"-j [-n] | -k [-k] |\n"
|
||||||
" procstat [--libxo] -L [-h] [-M core] [-N system] core ...\n"
|
" -l | -r [-H] | -s | -t | -v | -x]\n"
|
||||||
"Available commands:\n");
|
" procstat [--libxo] -L [-h] [-M core] [-N system] core ...\n"
|
||||||
for (i = 0, l = nitems(cmd_table); i < l; i++) {
|
"Available commands:\n");
|
||||||
multi = i + 1 < l && cmd_table[i].cmd == cmd_table[i + 1].cmd;
|
for (i = 0, l = nitems(cmd_table); i < l; i++) {
|
||||||
xo_error(" %s%s%s", multi ? "[" : "",
|
multi = i + 1 < l && cmd_table[i].cmd ==
|
||||||
cmd_table[i].command, (cmd_table[i].cmp & PS_CMP_PLURAL) ?
|
cmd_table[i + 1].cmd;
|
||||||
"(s)" : "");
|
xo_error(" %s%s%s", multi ? "[" : "",
|
||||||
for (; i + 1 < l && cmd_table[i].cmd == cmd_table[i + 1].cmd;
|
cmd_table[i].command, (cmd_table[i].cmp &
|
||||||
i++)
|
PS_CMP_PLURAL) ? "(s)" : "");
|
||||||
xo_error(" | %s%s", cmd_table[i + 1].command,
|
for (; i + 1 < l && cmd_table[i].cmd ==
|
||||||
(cmd_table[i].cmp & PS_CMP_PLURAL) ? "(s)" : "");
|
cmd_table[i + 1].cmd; i++)
|
||||||
if (multi)
|
xo_error(" | %s%s", cmd_table[i + 1].command,
|
||||||
xo_error("]");
|
(cmd_table[i].cmp & PS_CMP_PLURAL) ?
|
||||||
if (cmd_table[i].usage != NULL)
|
"(s)" : "");
|
||||||
xo_error(" %s", cmd_table[i].usage);
|
if (multi)
|
||||||
xo_error("\n");
|
xo_error("]");
|
||||||
|
if (cmd_table[i].usage != NULL)
|
||||||
|
xo_error(" %s", cmd_table[i].usage);
|
||||||
|
xo_error("\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
xo_error("usage: %s [--libxo] pid ...\n", progname);
|
||||||
}
|
}
|
||||||
xo_finish();
|
xo_finish();
|
||||||
exit(EX_USAGE);
|
exit(EX_USAGE);
|
||||||
@ -202,6 +231,25 @@ kinfo_proc_thread_name(const struct kinfo_proc *kipp)
|
|||||||
return (name);
|
return (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct procstat_cmd *
|
||||||
|
getcmdbyprogname(const char *pprogname)
|
||||||
|
{
|
||||||
|
const char *ca;
|
||||||
|
size_t i, len;
|
||||||
|
|
||||||
|
if (pprogname == NULL)
|
||||||
|
return (NULL);
|
||||||
|
len = strlen(pprogname);
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(pacmd_table); i++) {
|
||||||
|
ca = pacmd_table[i].command;
|
||||||
|
if (ca != NULL && strcmp(ca, pprogname) == 0)
|
||||||
|
return (&pacmd_table[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct procstat_cmd *
|
static const struct procstat_cmd *
|
||||||
getcmd(const char *str)
|
getcmd(const char *str)
|
||||||
{
|
{
|
||||||
@ -237,17 +285,14 @@ getcmd(const char *str)
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ch, interval;
|
|
||||||
int i;
|
|
||||||
struct kinfo_proc *p;
|
struct kinfo_proc *p;
|
||||||
const struct procstat_cmd *cmd;
|
const struct procstat_cmd *cmd;
|
||||||
struct procstat *prstat, *cprstat;
|
struct procstat *prstat, *cprstat;
|
||||||
|
char *dummy, *nlistf, *memf;
|
||||||
|
const char *xocontainer;
|
||||||
long l;
|
long l;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char *dummy;
|
int aflag, ch, cnt, i, interval;
|
||||||
char *nlistf, *memf;
|
|
||||||
int aflag;
|
|
||||||
int cnt;
|
|
||||||
|
|
||||||
interval = 0;
|
interval = 0;
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
@ -255,6 +300,9 @@ main(int argc, char *argv[])
|
|||||||
aflag = 0;
|
aflag = 0;
|
||||||
argc = xo_parse_args(argc, argv);
|
argc = xo_parse_args(argc, argv);
|
||||||
|
|
||||||
|
progname = getprogname();
|
||||||
|
cmd = getcmdbyprogname(progname);
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) {
|
while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -262,7 +310,7 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("binary");
|
cmd = getcmd("binary");
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
@ -270,17 +318,17 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("arguments");
|
cmd = getcmd("arguments");
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("environment");
|
cmd = getcmd("environment");
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("files");
|
cmd = getcmd("files");
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -291,33 +339,33 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("signals");
|
cmd = getcmd("signals");
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("tsignals");
|
cmd = getcmd("tsignals");
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
if (cmd != NULL && cmd->cmd == procstat_kstack) {
|
if (cmd != NULL && cmd->cmd == procstat_kstack) {
|
||||||
if ((procstat_opts & PS_OPT_VERBOSE) != 0)
|
if ((procstat_opts & PS_OPT_VERBOSE) != 0)
|
||||||
usage();
|
usage(cmd);
|
||||||
procstat_opts |= PS_OPT_VERBOSE;
|
procstat_opts |= PS_OPT_VERBOSE;
|
||||||
} else {
|
} else {
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("kstack");
|
cmd = getcmd("kstack");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("ptlwpinfo");
|
cmd = getcmd("ptlwpinfo");
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("rlimit");
|
cmd = getcmd("rlimit");
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -331,75 +379,79 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("rusage");
|
cmd = getcmd("rusage");
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("cpuset");
|
cmd = getcmd("cpuset");
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("credentials");
|
cmd = getcmd("credentials");
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("threads");
|
cmd = getcmd("threads");
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("vm");
|
cmd = getcmd("vm");
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
l = strtol(optarg, &dummy, 10);
|
l = strtol(optarg, &dummy, 10);
|
||||||
if (*dummy != '\0')
|
if (*dummy != '\0')
|
||||||
usage();
|
usage(cmd);
|
||||||
if (l < 1 || l > INT_MAX)
|
if (l < 1 || l > INT_MAX)
|
||||||
usage();
|
usage(cmd);
|
||||||
interval = l;
|
interval = l;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
if (cmd != NULL)
|
if (cmd != NULL)
|
||||||
usage();
|
usage(cmd);
|
||||||
cmd = getcmd("auxv");
|
cmd = getcmd("auxv");
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
if (cmd == NULL && argv[0] != NULL && (cmd = getcmd(argv[0])) != NULL) {
|
if (cmd == NULL && argv[0] != NULL)
|
||||||
|
cmd = getcmd(argv[0]);
|
||||||
|
if (cmd != NULL) {
|
||||||
if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0)
|
if ((procstat_opts & PS_SUBCOMMAND_OPTS) != 0)
|
||||||
usage();
|
usage(cmd);
|
||||||
if (cmd->opt != NULL) {
|
if (cmd->opt != NULL) {
|
||||||
optreset = 1;
|
optreset = 1;
|
||||||
optind = 1;
|
optind = 1;
|
||||||
cmd->opt(argc, argv);
|
cmd->opt(argc, argv);
|
||||||
argc -= optind;
|
if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
|
||||||
argv += optind;
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
argc -= 1;
|
argc -= 1;
|
||||||
argv += 1;
|
argv += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cmd == NULL)
|
cmd = getcmd("basic");
|
||||||
cmd = getcmd("basic");
|
|
||||||
if (cmd->cmd != procstat_files &&
|
|
||||||
(procstat_opts & PS_OPT_CAPABILITIES) != 0)
|
|
||||||
usage();
|
|
||||||
}
|
}
|
||||||
|
if (cmd->cmd != procstat_files &&
|
||||||
|
(procstat_opts & PS_OPT_CAPABILITIES) != 0 &&
|
||||||
|
(cmd->cmp & PS_MODE_COMPAT) == 0)
|
||||||
|
usage(cmd);
|
||||||
|
|
||||||
/* Must specify either the -a flag or a list of pids. */
|
/* Must specify either the -a flag or a list of pids. */
|
||||||
if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
|
if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
|
||||||
usage();
|
usage(cmd);
|
||||||
|
|
||||||
if (memf != NULL)
|
if (memf != NULL)
|
||||||
prstat = procstat_open_kvm(nlistf, memf);
|
prstat = procstat_open_kvm(nlistf, memf);
|
||||||
@ -408,9 +460,11 @@ main(int argc, char *argv[])
|
|||||||
if (prstat == NULL)
|
if (prstat == NULL)
|
||||||
xo_errx(1, "procstat_open()");
|
xo_errx(1, "procstat_open()");
|
||||||
do {
|
do {
|
||||||
|
xocontainer = cmd->xocontainer != NULL ? cmd->xocontainer :
|
||||||
|
cmd->command;
|
||||||
xo_set_version(PROCSTAT_XO_VERSION);
|
xo_set_version(PROCSTAT_XO_VERSION);
|
||||||
xo_open_container("procstat");
|
xo_open_container(progname);
|
||||||
xo_open_container(cmd->xocontainer);
|
xo_open_container(xocontainer);
|
||||||
|
|
||||||
if (aflag) {
|
if (aflag) {
|
||||||
p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
|
p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
|
||||||
@ -430,7 +484,7 @@ main(int argc, char *argv[])
|
|||||||
l = strtol(argv[i], &dummy, 10);
|
l = strtol(argv[i], &dummy, 10);
|
||||||
if (*dummy == '\0') {
|
if (*dummy == '\0') {
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
usage();
|
usage(cmd);
|
||||||
pid = l;
|
pid = l;
|
||||||
|
|
||||||
p = procstat_getprocs(prstat, KERN_PROC_PID,
|
p = procstat_getprocs(prstat, KERN_PROC_PID,
|
||||||
@ -441,26 +495,34 @@ main(int argc, char *argv[])
|
|||||||
procstat(cmd, prstat, p);
|
procstat(cmd, prstat, p);
|
||||||
procstat_freeprocs(prstat, p);
|
procstat_freeprocs(prstat, p);
|
||||||
} else {
|
} else {
|
||||||
cprstat = procstat_open_core(argv[i]);
|
if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
|
||||||
if (cprstat == NULL) {
|
cprstat = procstat_open_core(argv[i]);
|
||||||
warnx("procstat_open()");
|
if (cprstat == NULL) {
|
||||||
continue;
|
warnx("procstat_open()");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p = procstat_getprocs(cprstat,
|
||||||
|
KERN_PROC_PID, -1, &cnt);
|
||||||
|
if (p == NULL) {
|
||||||
|
xo_errx(1,
|
||||||
|
"procstat_getprocs()");
|
||||||
|
}
|
||||||
|
if (cnt != 0)
|
||||||
|
procstat(cmd, cprstat, p);
|
||||||
|
procstat_freeprocs(cprstat, p);
|
||||||
|
procstat_close(cprstat);
|
||||||
|
} else {
|
||||||
|
usage(cmd);
|
||||||
}
|
}
|
||||||
p = procstat_getprocs(cprstat, KERN_PROC_PID,
|
|
||||||
-1, &cnt);
|
|
||||||
if (p == NULL)
|
|
||||||
xo_errx(1, "procstat_getprocs()");
|
|
||||||
if (cnt != 0)
|
|
||||||
procstat(cmd, cprstat, p);
|
|
||||||
procstat_freeprocs(cprstat, p);
|
|
||||||
procstat_close(cprstat);
|
|
||||||
}
|
}
|
||||||
/* Suppress header after first process. */
|
if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
|
||||||
procstat_opts |= PS_OPT_NOHEADER;
|
/* Suppress header after first process. */
|
||||||
|
procstat_opts |= PS_OPT_NOHEADER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xo_close_container(cmd->xocontainer);
|
xo_close_container(xocontainer);
|
||||||
xo_close_container("procstat");
|
xo_close_container(progname);
|
||||||
xo_finish();
|
xo_finish();
|
||||||
if (interval)
|
if (interval)
|
||||||
sleep(interval);
|
sleep(interval);
|
||||||
@ -480,7 +542,7 @@ cmdopt_none(int argc, char * const argv[])
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -497,7 +559,7 @@ cmdopt_verbose(int argc, char * const argv[])
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,7 +576,7 @@ cmdopt_signals(int argc, char * const argv[])
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -533,7 +595,7 @@ cmdopt_rusage(int argc, char * const argv[])
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,7 +612,7 @@ cmdopt_files(int argc, char * const argv[])
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,8 @@ enum {
|
|||||||
PS_OPT_NOHEADER = 0x02,
|
PS_OPT_NOHEADER = 0x02,
|
||||||
PS_OPT_PERTHREAD = 0x04,
|
PS_OPT_PERTHREAD = 0x04,
|
||||||
PS_OPT_SIGNUM = 0x08,
|
PS_OPT_SIGNUM = 0x08,
|
||||||
PS_OPT_VERBOSE = 0x10
|
PS_OPT_VERBOSE = 0x10,
|
||||||
|
PS_MODE_COMPAT = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PS_SUBCOMMAND_OPTS \
|
#define PS_SUBCOMMAND_OPTS \
|
||||||
@ -64,7 +65,10 @@ void procstat_cs(struct procstat *prstat, struct kinfo_proc *kipp);
|
|||||||
void procstat_env(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_files(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp);
|
void procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
|
void procstat_pargs(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
|
void procstat_penv(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
void procstat_ptlwpinfo(struct procstat *prstat, struct kinfo_proc *kipp);
|
void procstat_ptlwpinfo(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
|
void procstat_pwdx(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
void procstat_rlimit(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_rusage(struct procstat *prstat, struct kinfo_proc *kipp);
|
||||||
void procstat_sigfastblock(struct procstat *procstat,
|
void procstat_sigfastblock(struct procstat *procstat,
|
||||||
|
@ -68,7 +68,7 @@ kstack_nextstate(enum trace_state ts)
|
|||||||
return (TS_OFF);
|
return (TS_OFF);
|
||||||
|
|
||||||
case TS_OFF:
|
case TS_OFF:
|
||||||
return TS_FRAMENUM;
|
return (TS_FRAMENUM);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errx(-1, "kstack_nextstate");
|
errx(-1, "kstack_nextstate");
|
||||||
|
86
usr.bin/procstat/procstat_penv.c
Normal file
86
usr.bin/procstat/procstat_penv.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Juraj Lutter <juraj@lutter.sk>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <libprocstat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "procstat.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
procstat_pargs(struct procstat *procstat, struct kinfo_proc *kipp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **args;
|
||||||
|
|
||||||
|
args = procstat_getargv(procstat, kipp, 0);
|
||||||
|
|
||||||
|
xo_emit("{k:process_id/%d}: {:command/%s/%s}\n", kipp->ki_pid,
|
||||||
|
kipp->ki_comm);
|
||||||
|
|
||||||
|
if (args == NULL) {
|
||||||
|
xo_emit("{d:args/-}\n");
|
||||||
|
} else {
|
||||||
|
for (i = 0; args[i] != NULL; i++) {
|
||||||
|
xo_emit("{Ld:argv[}{Ld:/%d}{Ldwc:]}{l:argv/%s}\n",
|
||||||
|
i, args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
procstat_penv(struct procstat *procstat, struct kinfo_proc *kipp)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **envs;
|
||||||
|
|
||||||
|
envs = procstat_getenvv(procstat, kipp, 0);
|
||||||
|
|
||||||
|
xo_emit("{k:process_id/%d}: {:command/%s/%s}\n", kipp->ki_pid,
|
||||||
|
kipp->ki_comm);
|
||||||
|
|
||||||
|
if (envs == NULL) {
|
||||||
|
xo_emit("{d:env/-}\n");
|
||||||
|
} else {
|
||||||
|
for (i = 0; envs[i] != NULL; i++) {
|
||||||
|
xo_emit("{Ld:envp[}{Ld:/%d}{Ldwc:]}{l:envp/%s}\n",
|
||||||
|
i, envs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
usr.bin/procstat/procstat_pwdx.c
Normal file
70
usr.bin/procstat/procstat_pwdx.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020 Juraj Lutter <juraj@lutter.sk>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/capsicum.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/user.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <libprocstat.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "procstat.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
procstat_pwdx(struct procstat *procstat, struct kinfo_proc *kipp)
|
||||||
|
{
|
||||||
|
struct filestat_list *head;
|
||||||
|
struct filestat *fst;
|
||||||
|
|
||||||
|
head = procstat_getfiles(procstat, kipp, 0);
|
||||||
|
if (head == NULL)
|
||||||
|
return;
|
||||||
|
STAILQ_FOREACH(fst, head, next) {
|
||||||
|
if ((fst->fs_uflags & PS_FST_UFLAG_CDIR) &&
|
||||||
|
(fst->fs_path != NULL)) {
|
||||||
|
xo_emit("{k:process_id/%d}{P:: }", kipp->ki_pid);
|
||||||
|
xo_emit("{:cwd/%s}", fst->fs_path);
|
||||||
|
xo_emit("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
procstat_freefiles(procstat, head);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user