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 */