Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
@@ -24,10 +24,11 @@
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018 Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/loadavg.h>
@@ -84,17 +85,17 @@
#define PSINFO_HEADER_PROC \
" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP "
#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 \
" NLWP USERNAME SWAP RSS MEMORY TIME CPU "
#define TASK_HEADER_PROC \
@@ -108,16 +109,16 @@
#define ZONE_HEADER_PROC \
"ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE "
#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 \
"%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
#define PROJECT_LINE \
@@ -170,11 +171,11 @@
static long pagesize;
/* 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 */
-1, /* number of iterations; infinitely */
OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
@@ -359,15 +360,16 @@
char dfl[4], lck[4], slp[4], lat[4];
char vcx[4], icx[4], scl[4], sig[4];
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;
if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) {
@@ -383,58 +385,63 @@
print_timestamp();
if (opts.o_outpmode & OPT_TTY)
(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');
for (i = 0; i < list->l_used; i++) {
@@ -497,19 +504,18 @@
(void) putp(t_eol);
(void) putchar('\n');
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);
Format_state(pstate,
lwp->li_info.pr_lwp.pr_sname,
@@ -534,25 +540,21 @@
else
Format_time(ptime,
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');
}
if (opts.o_outpmode & OPT_MSACCT) {
@@ -568,16 +570,15 @@
Format_pct(dfl, lwp->li_dfl, 4);
Format_pct(lck, lwp->li_lck, 4);
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');
}
break;
}
@@ -875,10 +876,31 @@
(void) memcpy(&lwp->li_info, psinfo, sizeof (psinfo_t));
lwp->li_info.pr_lwp.pr_pctcpu = lwp->li_info.pr_pctcpu;
}
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;
pid_t pid = psinfo->pr_pid;
id_t lwpid = lwpsinfo->pr_lwpid;
@@ -889,10 +911,11 @@
lwp->li_flags |= LWP_ALIVE;
lwp->li_flags |= flags;
(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
prstat_scandir(DIR *procdir)
{
@@ -1111,11 +1134,11 @@
}
}
}
static void
-curses_on()
+curses_on(void)
{
if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
(void) initscr();
(void) nonl();
(void) putp(t_smcup);
@@ -1122,11 +1145,11 @@
is_curses_on = TRUE;
}
}
static void
-curses_off()
+curses_off(void)
{
if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
(void) putp(t_rmcup);
(void) endwin();
is_curses_on = FALSE;
@@ -1133,30 +1156,44 @@
}
(void) fflush(stdout);
}
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) &&
(opts.o_outpmode & OPT_USEHOME)) {
movecur = t_home;
@@ -1182,21 +1219,23 @@
for (i = 0; i <= n; i++)
(void) strcat(movecur, t_up);
}
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);
}
n = n - 3; /* minus header, total and cursor lines */