svn commit: r365880 - head/usr.bin/procstat

Konstantin Belousov kib at FreeBSD.org
Fri Sep 18 12:59:30 UTC 2020


Author: kib
Date: Fri Sep 18 12:59:27 2020
New Revision: 365880
URL: https://svnweb.freebsd.org/changeset/base/365880

Log:
  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 at lutter.sk>
  MFC after:	1 week
  Differential revision:	https://reviews.freebsd.org/D26310

Added:
  head/usr.bin/procstat/procstat_penv.c   (contents, props changed)
  head/usr.bin/procstat/procstat_pwdx.c   (contents, props changed)
Modified:
  head/usr.bin/procstat/Makefile
  head/usr.bin/procstat/procstat.1
  head/usr.bin/procstat/procstat.c
  head/usr.bin/procstat/procstat.h
  head/usr.bin/procstat/procstat_kstack.c

Modified: head/usr.bin/procstat/Makefile
==============================================================================
--- head/usr.bin/procstat/Makefile	Fri Sep 18 12:37:41 2020	(r365879)
+++ head/usr.bin/procstat/Makefile	Fri Sep 18 12:59:27 2020	(r365880)
@@ -13,14 +13,24 @@ SRCS=	procstat.c		\
 	procstat_cs.c		\
 	procstat_files.c	\
 	procstat_kstack.c	\
+	procstat_penv.c		\
 	procstat_ptlwpinfo.c	\
+	procstat_pwdx.c		\
 	procstat_rlimit.c	\
 	procstat_rusage.c	\
 	procstat_sigs.c		\
 	procstat_threads.c	\
 	procstat_vm.c
 
+MLINKS+=	procstat.1 pargs.1
+MLINKS+=	procstat.1 penv.1
+MLINKS+=	procstat.1 pwdx.1
+
 LIBADD+=	procstat xo util sbuf
+
+LINKS+=		${BINDIR}/procstat ${BINDIR}/pargs
+LINKS+=		${BINDIR}/procstat ${BINDIR}/penv
+LINKS+=		${BINDIR}/procstat ${BINDIR}/pwdx
 
 HAS_TESTS=
 SUBDIR.${MK_TESTS}+= tests

Modified: head/usr.bin/procstat/procstat.1
==============================================================================
--- head/usr.bin/procstat/procstat.1	Fri Sep 18 12:37:41 2020	(r365879)
+++ head/usr.bin/procstat/procstat.1	Fri Sep 18 12:59:27 2020	(r365880)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 4, 2019
+.Dd September 14, 2020
 .Dt PROCSTAT 1
 .Os
 .Sh NAME
@@ -102,6 +102,15 @@
 .Op Fl N Ar system
 .Op Fl w Ar interval
 .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
 .Nm
 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
 the core file is specified as the argument.
 .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
 .Fl -libxo
 flag is specified the output is generated via
@@ -121,7 +141,8 @@ See
 .Xr xo_parse_args 3
 for details on command line arguments.
 .Pp
-The following commands are available:
+The following commands are available for
+.Nm :
 .Bl -tag -width indent
 .It Ar basic
 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.
 .It Ar auxv | Fl x
 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
 .Pp
 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.
 .It I
 if signal delivery disposition is
-.Dv SIG_IGN;
+.Dv SIG_IGN ;
 - otherwise.
 .It C
 if the signal will be caught; - otherwise.
@@ -711,6 +738,10 @@ support was added by
 .An -nosplit
 Allan Jude
 .Aq Mt allanjude at FreeBSD.org .
+.br
+.An Juraj Lutter
+.Aq Mt juraj at lutter.sk
+added the pargs, penv and pwdx functionality.
 .Sh BUGS
 The display of open file or memory mapping pathnames is implemented using the
 kernel's name cache.

Modified: head/usr.bin/procstat/procstat.c
==============================================================================
--- head/usr.bin/procstat/procstat.c	Fri Sep 18 12:37:41 2020	(r365879)
+++ head/usr.bin/procstat/procstat.c	Fri Sep 18 12:59:27 2020	(r365880)
@@ -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_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[] = {
 	{ "argument", "arguments", NULL, &procstat_args, &cmdopt_none,
 	    PS_CMP_PLURAL | PS_CMP_SUBSTR },
@@ -88,8 +105,14 @@ static const struct procstat_cmd cmd_table[] = {
 	    PS_CMP_PLURAL },
 	{ "kstack", "kstack", "[-v]", &procstat_kstack, &cmdopt_verbose,
 	    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,
 	    PS_CMP_NORMAL },
+	{ "pwdx", "pwd", NULL, &procstat_pwdx, &cmdopt_none,
+	    PS_CMP_NORMAL },
 	{ "rlimit", "rlimit", NULL, &procstat_rlimit, &cmdopt_none,
 	    PS_CMP_NORMAL },
 	{ "rusage", "rusage", "[-Ht]", &procstat_rusage, &cmdopt_rusage,
@@ -106,43 +129,49 @@ static const struct procstat_cmd cmd_table[] = {
 };
 
 static void
-usage(void)
+usage(const struct procstat_cmd *cmd)
 {
 	size_t i, l;
 	int multi;
 
-	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");
+	if (cmd == NULL || (cmd->cmp & PS_MODE_COMPAT) == 0) {
+		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");
+		}
+	} else {
+		xo_error("usage: %s [--libxo] pid ...\n", progname);
 	}
 	xo_finish();
 	exit(EX_USAGE);
@@ -203,6 +232,25 @@ kinfo_proc_thread_name(const struct kinfo_proc *kipp)
 }
 
 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 *
 getcmd(const char *str)
 {
 	const struct procstat_cmd *cmd;
@@ -237,17 +285,14 @@ getcmd(const char *str)
 int
 main(int argc, char *argv[])
 {
-	int ch, interval;
-	int i;
 	struct kinfo_proc *p;
 	const struct procstat_cmd *cmd;
 	struct procstat *prstat, *cprstat;
+	char *dummy, *nlistf, *memf;
+	const char *xocontainer;
 	long l;
 	pid_t pid;
-	char *dummy;
-	char *nlistf, *memf;
-	int aflag;
-	int cnt;
+	int aflag, ch, cnt, i, interval;
 
 	interval = 0;
 	cmd = NULL;
@@ -255,6 +300,9 @@ main(int argc, char *argv[])
 	aflag = 0;
 	argc = xo_parse_args(argc, argv);
 
+	progname = getprogname();
+	cmd = getcmdbyprogname(progname);
+
 	while ((ch = getopt(argc, argv, "abCcefHhijkLlM:N:nrSstvw:x")) != -1) {
 		switch (ch) {
 		case 'a':
@@ -262,7 +310,7 @@ main(int argc, char *argv[])
 			break;
 		case 'b':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("binary");
 			break;
 		case 'C':
@@ -270,17 +318,17 @@ main(int argc, char *argv[])
 			break;
 		case 'c':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("arguments");
 			break;
 		case 'e':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("environment");
 			break;
 		case 'f':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("files");
 			break;
 		case 'H':
@@ -291,33 +339,33 @@ main(int argc, char *argv[])
 			break;
 		case 'i':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("signals");
 			break;
 		case 'j':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("tsignals");
 			break;
 		case 'k':
 			if (cmd != NULL && cmd->cmd == procstat_kstack) {
 				if ((procstat_opts & PS_OPT_VERBOSE) != 0)
-					usage();
+					usage(cmd);
 				procstat_opts |= PS_OPT_VERBOSE;
 			} else {
 				if (cmd != NULL)
-					usage();
+					usage(cmd);
 				cmd = getcmd("kstack");
 			}
 			break;
 		case 'L':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("ptlwpinfo");
 			break;
 		case 'l':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("rlimit");
 			break;
 		case 'M':
@@ -331,75 +379,79 @@ main(int argc, char *argv[])
 			break;
 		case 'r':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("rusage");
 			break;
 		case 'S':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("cpuset");
 			break;
 		case 's':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("credentials");
 			break;
 		case 't':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("threads");
 			break;
 		case 'v':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("vm");
 			break;
 		case 'w':
 			l = strtol(optarg, &dummy, 10);
 			if (*dummy != '\0')
-				usage();
+				usage(cmd);
 			if (l < 1 || l > INT_MAX)
-				usage();
+				usage(cmd);
 			interval = l;
 			break;
 		case 'x':
 			if (cmd != NULL)
-				usage();
+				usage(cmd);
 			cmd = getcmd("auxv");
 			break;
 		case '?':
 		default:
-			usage();
+			usage(cmd);
 		}
 
 	}
 	argc -= 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)
-			usage();
+			usage(cmd);
 		if (cmd->opt != NULL) {
 			optreset = 1;
 			optind = 1;
 			cmd->opt(argc, argv);
-			argc -= optind;
-			argv += optind;
+			if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
+				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();
+		cmd = getcmd("basic");
 	}
+	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. */
 	if (!(aflag == 1 && argc == 0) && !(aflag == 0 && argc > 0))
-		usage();
+		usage(cmd);
 
 	if (memf != NULL)
 		prstat = procstat_open_kvm(nlistf, memf);
@@ -408,9 +460,11 @@ main(int argc, char *argv[])
 	if (prstat == NULL)
 		xo_errx(1, "procstat_open()");
 	do {
+		xocontainer = cmd->xocontainer != NULL ? cmd->xocontainer :
+		    cmd->command;
 		xo_set_version(PROCSTAT_XO_VERSION);
-		xo_open_container("procstat");
-		xo_open_container(cmd->xocontainer);
+		xo_open_container(progname);
+		xo_open_container(xocontainer);
 
 		if (aflag) {
 			p = procstat_getprocs(prstat, KERN_PROC_PROC, 0, &cnt);
@@ -430,7 +484,7 @@ main(int argc, char *argv[])
 			l = strtol(argv[i], &dummy, 10);
 			if (*dummy == '\0') {
 				if (l < 0)
-					usage();
+					usage(cmd);
 				pid = l;
 
 				p = procstat_getprocs(prstat, KERN_PROC_PID,
@@ -441,26 +495,34 @@ main(int argc, char *argv[])
 					procstat(cmd, prstat, p);
 				procstat_freeprocs(prstat, p);
 			} else {
-				cprstat = procstat_open_core(argv[i]);
-				if (cprstat == NULL) {
-					warnx("procstat_open()");
-					continue;
+				if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
+					cprstat = procstat_open_core(argv[i]);
+					if (cprstat == NULL) {
+						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. */
-			procstat_opts |= PS_OPT_NOHEADER;
+			if ((cmd->cmp & PS_MODE_COMPAT) == 0) {
+				/* Suppress header after first process. */
+				procstat_opts |= PS_OPT_NOHEADER;
+			}
 		}
 
-		xo_close_container(cmd->xocontainer);
-		xo_close_container("procstat");
+		xo_close_container(xocontainer);
+		xo_close_container(progname);
 		xo_finish();
 		if (interval)
 			sleep(interval);
@@ -480,7 +542,7 @@ cmdopt_none(int argc, char * const argv[])
 		switch (ch) {
 		case '?':
 		default:
-			usage();
+			usage(NULL);
 		}
 	}
 }
@@ -497,7 +559,7 @@ cmdopt_verbose(int argc, char * const argv[])
 			break;
 		case '?':
 		default:
-			usage();
+			usage(NULL);
 		}
 	}
 }
@@ -514,7 +576,7 @@ cmdopt_signals(int argc, char * const argv[])
 			break;
 		case '?':
 		default:
-			usage();
+			usage(NULL);
 		}
 	}
 }
@@ -533,7 +595,7 @@ cmdopt_rusage(int argc, char * const argv[])
 			break;
 		case '?':
 		default:
-			usage();
+			usage(NULL);
 		}
 	}
 }
@@ -550,7 +612,7 @@ cmdopt_files(int argc, char * const argv[])
 			break;
 		case '?':
 		default:
-			usage();
+			usage(NULL);
 		}
 	}
 }

Modified: head/usr.bin/procstat/procstat.h
==============================================================================
--- head/usr.bin/procstat/procstat.h	Fri Sep 18 12:37:41 2020	(r365879)
+++ head/usr.bin/procstat/procstat.h	Fri Sep 18 12:59:27 2020	(r365880)
@@ -42,7 +42,8 @@ enum {
 	PS_OPT_NOHEADER		= 0x02,
 	PS_OPT_PERTHREAD	= 0x04,
 	PS_OPT_SIGNUM		= 0x08,
-	PS_OPT_VERBOSE		= 0x10
+	PS_OPT_VERBOSE		= 0x10,
+	PS_MODE_COMPAT		= 0x20,
 };
 
 #define PS_SUBCOMMAND_OPTS			\
@@ -64,7 +65,10 @@ void	procstat_cs(struct procstat *prstat, struct kinfo
 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);
+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_pwdx(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_sigfastblock(struct procstat *procstat,

Modified: head/usr.bin/procstat/procstat_kstack.c
==============================================================================
--- head/usr.bin/procstat/procstat_kstack.c	Fri Sep 18 12:37:41 2020	(r365879)
+++ head/usr.bin/procstat/procstat_kstack.c	Fri Sep 18 12:59:27 2020	(r365880)
@@ -68,7 +68,7 @@ kstack_nextstate(enum trace_state ts)
 		return (TS_OFF);
 
 	case TS_OFF:
-		return TS_FRAMENUM;
+		return (TS_FRAMENUM);
 
 	default:
 		errx(-1, "kstack_nextstate");

Added: head/usr.bin/procstat/procstat_penv.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/procstat/procstat_penv.c	Fri Sep 18 12:59:27 2020	(r365880)
@@ -0,0 +1,86 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Juraj Lutter <juraj at 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]);
+		}
+	}
+}

Added: head/usr.bin/procstat/procstat_pwdx.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/procstat/procstat_pwdx.c	Fri Sep 18 12:59:27 2020	(r365880)
@@ -0,0 +1,70 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Juraj Lutter <juraj at 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);
+}


More information about the svn-src-all mailing list