Print this page
8158 Want named threads API
9857 proc manpages should have LIBRARY section
*** 24,33 ****
--- 24,34 ----
*
* 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,100 ****
#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 "
#define PSINFO_HEADER_LWP_LGRP \
! " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWPID "
#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 "
#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 \
--- 85,101 ----
#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/LWP "
#define PSINFO_HEADER_LWP_LGRP \
! " 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/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,123 ****
#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"
#define PSINFO_LINE_LGRP \
! "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d"
#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"
#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 \
--- 109,124 ----
#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%% %s"
#define PSINFO_LINE_LGRP \
! "%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 %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,180 ****
static long pagesize;
/* default settings */
! static 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,
--- 171,181 ----
static long pagesize;
/* default settings */
! 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,373 ****
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 projname[PROJNAME_MAX+1];
char zonename[ZONENAME_MAX+1];
float cpu, mem;
double loadavg[3] = {0, 0, 0};
! int i, lwpid;
if (list->l_size == 0)
return;
if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) {
--- 360,375 ----
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, n;
if (list->l_size == 0)
return;
if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) {
*** 383,440 ****
print_timestamp();
if (opts.o_outpmode & OPT_TTY)
(void) putchar('\r');
(void) putp(t_ulon);
switch (list->l_type) {
case LT_PROJECTS:
if (opts.o_outpmode & OPT_LWPS)
! (void) printf(PROJECT_HEADER_LWP);
else
! (void) printf(PROJECT_HEADER_PROC);
break;
case LT_TASKS:
if (opts.o_outpmode & OPT_LWPS)
! (void) printf(TASK_HEADER_LWP);
else
! (void) printf(TASK_HEADER_PROC);
break;
case LT_ZONES:
if (opts.o_outpmode & OPT_LWPS)
! (void) printf(ZONE_HEADER_LWP);
else
! (void) printf(ZONE_HEADER_PROC);
break;
case LT_USERS:
if (opts.o_outpmode & OPT_LWPS)
! (void) printf(USER_HEADER_LWP);
else
! (void) 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);
else
! (void) printf(PSINFO_HEADER_LWP);
}
if (opts.o_outpmode & OPT_MSACCT)
! (void) printf(USAGE_HEADER_LWP);
} else {
if (opts.o_outpmode & OPT_PSINFO) {
if (opts.o_outpmode & OPT_LGRP)
! (void) printf(PSINFO_HEADER_PROC_LGRP);
else
! (void) printf(PSINFO_HEADER_PROC);
}
if (opts.o_outpmode & OPT_MSACCT)
! (void) printf(USAGE_HEADER_PROC);
}
break;
}
(void) putp(t_uloff);
(void) putp(t_eol);
(void) putchar('\n');
for (i = 0; i < list->l_used; i++) {
--- 385,447 ----
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)
! n = printf(PROJECT_HEADER_LWP);
else
! n = printf(PROJECT_HEADER_PROC);
break;
case LT_TASKS:
if (opts.o_outpmode & OPT_LWPS)
! n = printf(TASK_HEADER_LWP);
else
! n = printf(TASK_HEADER_PROC);
break;
case LT_ZONES:
if (opts.o_outpmode & OPT_LWPS)
! n = printf(ZONE_HEADER_LWP);
else
! n = printf(ZONE_HEADER_PROC);
break;
case LT_USERS:
if (opts.o_outpmode & OPT_LWPS)
! n = printf(USER_HEADER_LWP);
else
! 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)
! n = printf(PSINFO_HEADER_LWP_LGRP);
else
! n = printf(PSINFO_HEADER_LWP);
}
if (opts.o_outpmode & OPT_MSACCT)
! n = printf(USAGE_HEADER_LWP);
} else {
if (opts.o_outpmode & OPT_PSINFO) {
if (opts.o_outpmode & OPT_LGRP)
! n = printf(PSINFO_HEADER_PROC_LGRP);
else
! n = printf(PSINFO_HEADER_PROC);
}
if (opts.o_outpmode & OPT_MSACCT)
! 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,515 ****
(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;
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,
--- 504,521 ----
(void) putp(t_eol);
(void) putchar('\n');
break;
case LT_LWPS:
lwp = list->l_ptrs[i];
!
! 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,558 ****
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);
} 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);
}
(void) putp(t_eol);
(void) putchar('\n');
}
if (opts.o_outpmode & OPT_MSACCT) {
--- 540,560 ----
else
Format_time(ptime,
lwp->li_info.pr_time.tv_sec, 10);
if (opts.o_outpmode & OPT_TTY)
(void) putchar('\r');
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,
! 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, name);
}
(void) putp(t_eol);
(void) putchar('\n');
}
if (opts.o_outpmode & OPT_MSACCT) {
*** 568,583 ****
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);
(void) putp(t_eol);
(void) putchar('\n');
}
break;
}
--- 570,584 ----
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');
(void) printf(USAGE_LINE,
(int)lwp->li_info.pr_pid, pname,
usr, sys, trp, tfl, dfl, lck,
slp, lat, vcx, icx, scl, sig,
! name);
(void) putp(t_eol);
(void) putchar('\n');
}
break;
}
*** 875,884 ****
--- 876,906 ----
(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,898 ****
--- 911,921 ----
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,1121 ****
}
}
}
static void
! curses_on()
{
if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
(void) initscr();
(void) nonl();
(void) putp(t_smcup);
--- 1134,1144 ----
}
}
}
static void
! curses_on(void)
{
if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
(void) initscr();
(void) nonl();
(void) putp(t_smcup);
*** 1122,1132 ****
is_curses_on = TRUE;
}
}
static void
! curses_off()
{
if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
(void) putp(t_rmcup);
(void) endwin();
is_curses_on = FALSE;
--- 1145,1155 ----
is_curses_on = TRUE;
}
}
static void
! curses_off(void)
{
if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
(void) putp(t_rmcup);
(void) endwin();
is_curses_on = FALSE;
*** 1133,1162 ****
}
(void) fflush(stdout);
}
static int
! nlines()
{
struct winsize ws;
char *envp;
int n;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
if (ws.ws_row > 0)
! return (ws.ws_row);
}
! if (envp = getenv("LINES")) {
if ((n = Atoi(envp)) > 0) {
opts.o_outpmode &= ~OPT_USEHOME;
! return (n);
}
}
! return (-1);
}
static void
! setmovecur()
{
int i, n;
if ((opts.o_outpmode & OPT_FULLSCREEN) &&
(opts.o_outpmode & OPT_USEHOME)) {
movecur = t_home;
--- 1156,1199 ----
}
(void) fflush(stdout);
}
static int
! 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)
! *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")) != NULL) {
if ((n = Atoi(envp)) > 0) {
opts.o_outpmode &= ~OPT_USEHOME;
! *linesp = n;
}
}
! if ((envp = getenv("COLUMNS")) != NULL) {
! if ((n = Atoi(envp)) > 0) {
! *colsp = n;
! }
! }
!
! return ((*linesp > 0 && *colsp > 0) ? 0 : -1);
}
static void
! setmovecur(void)
{
int i, n;
if ((opts.o_outpmode & OPT_FULLSCREEN) &&
(opts.o_outpmode & OPT_USEHOME)) {
movecur = t_home;
*** 1182,1202 ****
for (i = 0; i <= n; i++)
(void) strcat(movecur, t_up);
}
static int
! setsize()
{
static int oldn = 0;
! int n;
if (opts.o_outpmode & OPT_FULLSCREEN) {
! n = nlines();
if (n == oldn)
return (0);
oldn = n;
! if (n == -1) {
opts.o_outpmode &= ~OPT_USEHOME;
setmovecur(); /* set default window size */
return (1);
}
n = n - 3; /* minus header, total and cursor lines */
--- 1219,1241 ----
for (i = 0; i <= n; i++)
(void) strcat(movecur, t_up);
}
static int
! setsize(void)
{
static int oldn = 0;
! int cols, n, ret;
if (opts.o_outpmode & OPT_FULLSCREEN) {
! ret = nlines(&n, &cols);
! if (ret != -1)
! opts.o_cols = cols;
if (n == oldn)
return (0);
oldn = n;
! if (ret == -1) {
opts.o_outpmode &= ~OPT_USEHOME;
setmovecur(); /* set default window size */
return (1);
}
n = n - 3; /* minus header, total and cursor lines */