--- old/usr/src/cmd/prstat/prstat.c	Mon Oct 15 13:24:41 2018
+++ new/usr/src/cmd/prstat/prstat.c	Mon Oct 15 13:24:41 2018
@@ -26,6 +26,7 @@
  * Use is subject to license terms.
  *
  * Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018 Joyent, Inc.  All rights reserved.
  */
 
 #include <sys/types.h>
@@ -86,13 +87,13 @@
 #define	PSINFO_HEADER_PROC_LGRP \
 "   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU LGRP PROCESS/NLWP  "
 #define	PSINFO_HEADER_LWP \
-"   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/LWPID      "
+"   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/LWP        "
 #define	PSINFO_HEADER_LWP_LGRP \
-"   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU LGRP PROCESS/LWPID "
+"   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU LGRP PROCESS/LWP   "
 #define	USAGE_HEADER_PROC \
 "   PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP  "
 #define	USAGE_HEADER_LWP \
-"   PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID "
+"   PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWP   "
 #define	USER_HEADER_PROC \
 " NPROC USERNAME  SWAP   RSS MEMORY      TIME  CPU                             "
 #define	USER_HEADER_LWP \
@@ -110,12 +111,12 @@
 #define	ZONE_HEADER_LWP \
 "ZONEID     NLWP  SWAP   RSS MEMORY      TIME  CPU ZONE                        "
 #define	PSINFO_LINE \
-"%6d %-8s %5s %5s %-6s %3s  %3s %9s %3.3s%% %-.16s/%d"
+"%6d %-8s %5s %5s %-6s %3s  %3s %9s %3.3s%% %s"
 #define	PSINFO_LINE_LGRP \
-"%6d %-8s %5s %5s %-6s %3s  %3s %9s %3.3s%% %4d %-.16s/%d"
+"%6d %-8s %5s %5s %-6s %3s  %3s %9s %3.3s%% %4d %s"
 #define	USAGE_LINE \
 "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\
-"%3.3s %3.3s %-.12s/%d"
+"%3.3s %3.3s %s"
 #define	USER_LINE \
 "%6d %-8s %5.5s %5.5s   %3.3s%% %9s %3.3s%%"
 #define	TASK_LINE \
@@ -149,8 +150,8 @@
 static table_t	tsk_tbl = {0, 0, NULL};		/* selected tasks */
 static table_t	lgr_tbl = {0, 0, NULL};		/* selected lgroups */
 static zonetbl_t zone_tbl = {0, 0, NULL};	/* selected zones */
-static uidtbl_t euid_tbl = {0, 0, NULL}; 	/* selected effective users */
-static uidtbl_t ruid_tbl = {0, 0, NULL}; 	/* selected real users */
+static uidtbl_t euid_tbl = {0, 0, NULL};	/* selected effective users */
+static uidtbl_t ruid_tbl = {0, 0, NULL};	/* selected real users */
 
 static uint_t	total_procs;			/* total number of procs */
 static uint_t	total_lwps;			/* total number of lwps */
@@ -172,7 +173,7 @@
 
 /* default settings */
 
-static optdesc_t opts = {
+optdesc_t opts = {
 	5,			/* interval between updates, seconds */
 	15,			/* number of lines in top part */
 	5,			/* number of lines in bottom part */
@@ -361,11 +362,12 @@
 	char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12];
 	char pstate[7], pnice[4], ppri[4];
 	char pname[LOGNAME_MAX+1];
+	char name[PRFNSZ + THREAD_NAME_MAX + 2];
 	char projname[PROJNAME_MAX+1];
 	char zonename[ZONENAME_MAX+1];
 	float cpu, mem;
 	double loadavg[3] = {0, 0, 0};
-	int i, lwpid;
+	int i, n;
 
 	if (list->l_size == 0)
 		return;
@@ -385,54 +387,59 @@
 		(void) putchar('\r');
 	(void) putp(t_ulon);
 
+	n = opts.o_cols;
 	switch (list->l_type) {
 	case LT_PROJECTS:
 		if (opts.o_outpmode & OPT_LWPS)
-			(void) printf(PROJECT_HEADER_LWP);
+			n = printf(PROJECT_HEADER_LWP);
 		else
-			(void) printf(PROJECT_HEADER_PROC);
+			n = printf(PROJECT_HEADER_PROC);
 		break;
 	case LT_TASKS:
 		if (opts.o_outpmode & OPT_LWPS)
-			(void) printf(TASK_HEADER_LWP);
+			n = printf(TASK_HEADER_LWP);
 		else
-			(void) printf(TASK_HEADER_PROC);
+			n = printf(TASK_HEADER_PROC);
 		break;
 	case LT_ZONES:
 		if (opts.o_outpmode & OPT_LWPS)
-			(void) printf(ZONE_HEADER_LWP);
+			n = printf(ZONE_HEADER_LWP);
 		else
-			(void) printf(ZONE_HEADER_PROC);
+			n = printf(ZONE_HEADER_PROC);
 		break;
 	case LT_USERS:
 		if (opts.o_outpmode & OPT_LWPS)
-			(void) printf(USER_HEADER_LWP);
+			n = printf(USER_HEADER_LWP);
 		else
-			(void) printf(USER_HEADER_PROC);
+			n = printf(USER_HEADER_PROC);
 		break;
 	case LT_LWPS:
 		if (opts.o_outpmode & OPT_LWPS) {
 			if (opts.o_outpmode & OPT_PSINFO) {
 				if (opts.o_outpmode & OPT_LGRP)
-					(void) printf(PSINFO_HEADER_LWP_LGRP);
+					n = printf(PSINFO_HEADER_LWP_LGRP);
 				else
-					(void) printf(PSINFO_HEADER_LWP);
+					n = printf(PSINFO_HEADER_LWP);
 			}
 			if (opts.o_outpmode & OPT_MSACCT)
-				(void) printf(USAGE_HEADER_LWP);
+				n = printf(USAGE_HEADER_LWP);
 		} else {
 			if (opts.o_outpmode & OPT_PSINFO) {
 				if (opts.o_outpmode & OPT_LGRP)
-					(void) printf(PSINFO_HEADER_PROC_LGRP);
+					n = printf(PSINFO_HEADER_PROC_LGRP);
 				else
-					(void) printf(PSINFO_HEADER_PROC);
+					n = printf(PSINFO_HEADER_PROC);
 			}
 			if (opts.o_outpmode & OPT_MSACCT)
-				(void) printf(USAGE_HEADER_PROC);
+				n = printf(USAGE_HEADER_PROC);
 		}
 		break;
 	}
 
+	/* Pad out the header line so the underline spans the whole width */
+	if ((opts.o_outpmode & OPT_TERMCAP) && n < opts.o_cols)
+		(void) printf("%*s", (int)(opts.o_cols - n), "");
+
 	(void) putp(t_uloff);
 	(void) putp(t_eol);
 	(void) putchar('\n');
@@ -499,15 +506,14 @@
 			break;
 		case LT_LWPS:
 			lwp = list->l_ptrs[i];
-			if (opts.o_outpmode & OPT_LWPS)
-				lwpid = lwp->li_info.pr_lwp.pr_lwpid;
-			else
-				lwpid = lwp->li_info.pr_nlwp +
-				    lwp->li_info.pr_nzomb;
+
+			format_name(lwp, name, sizeof (name));
+
 			pwd_getname(lwp->li_info.pr_uid, pname, sizeof (pname),
 			    opts.o_outpmode & OPT_NORESOLVE,
 			    opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
 			    LOGIN_WIDTH);
+
 			if (opts.o_outpmode & OPT_PSINFO) {
 				Format_size(psize, lwp->li_info.pr_size, 6);
 				Format_size(prssize, lwp->li_info.pr_rssize, 6);
@@ -536,21 +542,17 @@
 					    lwp->li_info.pr_time.tv_sec, 10);
 				if (opts.o_outpmode & OPT_TTY)
 					(void) putchar('\r');
-				stripfname(lwp->li_info.pr_fname);
 				if (opts.o_outpmode & OPT_LGRP) {
 					(void) printf(PSINFO_LINE_LGRP,
 					    (int)lwp->li_info.pr_pid, pname,
 					    psize, prssize, pstate,
 					    ppri, pnice, ptime, pcpu,
-					    (int)lwp->li_info.pr_lwp.pr_lgrp,
-					    lwp->li_info.pr_fname, lwpid);
+					    lwp->li_info.pr_lwp.pr_lgrp, name);
 				} else {
 					(void) printf(PSINFO_LINE,
 					    (int)lwp->li_info.pr_pid, pname,
-					    psize, prssize,
-					    pstate, ppri, pnice,
-					    ptime, pcpu,
-					    lwp->li_info.pr_fname, lwpid);
+					    psize, prssize, pstate, ppri, pnice,
+					    ptime, pcpu, name);
 				}
 				(void) putp(t_eol);
 				(void) putchar('\n');
@@ -570,12 +572,11 @@
 				Format_pct(lat, lwp->li_lat, 4);
 				if (opts.o_outpmode & OPT_TTY)
 					(void) putchar('\r');
-				stripfname(lwp->li_info.pr_fname);
 				(void) printf(USAGE_LINE,
 				    (int)lwp->li_info.pr_pid, pname,
 				    usr, sys, trp, tfl, dfl, lck,
 				    slp, lat, vcx, icx, scl, sig,
-				    lwp->li_info.pr_fname, lwpid);
+				    name);
 				(void) putp(t_eol);
 				(void) putchar('\n');
 			}
@@ -877,6 +878,27 @@
 }
 
 static void
+get_lwpname(pid_t pid, id_t lwpid, char *buf, size_t bufsize)
+{
+	char *path = NULL;
+	int fd;
+
+	buf[0] = '\0';
+
+	if (asprintf(&path, "/proc/%d/lwp/%d/lwpname",
+	    (int)pid, (int)lwpid) == -1)
+		return;
+
+	if ((fd = open(path, O_RDONLY)) != -1) {
+		(void) read(fd, buf, bufsize);
+		buf[bufsize - 1] = '\0';
+		(void) close(fd);
+	}
+
+	free(path);
+}
+
+static void
 add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags)
 {
 	lwp_info_t *lwp;
@@ -891,6 +913,7 @@
 	(void) memcpy(&lwp->li_info, psinfo,
 	    sizeof (psinfo_t) - sizeof (lwpsinfo_t));
 	(void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t));
+	get_lwpname(pid, lwpid, lwp->li_lwpname, sizeof (lwp->li_lwpname));
 }
 
 static void
@@ -1113,7 +1136,7 @@
 }
 
 static void
-curses_on()
+curses_on(void)
 {
 	if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
 		(void) initscr();
@@ -1124,7 +1147,7 @@
 }
 
 static void
-curses_off()
+curses_off(void)
 {
 	if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
 		(void) putp(t_rmcup);
@@ -1135,26 +1158,40 @@
 }
 
 static int
-nlines()
+nlines(int *linesp, int *colsp)
 {
 	struct winsize ws;
 	char *envp;
 	int n;
+
+	*linesp = -1;
+	*colsp = -1;
 	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
 		if (ws.ws_row > 0)
-			return (ws.ws_row);
+			*linesp = ws.ws_row;
+		if (ws.ws_col > 0)
+			*colsp = ws.ws_col;
+		if (ws.ws_row > 0 && ws.ws_col > 0)
+			return (0);
 	}
-	if (envp = getenv("LINES")) {
+
+	if ((envp = getenv("LINES")) != NULL) {
 		if ((n = Atoi(envp)) > 0) {
 			opts.o_outpmode &= ~OPT_USEHOME;
-			return (n);
+			*linesp = n;
 		}
 	}
-	return (-1);
+	if ((envp = getenv("COLUMNS")) != NULL) {
+		if ((n = Atoi(envp)) > 0) {
+			*colsp = n;
+		}
+	}
+
+	return ((*linesp > 0 && *colsp > 0) ? 0 : -1);
 }
 
 static void
-setmovecur()
+setmovecur(void)
 {
 	int i, n;
 	if ((opts.o_outpmode & OPT_FULLSCREEN) &&
@@ -1184,17 +1221,19 @@
 }
 
 static int
-setsize()
+setsize(void)
 {
 	static int oldn = 0;
-	int n;
+	int cols, n, ret;
 
 	if (opts.o_outpmode & OPT_FULLSCREEN) {
-		n = nlines();
+		ret = nlines(&n, &cols);
+		if (ret != -1)
+			opts.o_cols = cols;
 		if (n == oldn)
 			return (0);
 		oldn = n;
-		if (n == -1) {
+		if (ret == -1) {
 			opts.o_outpmode &= ~OPT_USEHOME;
 			setmovecur();		/* set default window size */
 			return (1);
