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