summaryrefslogtreecommitdiff
path: root/usr/src/cmd/ps/ps.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/ps/ps.c')
-rw-r--r--usr/src/cmd/ps/ps.c201
1 files changed, 121 insertions, 80 deletions
diff --git a/usr/src/cmd/ps/ps.c b/usr/src/cmd/ps/ps.c
index 1a3e91689a..1387a9440a 100644
--- a/usr/src/cmd/ps/ps.c
+++ b/usr/src/cmd/ps/ps.c
@@ -27,7 +27,7 @@
*/
/*
- * Copyright (c) 2018, Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -64,6 +64,8 @@
#include <sys/pset.h>
#include <project.h>
#include <zone.h>
+#include <assert.h>
+#include <stdbool.h>
#define min(a, b) ((a) > (b) ? (b) : (a))
#define max(a, b) ((a) < (b) ? (b) : (a))
@@ -288,7 +290,7 @@ static int nzoneid = 0;
static int kbytes_per_page;
static int pidwidth;
-static char *procdir = "/proc"; /* standard /proc directory */
+static char procdir[MAXPATHLEN]; /* standard /proc directory */
static struct ughead euid_tbl; /* table to store selected euid's */
static struct ughead ruid_tbl; /* table to store selected real uid's */
@@ -337,10 +339,22 @@ static int pidcmp(const void *p1, const void *p2);
extern int ucbmain(int, char **);
static int stdmain(int, char **);
+/* also used by ucbps.c */
+void get_psargs(bool, bool, psinfo_t *, char *, size_t);
+void print_psargs(char *, int);
+
int
main(int argc, char **argv)
{
const char *me;
+ const char *zroot = zone_get_nroot();
+
+ /*
+ * If this is a branded zone, the native procfs may mounted in a
+ * non-standard location. Apply such a path prefix if it exists.
+ */
+ (void) snprintf(procdir, sizeof (procdir), "%s/proc", zroot != NULL ?
+ zroot : "");
/*
* The original two ps'es are linked in a single binary;
@@ -1362,14 +1376,12 @@ prfind(int found, psinfo_t *psinfo, char **tpp)
static void
prcom(psinfo_t *psinfo, char *ttyp)
{
- char *cp;
- long tm;
- int bytesleft;
- int wcnt, length;
- wchar_t wchar;
+ long tm;
+ int wcnt;
struct passwd *pwd;
- int zombie_lwp;
- char zonename[ZONENAME_MAX];
+ int zombie_lwp;
+ char zonename[ZONENAME_MAX];
+ char psargs[PRMAXARGVLEN] = "";
/*
* If process is zombie, call zombie print routine and return.
@@ -1558,44 +1570,22 @@ prcom(psinfo_t *psinfo, char *ttyp)
if (psinfo->pr_time.tv_nsec > 500000000)
tm++;
}
- (void) printf(" %4ld:%.2ld", tm / 60, tm % 60); /* [L]TIME */
+ (void) printf(" %4ld:%.2ld ", tm / 60, tm % 60); /* [L]TIME */
if (zombie_lwp) {
- (void) printf(" <defunct>\n");
+ (void) printf("<defunct>\n");
return;
}
if (!fflg) { /* CMD */
wcnt = namencnt(psinfo->pr_fname, 16, 8);
- (void) printf(" %.*s\n", wcnt, psinfo->pr_fname);
+ (void) printf("%.*s\n", wcnt, psinfo->pr_fname);
return;
}
-
- /*
- * PRARGSZ == length of cmd arg string.
- */
- psinfo->pr_psargs[PRARGSZ-1] = '\0';
- bytesleft = PRARGSZ;
- for (cp = psinfo->pr_psargs; *cp != '\0'; cp += length) {
- length = mbtowc(&wchar, cp, MB_LEN_MAX);
- if (length == 0)
- break;
- if (length < 0 || !iswprint(wchar)) {
- if (length < 0)
- length = 1;
- if (bytesleft <= length) {
- *cp = '\0';
- break;
- }
- /* omit the unprintable character */
- (void) memmove(cp, cp+length, bytesleft-length);
- length = 0;
- }
- bytesleft -= length;
- }
- wcnt = namencnt(psinfo->pr_psargs, PRARGSZ, lflg ? 35 : PRARGSZ);
- (void) printf(" %.*s\n", wcnt, psinfo->pr_psargs);
+ get_psargs(false, fflg, psinfo, psargs, sizeof (psargs));
+ print_psargs(psargs, 0);
+ printf("\n");
}
/*
@@ -1650,20 +1640,98 @@ print_time(time_t tim, int width)
(void) printf("%*s", width, buf);
}
+void
+get_psargs(bool comm, bool full, psinfo_t *psinfo, char *buf, size_t bufsize)
+{
+ char *path = NULL;
+ ssize_t size = 0;
+ char *cp;
+ int fd;
+
+ assert(psinfo->pr_psargs[PRARGSZ - 1] == '\0');
+
+ if (full && getenv("SHORT_PSARGS") == NULL &&
+ asprintf(&path, "%s/%d/cmdline", procdir,
+ (int)psinfo->pr_pid) != -1 && (fd = open(path, O_RDONLY)) != -1) {
+ size = read(fd, buf, bufsize);
+ (void) close(fd);
+ }
+
+ free(path);
+
+ if (size <= 0) {
+ (void) strlcpy(buf, psinfo->pr_psargs, bufsize);
+ } else {
+ ssize_t i;
+
+ buf[bufsize - 1] = '\0';
+
+ for (cp = buf; cp - buf < size; cp++) {
+ if (*cp == '\0' && (cp - buf) + 1 < size)
+ *cp = ' ';
+ }
+
+ for (i = strlen(buf) - 1; i >= 0 && isspace(buf[i]); i--) {
+ buf[i] = '\0';
+ }
+ }
+
+ if (comm && (cp = strpbrk(buf, " \t\r\v\f\n")) != NULL)
+ *cp = '\0';
+}
+
+void
+print_psargs(char *psargs, int width)
+{
+ int bytesleft;
+ int length;
+ char *cp;
+ int wcnt;
+
+ bytesleft = strlen(psargs);
+
+ for (cp = psargs; *cp != '\0'; cp += length) {
+ wchar_t wchar;
+
+ length = mbtowc(&wchar, cp, MB_LEN_MAX);
+
+ if (length == 0)
+ break;
+
+ if (length < 0 || !iswprint(wchar)) {
+ if (length < 0)
+ length = 1;
+ if (bytesleft <= length) {
+ *cp = '\0';
+ break;
+ }
+ /* omit the unprintable character */
+ (void) memmove(cp, cp + length, bytesleft - length);
+ bytesleft -= length;
+ length = 0;
+ }
+ bytesleft -= length;
+ }
+
+ wcnt = namencnt(psargs, PRMAXARGVLEN, width);
+
+ if (width != 0) {
+ (void) printf("%.*s", width, psargs);
+ } else {
+ (void) printf("%-.*s", wcnt, psargs);
+ }
+}
+
static void
print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
{
+ char psargs[PRMAXARGVLEN] = "";
int width = f->width;
struct passwd *pwd;
struct group *grp;
time_t cputime;
- int bytesleft;
int wcnt;
- wchar_t wchar;
- char *cp;
- int length;
ulong_t mask;
- char c = '\0', *csave = NULL;
int zombie_lwp;
zombie_lwp = (Lflg && psinfo->pr_lwp.pr_sname == 'Z');
@@ -1916,12 +1984,11 @@ print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
(void) printf("%s", "<defunct>");
break;
}
- csave = strpbrk(psinfo->pr_psargs, " \t\r\v\f\n");
- if (csave) {
- c = *csave;
- *csave = '\0';
- }
- /* FALLTHROUGH */
+
+ get_psargs(true, false, psinfo, psargs, sizeof (psargs));
+ print_psargs(psargs, f->next != NULL ? width : 0);
+ break;
+
case F_ARGS:
/*
* PRARGSZ == length of cmd arg string.
@@ -1930,38 +1997,11 @@ print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
(void) printf("%-*s", width, "<defunct>");
break;
}
- psinfo->pr_psargs[PRARGSZ-1] = '\0';
- bytesleft = PRARGSZ;
- for (cp = psinfo->pr_psargs; *cp != '\0'; cp += length) {
- length = mbtowc(&wchar, cp, MB_LEN_MAX);
- if (length == 0)
- break;
- if (length < 0 || !iswprint(wchar)) {
- if (length < 0)
- length = 1;
- if (bytesleft <= length) {
- *cp = '\0';
- break;
- }
- /* omit the unprintable character */
- (void) memmove(cp, cp+length, bytesleft-length);
- length = 0;
- }
- bytesleft -= length;
- }
- wcnt = namencnt(psinfo->pr_psargs, PRARGSZ, width);
- /*
- * Print full width unless this is the last format.
- */
- if (f->next != NULL)
- (void) printf("%-*.*s", width, wcnt,
- psinfo->pr_psargs);
- else
- (void) printf("%-.*s", wcnt,
- psinfo->pr_psargs);
- if (f->fname == F_COMM && csave)
- *csave = c;
+
+ get_psargs(false, fflg, psinfo, psargs, sizeof (psargs));
+ print_psargs(psargs, f->next != NULL ? width : 0);
break;
+
case F_TASKID:
(void) printf("%*d", width, (int)psinfo->pr_taskid);
break;
@@ -2422,7 +2462,8 @@ namencnt(char *cmd, int csisize, int scrsize)
return (8); /* default to use for illegal chars */
if ((nscrsz = wcwidth(wchar)) <= 0)
return (8);
- if (csiwcnt + ncsisz > csisize || scrwcnt + nscrsz > scrsize)
+ if (csiwcnt + ncsisz > csisize ||
+ (scrsize != 0 && scrwcnt + nscrsz > scrsize))
break;
csiwcnt += ncsisz;
scrwcnt += nscrsz;