164 static list_t   zones;                          /* list of zones */
 165 static list_t   lgroups;                        /* list of lgroups */
 166 
 167 static volatile uint_t sigwinch = 0;
 168 static volatile uint_t sigtstp = 0;
 169 static volatile uint_t sigterm = 0;
 170 
 171 static long pagesize;
 172 
 173 /* default settings */
 174 
 175 static optdesc_t opts = {
 176         5,                      /* interval between updates, seconds */
 177         15,                     /* number of lines in top part */
 178         5,                      /* number of lines in bottom part */
 179         -1,                     /* number of iterations; infinitely */
 180         OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
 181         -1                      /* sort in decreasing order */
 182 };
 183 
 184 /*
 185  * Print timestamp as decimal reprentation of time_t value (-d u was specified)
 186  * or the standard date format (-d d was specified).
 187  */
 188 static void
 189 print_timestamp(void)
 190 {
 191         time_t t = time(NULL);
 192         static char *fmt = NULL;
 193 
 194         /* We only need to retrieve this once per invocation */
 195         if (fmt == NULL)
 196                 fmt = nl_langinfo(_DATE_FMT);
 197 
 198         if (opts.o_outpmode & OPT_UDATE) {
 199                 (void) printf("%ld", t);
 200         } else if (opts.o_outpmode & OPT_DDATE) {
 201                 char dstr[64];
 202                 int len;
 203 
 
 831                     TIME2NSEC(lwp->li_usage.pr_ttime))/period;
 832                 lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) -
 833                     TIME2NSEC(lwp->li_usage.pr_tftime))/period;
 834                 lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) -
 835                     TIME2NSEC(lwp->li_usage.pr_dftime))/period;
 836                 lwp->li_lck = (TIME2NSEC(usage->pr_ltime) -
 837                     TIME2NSEC(lwp->li_usage.pr_ltime))/period;
 838                 lwp->li_lat = (TIME2NSEC(usage->pr_wtime) -
 839                     TIME2NSEC(lwp->li_usage.pr_wtime))/period;
 840                 lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx;
 841                 lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx;
 842                 lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc;
 843                 lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
 844                 (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
 845         }
 846 }
 847 
 848 static int
 849 read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
 850 {
 851         char procfile[MAX_PROCFS_PATH];
 852 
 853         (void) snprintf(procfile, MAX_PROCFS_PATH,
 854             "/proc/%s/%s", pidstr, file);
 855         if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL)
 856                 return (1);
 857         if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) {
 858                 fd_close(*fd);
 859                 return (1);
 860         }
 861         return (0);
 862 }
 863 
 864 static void
 865 add_proc(psinfo_t *psinfo)
 866 {
 867         lwp_info_t *lwp;
 868         id_t lwpid;
 869         pid_t pid = psinfo->pr_pid;
 870 
 871         lwpid = psinfo->pr_lwp.pr_lwpid;
 872         if ((lwp = lwpid_get(pid, lwpid)) == NULL)
 873                 lwp = list_add_lwp(&lwps, pid, lwpid);
 
1359         curses_off();
1360         list_clear(&lwps);
1361         list_clear(&users);
1362         list_clear(&tasks);
1363         list_clear(&projects);
1364         list_clear(&zones);
1365         fd_exit();
1366 }
1367 
1368 
1369 int
1370 main(int argc, char **argv)
1371 {
1372         DIR *procdir;
1373         char *p;
1374         char *sortk = "cpu";    /* default sort key */
1375         int opt;
1376         int timeout;
1377         struct pollfd pollset;
1378         char key;
1379 
1380         (void) setlocale(LC_ALL, "");
1381         (void) textdomain(TEXT_DOMAIN);
1382         Progname(argv[0]);
1383         lwpid_init();
1384         fd_init(Setrlimit());
1385 
1386         pagesize = sysconf(_SC_PAGESIZE);
1387 
1388         while ((opt = getopt(argc, argv,
1389             "vcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) {
1390                 switch (opt) {
1391                 case 'r':
1392                         opts.o_outpmode |= OPT_NORESOLVE;
1393                         break;
1394                 case 'R':
1395                         opts.o_outpmode |= OPT_REALTIME;
1396                         break;
1397                 case 'c':
1398                         opts.o_outpmode &= ~OPT_TERMCAP;
 
1558                 opts.o_outpmode &= ~OPT_FULLSCREEN;
1559         }
1560         if (opts.o_outpmode & OPT_TERMCAP)
1561                 ldtermcap();            /* can turn OPT_TERMCAP off */
1562         if (opts.o_outpmode & OPT_TERMCAP)
1563                 (void) setsize();
1564         list_alloc(&lwps, opts.o_ntop);
1565         list_alloc(&users, opts.o_nbottom);
1566         list_alloc(&tasks, opts.o_nbottom);
1567         list_alloc(&projects, opts.o_nbottom);
1568         list_alloc(&zones, opts.o_nbottom);
1569         list_alloc(&lgroups, opts.o_nbottom);
1570         list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS);
1571         list_setkeyfunc(NULL, &opts, &users, LT_USERS);
1572         list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS);
1573         list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS);
1574         list_setkeyfunc(NULL, &opts, &zones, LT_ZONES);
1575         list_setkeyfunc(NULL, &opts, &lgroups, LT_LGRPS);
1576         if (opts.o_outpmode & OPT_TERMCAP)
1577                 curses_on();
1578         if ((procdir = opendir("/proc")) == NULL)
1579                 Die(gettext("cannot open /proc directory\n"));
1580         if (opts.o_outpmode & OPT_TTY) {
1581                 (void) printf(gettext("Please wait...\r"));
1582                 if (!(opts.o_outpmode & OPT_TERMCAP))
1583                         (void) putchar('\n');
1584                 (void) fflush(stdout);
1585         }
1586         set_signals();
1587         pollset.fd = STDIN_FILENO;
1588         pollset.events = POLLIN;
1589         timeout = opts.o_interval * MILLISEC;
1590 
1591         /*
1592          * main program loop
1593          */
1594         do {
1595                 if (sigterm == 1)
1596                         break;
1597                 if (sigtstp == 1) {
1598                         curses_off();
 
 | 
 
 
 164 static list_t   zones;                          /* list of zones */
 165 static list_t   lgroups;                        /* list of lgroups */
 166 
 167 static volatile uint_t sigwinch = 0;
 168 static volatile uint_t sigtstp = 0;
 169 static volatile uint_t sigterm = 0;
 170 
 171 static long pagesize;
 172 
 173 /* default settings */
 174 
 175 static optdesc_t opts = {
 176         5,                      /* interval between updates, seconds */
 177         15,                     /* number of lines in top part */
 178         5,                      /* number of lines in bottom part */
 179         -1,                     /* number of iterations; infinitely */
 180         OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
 181         -1                      /* sort in decreasing order */
 182 };
 183 
 184 
 185 static int
 186 proc_snprintf(char *_RESTRICT_KYWD s, size_t n,
 187     const char *_RESTRICT_KYWD fmt, ...)
 188 {
 189         static boolean_t ptools_zroot_valid = B_FALSE;
 190         static const char *ptools_zroot = NULL;
 191         va_list args;
 192         int ret, nret = 0;
 193 
 194         if (ptools_zroot_valid == B_FALSE) {
 195                 ptools_zroot_valid = B_TRUE;
 196                 ptools_zroot = zone_get_nroot();
 197         }
 198 
 199         if (ptools_zroot != NULL) {
 200                 nret = snprintf(s, n, "%s", ptools_zroot);
 201                 if (nret > n)
 202                         return (nret);
 203         }
 204         va_start(args, fmt);
 205         ret = vsnprintf(s + nret, n - nret, fmt, args);
 206         va_end(args);
 207 
 208         return (ret + nret);
 209 }
 210 
 211 /*
 212  * Print timestamp as decimal reprentation of time_t value (-d u was specified)
 213  * or the standard date format (-d d was specified).
 214  */
 215 static void
 216 print_timestamp(void)
 217 {
 218         time_t t = time(NULL);
 219         static char *fmt = NULL;
 220 
 221         /* We only need to retrieve this once per invocation */
 222         if (fmt == NULL)
 223                 fmt = nl_langinfo(_DATE_FMT);
 224 
 225         if (opts.o_outpmode & OPT_UDATE) {
 226                 (void) printf("%ld", t);
 227         } else if (opts.o_outpmode & OPT_DDATE) {
 228                 char dstr[64];
 229                 int len;
 230 
 
 858                     TIME2NSEC(lwp->li_usage.pr_ttime))/period;
 859                 lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) -
 860                     TIME2NSEC(lwp->li_usage.pr_tftime))/period;
 861                 lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) -
 862                     TIME2NSEC(lwp->li_usage.pr_dftime))/period;
 863                 lwp->li_lck = (TIME2NSEC(usage->pr_ltime) -
 864                     TIME2NSEC(lwp->li_usage.pr_ltime))/period;
 865                 lwp->li_lat = (TIME2NSEC(usage->pr_wtime) -
 866                     TIME2NSEC(lwp->li_usage.pr_wtime))/period;
 867                 lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx;
 868                 lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx;
 869                 lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc;
 870                 lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
 871                 (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
 872         }
 873 }
 874 
 875 static int
 876 read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
 877 {
 878         char procfile[PATH_MAX];
 879 
 880         (void) proc_snprintf(procfile, PATH_MAX,
 881             "/proc/%s/%s", pidstr, file);
 882         if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL)
 883                 return (1);
 884         if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) {
 885                 fd_close(*fd);
 886                 return (1);
 887         }
 888         return (0);
 889 }
 890 
 891 static void
 892 add_proc(psinfo_t *psinfo)
 893 {
 894         lwp_info_t *lwp;
 895         id_t lwpid;
 896         pid_t pid = psinfo->pr_pid;
 897 
 898         lwpid = psinfo->pr_lwp.pr_lwpid;
 899         if ((lwp = lwpid_get(pid, lwpid)) == NULL)
 900                 lwp = list_add_lwp(&lwps, pid, lwpid);
 
1386         curses_off();
1387         list_clear(&lwps);
1388         list_clear(&users);
1389         list_clear(&tasks);
1390         list_clear(&projects);
1391         list_clear(&zones);
1392         fd_exit();
1393 }
1394 
1395 
1396 int
1397 main(int argc, char **argv)
1398 {
1399         DIR *procdir;
1400         char *p;
1401         char *sortk = "cpu";    /* default sort key */
1402         int opt;
1403         int timeout;
1404         struct pollfd pollset;
1405         char key;
1406         char procpath[PATH_MAX];
1407 
1408         (void) setlocale(LC_ALL, "");
1409         (void) textdomain(TEXT_DOMAIN);
1410         Progname(argv[0]);
1411         lwpid_init();
1412         fd_init(Setrlimit());
1413 
1414         pagesize = sysconf(_SC_PAGESIZE);
1415 
1416         while ((opt = getopt(argc, argv,
1417             "vcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) {
1418                 switch (opt) {
1419                 case 'r':
1420                         opts.o_outpmode |= OPT_NORESOLVE;
1421                         break;
1422                 case 'R':
1423                         opts.o_outpmode |= OPT_REALTIME;
1424                         break;
1425                 case 'c':
1426                         opts.o_outpmode &= ~OPT_TERMCAP;
 
1586                 opts.o_outpmode &= ~OPT_FULLSCREEN;
1587         }
1588         if (opts.o_outpmode & OPT_TERMCAP)
1589                 ldtermcap();            /* can turn OPT_TERMCAP off */
1590         if (opts.o_outpmode & OPT_TERMCAP)
1591                 (void) setsize();
1592         list_alloc(&lwps, opts.o_ntop);
1593         list_alloc(&users, opts.o_nbottom);
1594         list_alloc(&tasks, opts.o_nbottom);
1595         list_alloc(&projects, opts.o_nbottom);
1596         list_alloc(&zones, opts.o_nbottom);
1597         list_alloc(&lgroups, opts.o_nbottom);
1598         list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS);
1599         list_setkeyfunc(NULL, &opts, &users, LT_USERS);
1600         list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS);
1601         list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS);
1602         list_setkeyfunc(NULL, &opts, &zones, LT_ZONES);
1603         list_setkeyfunc(NULL, &opts, &lgroups, LT_LGRPS);
1604         if (opts.o_outpmode & OPT_TERMCAP)
1605                 curses_on();
1606         (void) proc_snprintf(procpath, sizeof (procpath), "/proc");
1607         if ((procdir = opendir(procpath)) == NULL)
1608                 Die(gettext("cannot open /proc directory\n"));
1609         if (opts.o_outpmode & OPT_TTY) {
1610                 (void) printf(gettext("Please wait...\r"));
1611                 if (!(opts.o_outpmode & OPT_TERMCAP))
1612                         (void) putchar('\n');
1613                 (void) fflush(stdout);
1614         }
1615         set_signals();
1616         pollset.fd = STDIN_FILENO;
1617         pollset.events = POLLIN;
1618         timeout = opts.o_interval * MILLISEC;
1619 
1620         /*
1621          * main program loop
1622          */
1623         do {
1624                 if (sigterm == 1)
1625                         break;
1626                 if (sigtstp == 1) {
1627                         curses_off();
 
 |