17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5c6402783Sakolb * Common Development and Distribution License (the "License").
6c6402783Sakolb * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21c6402783Sakolb
227c478bd9Sstevel@tonic-gate /*
230a1278f2SGary Mills * Copyright (c) 2013 Gary Mills
240a1278f2SGary Mills *
254944376cSJohn Levon * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
267c478bd9Sstevel@tonic-gate * Use is subject to license terms.
277166d658SMenno Lageman *
287166d658SMenno Lageman * Portions Copyright 2009 Chad Mynhier
29*ab618543SJohn Levon * Copyright 2018 Joyent, Inc. All rights reserved.
307c478bd9Sstevel@tonic-gate */
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/resource.h>
347c478bd9Sstevel@tonic-gate #include <sys/loadavg.h>
357c478bd9Sstevel@tonic-gate #include <sys/time.h>
367c478bd9Sstevel@tonic-gate #include <sys/pset.h>
370209230bSgjelinek #include <sys/vm_usage.h>
387c478bd9Sstevel@tonic-gate #include <zone.h>
397c478bd9Sstevel@tonic-gate #include <libzonecfg.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #include <stdio.h>
427c478bd9Sstevel@tonic-gate #include <stdlib.h>
437c478bd9Sstevel@tonic-gate #include <unistd.h>
447c478bd9Sstevel@tonic-gate #include <dirent.h>
457c478bd9Sstevel@tonic-gate #include <string.h>
467c478bd9Sstevel@tonic-gate #include <errno.h>
477c478bd9Sstevel@tonic-gate #include <poll.h>
487c478bd9Sstevel@tonic-gate #include <ctype.h>
497c478bd9Sstevel@tonic-gate #include <fcntl.h>
507c478bd9Sstevel@tonic-gate #include <limits.h>
517c478bd9Sstevel@tonic-gate #include <signal.h>
527c478bd9Sstevel@tonic-gate #include <time.h>
537c478bd9Sstevel@tonic-gate #include <project.h>
547c478bd9Sstevel@tonic-gate
554944376cSJohn Levon #include <langinfo.h>
567c478bd9Sstevel@tonic-gate #include <libintl.h>
577c478bd9Sstevel@tonic-gate #include <locale.h>
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate #include "prstat.h"
607c478bd9Sstevel@tonic-gate #include "prutil.h"
617c478bd9Sstevel@tonic-gate #include "prtable.h"
627c478bd9Sstevel@tonic-gate #include "prsort.h"
637c478bd9Sstevel@tonic-gate #include "prfile.h"
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate * x86 <sys/regs.h> ERR conflicts with <curses.h> ERR. For the purposes
677c478bd9Sstevel@tonic-gate * of this file, we care about the curses.h ERR so include that last.
687c478bd9Sstevel@tonic-gate */
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate #if defined(ERR)
717c478bd9Sstevel@tonic-gate #undef ERR
727c478bd9Sstevel@tonic-gate #endif
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN /* should be defined by cc -D */
757c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* use this only if it wasn't */
767c478bd9Sstevel@tonic-gate #endif
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate #include <curses.h>
797c478bd9Sstevel@tonic-gate #include <term.h>
807c478bd9Sstevel@tonic-gate
810a1278f2SGary Mills #define LOGIN_WIDTH 8
820a1278f2SGary Mills #define ZONE_WIDTH 28
830a1278f2SGary Mills #define PROJECT_WIDTH 28
840a1278f2SGary Mills
857c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_PROC \
867c478bd9Sstevel@tonic-gate " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP "
87c6402783Sakolb #define PSINFO_HEADER_PROC_LGRP \
88c6402783Sakolb " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/NLWP "
897c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_LWP \
90*ab618543SJohn Levon " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWP "
91c6402783Sakolb #define PSINFO_HEADER_LWP_LGRP \
92*ab618543SJohn Levon " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWP "
937c478bd9Sstevel@tonic-gate #define USAGE_HEADER_PROC \
947c478bd9Sstevel@tonic-gate " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP "
957c478bd9Sstevel@tonic-gate #define USAGE_HEADER_LWP \
96*ab618543SJohn Levon " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWP "
977c478bd9Sstevel@tonic-gate #define USER_HEADER_PROC \
980209230bSgjelinek " NPROC USERNAME SWAP RSS MEMORY TIME CPU "
997c478bd9Sstevel@tonic-gate #define USER_HEADER_LWP \
1000209230bSgjelinek " NLWP USERNAME SWAP RSS MEMORY TIME CPU "
1017c478bd9Sstevel@tonic-gate #define TASK_HEADER_PROC \
1020209230bSgjelinek "TASKID NPROC SWAP RSS MEMORY TIME CPU PROJECT "
1037c478bd9Sstevel@tonic-gate #define TASK_HEADER_LWP \
1040209230bSgjelinek "TASKID NLWP SWAP RSS MEMORY TIME CPU PROJECT "
1057c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_PROC \
1060209230bSgjelinek "PROJID NPROC SWAP RSS MEMORY TIME CPU PROJECT "
1077c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_LWP \
1080209230bSgjelinek "PROJID NLWP SWAP RSS MEMORY TIME CPU PROJECT "
1097c478bd9Sstevel@tonic-gate #define ZONE_HEADER_PROC \
1100209230bSgjelinek "ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE "
1117c478bd9Sstevel@tonic-gate #define ZONE_HEADER_LWP \
1120209230bSgjelinek "ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE "
1137c478bd9Sstevel@tonic-gate #define PSINFO_LINE \
114*ab618543SJohn Levon "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %s"
115c6402783Sakolb #define PSINFO_LINE_LGRP \
116*ab618543SJohn Levon "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %s"
1177c478bd9Sstevel@tonic-gate #define USAGE_LINE \
1180a1278f2SGary Mills "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\
119*ab618543SJohn Levon "%3.3s %3.3s %s"
1207c478bd9Sstevel@tonic-gate #define USER_LINE \
1217c478bd9Sstevel@tonic-gate "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%"
1227c478bd9Sstevel@tonic-gate #define TASK_LINE \
1237c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
1247c478bd9Sstevel@tonic-gate #define PROJECT_LINE \
1257c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
1267c478bd9Sstevel@tonic-gate #define ZONE_LINE \
1277c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s"
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate #define TOTAL_LINE \
1307c478bd9Sstevel@tonic-gate "Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f"
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate /* global variables */
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate static char *t_ulon; /* termcap: start underline */
1357c478bd9Sstevel@tonic-gate static char *t_uloff; /* termcap: end underline */
1367c478bd9Sstevel@tonic-gate static char *t_up; /* termcap: cursor 1 line up */
1377c478bd9Sstevel@tonic-gate static char *t_eol; /* termcap: clear end of line */
1387c478bd9Sstevel@tonic-gate static char *t_smcup; /* termcap: cursor mvcap on */
1397c478bd9Sstevel@tonic-gate static char *t_rmcup; /* termcap: cursor mvcap off */
1407c478bd9Sstevel@tonic-gate static char *t_home; /* termcap: move cursor home */
1417c478bd9Sstevel@tonic-gate static char *movecur = NULL; /* termcap: move up string */
1427c478bd9Sstevel@tonic-gate static char *empty_string = "\0"; /* termcap: empty string */
1437c478bd9Sstevel@tonic-gate static uint_t print_movecur = FALSE; /* print movecur or not */
1447c478bd9Sstevel@tonic-gate static int is_curses_on = FALSE; /* current curses state */
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate static table_t pid_tbl = {0, 0, NULL}; /* selected processes */
1477c478bd9Sstevel@tonic-gate static table_t cpu_tbl = {0, 0, NULL}; /* selected processors */
1487c478bd9Sstevel@tonic-gate static table_t set_tbl = {0, 0, NULL}; /* selected processor sets */
1497c478bd9Sstevel@tonic-gate static table_t prj_tbl = {0, 0, NULL}; /* selected projects */
1507c478bd9Sstevel@tonic-gate static table_t tsk_tbl = {0, 0, NULL}; /* selected tasks */
151c6402783Sakolb static table_t lgr_tbl = {0, 0, NULL}; /* selected lgroups */
1527c478bd9Sstevel@tonic-gate static zonetbl_t zone_tbl = {0, 0, NULL}; /* selected zones */
153*ab618543SJohn Levon static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */
154*ab618543SJohn Levon static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate static uint_t total_procs; /* total number of procs */
1577c478bd9Sstevel@tonic-gate static uint_t total_lwps; /* total number of lwps */
1587c478bd9Sstevel@tonic-gate static float total_cpu; /* total cpu usage */
1597c478bd9Sstevel@tonic-gate static float total_mem; /* total memory usage */
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate static list_t lwps; /* list of lwps/processes */
1627c478bd9Sstevel@tonic-gate static list_t users; /* list of users */
1637c478bd9Sstevel@tonic-gate static list_t tasks; /* list of tasks */
1647c478bd9Sstevel@tonic-gate static list_t projects; /* list of projects */
1657c478bd9Sstevel@tonic-gate static list_t zones; /* list of zones */
166c6402783Sakolb static list_t lgroups; /* list of lgroups */
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate static volatile uint_t sigwinch = 0;
1697c478bd9Sstevel@tonic-gate static volatile uint_t sigtstp = 0;
1707c478bd9Sstevel@tonic-gate static volatile uint_t sigterm = 0;
1717c478bd9Sstevel@tonic-gate
1720209230bSgjelinek static long pagesize;
1730209230bSgjelinek
1747c478bd9Sstevel@tonic-gate /* default settings */
1757c478bd9Sstevel@tonic-gate
176*ab618543SJohn Levon optdesc_t opts = {
1777c478bd9Sstevel@tonic-gate 5, /* interval between updates, seconds */
1787c478bd9Sstevel@tonic-gate 15, /* number of lines in top part */
1797c478bd9Sstevel@tonic-gate 5, /* number of lines in bottom part */
1807c478bd9Sstevel@tonic-gate -1, /* number of iterations; infinitely */
1817c478bd9Sstevel@tonic-gate OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP,
1827c478bd9Sstevel@tonic-gate -1 /* sort in decreasing order */
1837c478bd9Sstevel@tonic-gate };
1847c478bd9Sstevel@tonic-gate
1854944376cSJohn Levon /*
1864944376cSJohn Levon * Print timestamp as decimal reprentation of time_t value (-d u was specified)
1874944376cSJohn Levon * or the standard date format (-d d was specified).
1884944376cSJohn Levon */
1894944376cSJohn Levon static void
print_timestamp(void)1904944376cSJohn Levon print_timestamp(void)
1914944376cSJohn Levon {
1924944376cSJohn Levon time_t t = time(NULL);
1934944376cSJohn Levon static char *fmt = NULL;
1944944376cSJohn Levon
1954944376cSJohn Levon /* We only need to retrieve this once per invocation */
1964944376cSJohn Levon if (fmt == NULL)
1974944376cSJohn Levon fmt = nl_langinfo(_DATE_FMT);
1984944376cSJohn Levon
1994944376cSJohn Levon if (opts.o_outpmode & OPT_UDATE) {
2004944376cSJohn Levon (void) printf("%ld", t);
2014944376cSJohn Levon } else if (opts.o_outpmode & OPT_DDATE) {
2024944376cSJohn Levon char dstr[64];
2034944376cSJohn Levon int len;
2044944376cSJohn Levon
2054944376cSJohn Levon len = strftime(dstr, sizeof (dstr), fmt, localtime(&t));
2064944376cSJohn Levon if (len > 0)
2074944376cSJohn Levon (void) printf("%s", dstr);
2084944376cSJohn Levon }
2094944376cSJohn Levon (void) putp(t_eol);
2104944376cSJohn Levon (void) putchar('\n');
2114944376cSJohn Levon }
2124944376cSJohn Levon
2137c478bd9Sstevel@tonic-gate static void
psetloadavg(long psetid,void * ptr)2147c478bd9Sstevel@tonic-gate psetloadavg(long psetid, void *ptr)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate double psetloadavg[3];
2177c478bd9Sstevel@tonic-gate double *loadavg = ptr;
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate if (pset_getloadavg((psetid_t)psetid, psetloadavg, 3) != -1) {
2207c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[0];
2217c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[1];
2227c478bd9Sstevel@tonic-gate *loadavg += psetloadavg[2];
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate
2260209230bSgjelinek /*
2270209230bSgjelinek * Queries the memory virtual and rss size for each member of a list.
2280209230bSgjelinek * This will override the values computed by /proc aggregation.
2290209230bSgjelinek */
2300209230bSgjelinek static void
list_getsize(list_t * list)2310209230bSgjelinek list_getsize(list_t *list)
2320209230bSgjelinek {
2330209230bSgjelinek id_info_t *id;
2340209230bSgjelinek vmusage_t *results, *next;
2350209230bSgjelinek vmusage_t *match;
2360209230bSgjelinek size_t nres = 0;
2370209230bSgjelinek size_t i;
2380209230bSgjelinek uint_t flags = 0;
2390209230bSgjelinek int ret;
2400209230bSgjelinek size_t physmem = sysconf(_SC_PHYS_PAGES) * pagesize;
2410209230bSgjelinek
2420209230bSgjelinek /*
2430209230bSgjelinek * Determine what swap/rss results to calculate. getvmusage() will
2440209230bSgjelinek * prune results returned to non-global zones automatically, so
2450209230bSgjelinek * there is no need to pass different flags when calling from a
2460209230bSgjelinek * non-global zone.
2470209230bSgjelinek *
2480209230bSgjelinek * Currently list_getsize() is only called with a single flag. This
2490209230bSgjelinek * is because -Z, -J, -T, and -a are mutually exclusive. Regardless
2500209230bSgjelinek * of this, we handle multiple flags.
2510209230bSgjelinek */
2520209230bSgjelinek if (opts.o_outpmode & OPT_USERS) {
2530209230bSgjelinek /*
2540209230bSgjelinek * Gather rss for all users in all zones. Treat the same
2550209230bSgjelinek * uid in different zones as the same user.
2560209230bSgjelinek */
2570209230bSgjelinek flags |= VMUSAGE_COL_RUSERS;
2580209230bSgjelinek
2590209230bSgjelinek } else if (opts.o_outpmode & OPT_TASKS) {
2600209230bSgjelinek /* Gather rss for all tasks in all zones */
2610209230bSgjelinek flags |= VMUSAGE_ALL_TASKS;
2620209230bSgjelinek
2630209230bSgjelinek } else if (opts.o_outpmode & OPT_PROJECTS) {
2640209230bSgjelinek /*
2650209230bSgjelinek * Gather rss for all projects in all zones. Treat the same
2660209230bSgjelinek * projid in diffrent zones as the same project.
2670209230bSgjelinek */
2680209230bSgjelinek flags |= VMUSAGE_COL_PROJECTS;
2690209230bSgjelinek
2700209230bSgjelinek } else if (opts.o_outpmode & OPT_ZONES) {
2710209230bSgjelinek /* Gather rss for all zones */
2720209230bSgjelinek flags |= VMUSAGE_ALL_ZONES;
2730209230bSgjelinek
2740209230bSgjelinek } else {
2750209230bSgjelinek Die(gettext(
2760209230bSgjelinek "Cannot determine rss flags for output options %x\n"),
2770209230bSgjelinek opts.o_outpmode);
2780209230bSgjelinek }
2790209230bSgjelinek
2800209230bSgjelinek /*
2810209230bSgjelinek * getvmusage() returns an array of result structures. One for
2820209230bSgjelinek * each zone, project, task, or user on the system, depending on
2830209230bSgjelinek * flags.
2840209230bSgjelinek *
2850209230bSgjelinek * If getvmusage() fails, prstat will use the size already gathered
2860209230bSgjelinek * from psinfo
2870209230bSgjelinek */
2880209230bSgjelinek if (getvmusage(flags, opts.o_interval, NULL, &nres) != 0)
2890209230bSgjelinek return;
2900209230bSgjelinek
2910209230bSgjelinek results = (vmusage_t *)Malloc(sizeof (vmusage_t) * nres);
2920209230bSgjelinek for (;;) {
2930209230bSgjelinek ret = getvmusage(flags, opts.o_interval, results, &nres);
2940209230bSgjelinek if (ret == 0)
2950209230bSgjelinek break;
2960209230bSgjelinek if (errno == EOVERFLOW) {
2970209230bSgjelinek results = (vmusage_t *)Realloc(results,
2980209230bSgjelinek sizeof (vmusage_t) * nres);
2990209230bSgjelinek continue;
3000209230bSgjelinek }
3010209230bSgjelinek /*
3020209230bSgjelinek * Failure for some other reason. Prstat will use the size
3030209230bSgjelinek * already gathered from psinfo.
3040209230bSgjelinek */
305e1009cb0S free(results);
3060209230bSgjelinek return;
3070209230bSgjelinek }
3080209230bSgjelinek for (id = list->l_head; id != NULL; id = id->id_next) {
3090209230bSgjelinek
3100209230bSgjelinek match = NULL;
3110209230bSgjelinek next = results;
3120209230bSgjelinek for (i = 0; i < nres; i++, next++) {
3130209230bSgjelinek switch (flags) {
3140209230bSgjelinek case VMUSAGE_COL_RUSERS:
3150209230bSgjelinek if (next->vmu_id == id->id_uid)
3160209230bSgjelinek match = next;
3170209230bSgjelinek break;
3180209230bSgjelinek case VMUSAGE_ALL_TASKS:
3190209230bSgjelinek if (next->vmu_id == id->id_taskid)
3200209230bSgjelinek match = next;
3210209230bSgjelinek break;
3220209230bSgjelinek case VMUSAGE_COL_PROJECTS:
3230209230bSgjelinek if (next->vmu_id == id->id_projid)
3240209230bSgjelinek match = next;
3250209230bSgjelinek break;
3260209230bSgjelinek case VMUSAGE_ALL_ZONES:
3270209230bSgjelinek if (next->vmu_id == id->id_zoneid)
3280209230bSgjelinek match = next;
3290209230bSgjelinek break;
3300209230bSgjelinek default:
3310209230bSgjelinek Die(gettext(
3320209230bSgjelinek "Unknown vmusage flags %d\n"), flags);
3330209230bSgjelinek }
3340209230bSgjelinek }
3350209230bSgjelinek if (match != NULL) {
3360209230bSgjelinek id->id_size = match->vmu_swap_all / 1024;
3370209230bSgjelinek id->id_rssize = match->vmu_rss_all / 1024;
3380209230bSgjelinek id->id_pctmem = (100.0 * (float)match->vmu_rss_all) /
3390209230bSgjelinek (float)physmem;
3400209230bSgjelinek /* Output using data from getvmusage() */
3410209230bSgjelinek id->id_sizematch = B_TRUE;
3420209230bSgjelinek }
3430209230bSgjelinek /*
3440209230bSgjelinek * If no match is found, prstat will use the size already
3450209230bSgjelinek * gathered from psinfo.
3460209230bSgjelinek */
3470209230bSgjelinek }
348e1009cb0S free(results);
3490209230bSgjelinek }
3500209230bSgjelinek
3517c478bd9Sstevel@tonic-gate /*
3527c478bd9Sstevel@tonic-gate * A routine to display the contents of the list on the screen
3537c478bd9Sstevel@tonic-gate */
3547c478bd9Sstevel@tonic-gate static void
list_print(list_t * list)3557c478bd9Sstevel@tonic-gate list_print(list_t *list)
3567c478bd9Sstevel@tonic-gate {
3577c478bd9Sstevel@tonic-gate lwp_info_t *lwp;
3587c478bd9Sstevel@tonic-gate id_info_t *id;
3597c478bd9Sstevel@tonic-gate char usr[4], sys[4], trp[4], tfl[4];
3607c478bd9Sstevel@tonic-gate char dfl[4], lck[4], slp[4], lat[4];
3617c478bd9Sstevel@tonic-gate char vcx[4], icx[4], scl[4], sig[4];
3627c478bd9Sstevel@tonic-gate char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12];
3637c478bd9Sstevel@tonic-gate char pstate[7], pnice[4], ppri[4];
3647c478bd9Sstevel@tonic-gate char pname[LOGNAME_MAX+1];
365*ab618543SJohn Levon char name[PRFNSZ + THREAD_NAME_MAX + 2];
3667c478bd9Sstevel@tonic-gate char projname[PROJNAME_MAX+1];
3677c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX+1];
3687c478bd9Sstevel@tonic-gate float cpu, mem;
3697c478bd9Sstevel@tonic-gate double loadavg[3] = {0, 0, 0};
370*ab618543SJohn Levon int i, n;
3717c478bd9Sstevel@tonic-gate
372156d6b3aSJerry Jelinek if (list->l_size == 0)
373156d6b3aSJerry Jelinek return;
374156d6b3aSJerry Jelinek
3757c478bd9Sstevel@tonic-gate if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) {
3767c478bd9Sstevel@tonic-gate /*
3777c478bd9Sstevel@tonic-gate * If processor sets aren't specified, we display system-wide
3787c478bd9Sstevel@tonic-gate * load averages.
3797c478bd9Sstevel@tonic-gate */
3807c478bd9Sstevel@tonic-gate (void) getloadavg(loadavg, 3);
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate
3834944376cSJohn Levon if (((opts.o_outpmode & OPT_UDATE) || (opts.o_outpmode & OPT_DDATE)) &&
3844944376cSJohn Levon ((list->l_type == LT_LWPS) || !(opts.o_outpmode & OPT_SPLIT)))
3854944376cSJohn Levon print_timestamp();
3867c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
3877c478bd9Sstevel@tonic-gate (void) putchar('\r');
3887c478bd9Sstevel@tonic-gate (void) putp(t_ulon);
3897c478bd9Sstevel@tonic-gate
390*ab618543SJohn Levon n = opts.o_cols;
3917c478bd9Sstevel@tonic-gate switch (list->l_type) {
3927c478bd9Sstevel@tonic-gate case LT_PROJECTS:
3937c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
394*ab618543SJohn Levon n = printf(PROJECT_HEADER_LWP);
3957c478bd9Sstevel@tonic-gate else
396*ab618543SJohn Levon n = printf(PROJECT_HEADER_PROC);
3977c478bd9Sstevel@tonic-gate break;
3987c478bd9Sstevel@tonic-gate case LT_TASKS:
3997c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
400*ab618543SJohn Levon n = printf(TASK_HEADER_LWP);
4017c478bd9Sstevel@tonic-gate else
402*ab618543SJohn Levon n = printf(TASK_HEADER_PROC);
4037c478bd9Sstevel@tonic-gate break;
4047c478bd9Sstevel@tonic-gate case LT_ZONES:
4057c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
406*ab618543SJohn Levon n = printf(ZONE_HEADER_LWP);
4077c478bd9Sstevel@tonic-gate else
408*ab618543SJohn Levon n = printf(ZONE_HEADER_PROC);
4097c478bd9Sstevel@tonic-gate break;
4107c478bd9Sstevel@tonic-gate case LT_USERS:
4117c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
412*ab618543SJohn Levon n = printf(USER_HEADER_LWP);
4137c478bd9Sstevel@tonic-gate else
414*ab618543SJohn Levon n = printf(USER_HEADER_PROC);
4157c478bd9Sstevel@tonic-gate break;
4167c478bd9Sstevel@tonic-gate case LT_LWPS:
4177c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) {
418c6402783Sakolb if (opts.o_outpmode & OPT_PSINFO) {
419c6402783Sakolb if (opts.o_outpmode & OPT_LGRP)
420*ab618543SJohn Levon n = printf(PSINFO_HEADER_LWP_LGRP);
421c6402783Sakolb else
422*ab618543SJohn Levon n = printf(PSINFO_HEADER_LWP);
423c6402783Sakolb }
4247c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT)
425*ab618543SJohn Levon n = printf(USAGE_HEADER_LWP);
4267c478bd9Sstevel@tonic-gate } else {
427c6402783Sakolb if (opts.o_outpmode & OPT_PSINFO) {
428c6402783Sakolb if (opts.o_outpmode & OPT_LGRP)
429*ab618543SJohn Levon n = printf(PSINFO_HEADER_PROC_LGRP);
430c6402783Sakolb else
431*ab618543SJohn Levon n = printf(PSINFO_HEADER_PROC);
432c6402783Sakolb }
4337c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT)
434*ab618543SJohn Levon n = printf(USAGE_HEADER_PROC);
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate break;
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate
439*ab618543SJohn Levon /* Pad out the header line so the underline spans the whole width */
440*ab618543SJohn Levon if ((opts.o_outpmode & OPT_TERMCAP) && n < opts.o_cols)
441*ab618543SJohn Levon (void) printf("%*s", (int)(opts.o_cols - n), "");
442*ab618543SJohn Levon
4437c478bd9Sstevel@tonic-gate (void) putp(t_uloff);
4447c478bd9Sstevel@tonic-gate (void) putp(t_eol);
4457c478bd9Sstevel@tonic-gate (void) putchar('\n');
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate for (i = 0; i < list->l_used; i++) {
4487c478bd9Sstevel@tonic-gate switch (list->l_type) {
4497c478bd9Sstevel@tonic-gate case LT_PROJECTS:
4507c478bd9Sstevel@tonic-gate case LT_TASKS:
4517c478bd9Sstevel@tonic-gate case LT_USERS:
4527c478bd9Sstevel@tonic-gate case LT_ZONES:
4537c478bd9Sstevel@tonic-gate id = list->l_ptrs[i];
4547c478bd9Sstevel@tonic-gate /*
4557c478bd9Sstevel@tonic-gate * CPU usage and memory usage normalization
4567c478bd9Sstevel@tonic-gate */
4577c478bd9Sstevel@tonic-gate if (total_cpu >= 100)
4587c478bd9Sstevel@tonic-gate cpu = (100 * id->id_pctcpu) / total_cpu;
4597c478bd9Sstevel@tonic-gate else
4607c478bd9Sstevel@tonic-gate cpu = id->id_pctcpu;
4610209230bSgjelinek if (id->id_sizematch == B_FALSE && total_mem >= 100)
4627c478bd9Sstevel@tonic-gate mem = (100 * id->id_pctmem) / total_mem;
4637c478bd9Sstevel@tonic-gate else
4647c478bd9Sstevel@tonic-gate mem = id->id_pctmem;
4650a1278f2SGary Mills if (list->l_type == LT_USERS) {
4660a1278f2SGary Mills pwd_getname(id->id_uid, pname, sizeof (pname),
4670a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE,
4680a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
4690a1278f2SGary Mills LOGIN_WIDTH);
4700a1278f2SGary Mills } else if (list->l_type == LT_ZONES) {
4717c478bd9Sstevel@tonic-gate getzonename(id->id_zoneid, zonename,
4720a1278f2SGary Mills sizeof (zonename),
4730a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
4740a1278f2SGary Mills ZONE_WIDTH);
4750a1278f2SGary Mills } else {
4767c478bd9Sstevel@tonic-gate getprojname(id->id_projid, projname,
4770a1278f2SGary Mills sizeof (projname),
4780a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE,
4790a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
4800a1278f2SGary Mills PROJECT_WIDTH);
4810a1278f2SGary Mills }
4827c478bd9Sstevel@tonic-gate Format_size(psize, id->id_size, 6);
4837c478bd9Sstevel@tonic-gate Format_size(prssize, id->id_rssize, 6);
4847c478bd9Sstevel@tonic-gate Format_pct(pmem, mem, 4);
4857c478bd9Sstevel@tonic-gate Format_pct(pcpu, cpu, 4);
4867c478bd9Sstevel@tonic-gate Format_time(ptime, id->id_time, 10);
4877c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
4887c478bd9Sstevel@tonic-gate (void) putchar('\r');
4897c478bd9Sstevel@tonic-gate if (list->l_type == LT_PROJECTS)
4907c478bd9Sstevel@tonic-gate (void) printf(PROJECT_LINE, (int)id->id_projid,
4917c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime,
4927c478bd9Sstevel@tonic-gate pcpu, projname);
4937c478bd9Sstevel@tonic-gate else if (list->l_type == LT_TASKS)
4947c478bd9Sstevel@tonic-gate (void) printf(TASK_LINE, (int)id->id_taskid,
4957c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime,
4967c478bd9Sstevel@tonic-gate pcpu, projname);
4977c478bd9Sstevel@tonic-gate else if (list->l_type == LT_ZONES)
4987c478bd9Sstevel@tonic-gate (void) printf(ZONE_LINE, (int)id->id_zoneid,
4997c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime,
5007c478bd9Sstevel@tonic-gate pcpu, zonename);
5017c478bd9Sstevel@tonic-gate else
5027c478bd9Sstevel@tonic-gate (void) printf(USER_LINE, id->id_nproc, pname,
5037c478bd9Sstevel@tonic-gate psize, prssize, pmem, ptime, pcpu);
5047c478bd9Sstevel@tonic-gate (void) putp(t_eol);
5057c478bd9Sstevel@tonic-gate (void) putchar('\n');
5067c478bd9Sstevel@tonic-gate break;
5077c478bd9Sstevel@tonic-gate case LT_LWPS:
5087c478bd9Sstevel@tonic-gate lwp = list->l_ptrs[i];
509*ab618543SJohn Levon
510*ab618543SJohn Levon format_name(lwp, name, sizeof (name));
511*ab618543SJohn Levon
5120a1278f2SGary Mills pwd_getname(lwp->li_info.pr_uid, pname, sizeof (pname),
5130a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE,
5140a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
5150a1278f2SGary Mills LOGIN_WIDTH);
516*ab618543SJohn Levon
5177c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PSINFO) {
5187c478bd9Sstevel@tonic-gate Format_size(psize, lwp->li_info.pr_size, 6);
5197c478bd9Sstevel@tonic-gate Format_size(prssize, lwp->li_info.pr_rssize, 6);
5207c478bd9Sstevel@tonic-gate Format_state(pstate,
5217c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname,
5227c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_onpro, 7);
5237c478bd9Sstevel@tonic-gate if (strcmp(lwp->li_info.pr_lwp.pr_clname,
5247c478bd9Sstevel@tonic-gate "RT") == 0 ||
5257c478bd9Sstevel@tonic-gate strcmp(lwp->li_info.pr_lwp.pr_clname,
5267c478bd9Sstevel@tonic-gate "SYS") == 0 ||
5277c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname == 'Z')
5287c478bd9Sstevel@tonic-gate (void) strcpy(pnice, " -");
5297c478bd9Sstevel@tonic-gate else
5307c478bd9Sstevel@tonic-gate Format_num(pnice,
5317c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_nice - NZERO,
5327c478bd9Sstevel@tonic-gate 4);
5337c478bd9Sstevel@tonic-gate Format_num(ppri, lwp->li_info.pr_lwp.pr_pri, 4);
5347c478bd9Sstevel@tonic-gate Format_pct(pcpu,
5357c478bd9Sstevel@tonic-gate FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu), 4);
5367c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
5377c478bd9Sstevel@tonic-gate Format_time(ptime,
5387c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_time.tv_sec,
5397c478bd9Sstevel@tonic-gate 10);
5407c478bd9Sstevel@tonic-gate else
5417c478bd9Sstevel@tonic-gate Format_time(ptime,
5427c478bd9Sstevel@tonic-gate lwp->li_info.pr_time.tv_sec, 10);
5437c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
5447c478bd9Sstevel@tonic-gate (void) putchar('\r');
545c6402783Sakolb if (opts.o_outpmode & OPT_LGRP) {
546c6402783Sakolb (void) printf(PSINFO_LINE_LGRP,
547c6402783Sakolb (int)lwp->li_info.pr_pid, pname,
5480a1278f2SGary Mills psize, prssize, pstate,
5490a1278f2SGary Mills ppri, pnice, ptime, pcpu,
550*ab618543SJohn Levon lwp->li_info.pr_lwp.pr_lgrp, name);
551c6402783Sakolb } else {
552c6402783Sakolb (void) printf(PSINFO_LINE,
553c6402783Sakolb (int)lwp->li_info.pr_pid, pname,
554*ab618543SJohn Levon psize, prssize, pstate, ppri, pnice,
555*ab618543SJohn Levon ptime, pcpu, name);
556c6402783Sakolb }
5577c478bd9Sstevel@tonic-gate (void) putp(t_eol);
5587c478bd9Sstevel@tonic-gate (void) putchar('\n');
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) {
5617c478bd9Sstevel@tonic-gate Format_pct(usr, lwp->li_usr, 4);
5627c478bd9Sstevel@tonic-gate Format_pct(sys, lwp->li_sys, 4);
5637c478bd9Sstevel@tonic-gate Format_pct(slp, lwp->li_slp, 4);
5647c478bd9Sstevel@tonic-gate Format_num(vcx, lwp->li_vcx, 4);
5657c478bd9Sstevel@tonic-gate Format_num(icx, lwp->li_icx, 4);
5667c478bd9Sstevel@tonic-gate Format_num(scl, lwp->li_scl, 4);
5677c478bd9Sstevel@tonic-gate Format_num(sig, lwp->li_sig, 4);
5687c478bd9Sstevel@tonic-gate Format_pct(trp, lwp->li_trp, 4);
5697c478bd9Sstevel@tonic-gate Format_pct(tfl, lwp->li_tfl, 4);
5707c478bd9Sstevel@tonic-gate Format_pct(dfl, lwp->li_dfl, 4);
5717c478bd9Sstevel@tonic-gate Format_pct(lck, lwp->li_lck, 4);
5727c478bd9Sstevel@tonic-gate Format_pct(lat, lwp->li_lat, 4);
5737c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
5747c478bd9Sstevel@tonic-gate (void) putchar('\r');
5757c478bd9Sstevel@tonic-gate (void) printf(USAGE_LINE,
5767c478bd9Sstevel@tonic-gate (int)lwp->li_info.pr_pid, pname,
5777c478bd9Sstevel@tonic-gate usr, sys, trp, tfl, dfl, lck,
5787c478bd9Sstevel@tonic-gate slp, lat, vcx, icx, scl, sig,
579*ab618543SJohn Levon name);
5807c478bd9Sstevel@tonic-gate (void) putp(t_eol);
5817c478bd9Sstevel@tonic-gate (void) putchar('\n');
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate break;
5847c478bd9Sstevel@tonic-gate }
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
5887c478bd9Sstevel@tonic-gate (void) putchar('\r');
5897c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) {
5907c478bd9Sstevel@tonic-gate switch (list->l_type) {
5917c478bd9Sstevel@tonic-gate case LT_PROJECTS:
5927c478bd9Sstevel@tonic-gate case LT_USERS:
5937c478bd9Sstevel@tonic-gate case LT_TASKS:
5947c478bd9Sstevel@tonic-gate case LT_ZONES:
5957c478bd9Sstevel@tonic-gate while (i++ < opts.o_nbottom) {
5967c478bd9Sstevel@tonic-gate (void) putp(t_eol);
5977c478bd9Sstevel@tonic-gate (void) putchar('\n');
5987c478bd9Sstevel@tonic-gate }
5997c478bd9Sstevel@tonic-gate break;
6007c478bd9Sstevel@tonic-gate case LT_LWPS:
6017c478bd9Sstevel@tonic-gate while (i++ < opts.o_ntop) {
6027c478bd9Sstevel@tonic-gate (void) putp(t_eol);
6037c478bd9Sstevel@tonic-gate (void) putchar('\n');
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
6097c478bd9Sstevel@tonic-gate (void) putchar('\r');
6107c478bd9Sstevel@tonic-gate
6117c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_SPLIT) && list->l_type == LT_LWPS)
6127c478bd9Sstevel@tonic-gate return;
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate (void) printf(TOTAL_LINE, total_procs, total_lwps,
6157c478bd9Sstevel@tonic-gate loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN],
6167c478bd9Sstevel@tonic-gate loadavg[LOADAVG_15MIN]);
6177c478bd9Sstevel@tonic-gate (void) putp(t_eol);
6187c478bd9Sstevel@tonic-gate (void) putchar('\n');
6197c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
6207c478bd9Sstevel@tonic-gate (void) putchar('\r');
6217c478bd9Sstevel@tonic-gate (void) putp(t_eol);
6227c478bd9Sstevel@tonic-gate (void) fflush(stdout);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate
6257c478bd9Sstevel@tonic-gate static lwp_info_t *
list_add_lwp(list_t * list,pid_t pid,id_t lwpid)6267c478bd9Sstevel@tonic-gate list_add_lwp(list_t *list, pid_t pid, id_t lwpid)
6277c478bd9Sstevel@tonic-gate {
6287c478bd9Sstevel@tonic-gate lwp_info_t *lwp;
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate if (list->l_head == NULL) {
6317c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = lwp = Zalloc(sizeof (lwp_info_t));
6327c478bd9Sstevel@tonic-gate } else {
6337c478bd9Sstevel@tonic-gate lwp = Zalloc(sizeof (lwp_info_t));
6347c478bd9Sstevel@tonic-gate lwp->li_prev = list->l_tail;
6357c478bd9Sstevel@tonic-gate ((lwp_info_t *)list->l_tail)->li_next = lwp;
6367c478bd9Sstevel@tonic-gate list->l_tail = lwp;
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate lwp->li_info.pr_pid = pid;
6397c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_lwpid = lwpid;
6407c478bd9Sstevel@tonic-gate lwpid_add(lwp, pid, lwpid);
6417c478bd9Sstevel@tonic-gate list->l_count++;
6427c478bd9Sstevel@tonic-gate return (lwp);
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate static void
list_remove_lwp(list_t * list,lwp_info_t * lwp)6467c478bd9Sstevel@tonic-gate list_remove_lwp(list_t *list, lwp_info_t *lwp)
6477c478bd9Sstevel@tonic-gate {
6487c478bd9Sstevel@tonic-gate if (lwp->li_prev)
6497c478bd9Sstevel@tonic-gate lwp->li_prev->li_next = lwp->li_next;
6507c478bd9Sstevel@tonic-gate else
6517c478bd9Sstevel@tonic-gate list->l_head = lwp->li_next; /* removing the head */
6527c478bd9Sstevel@tonic-gate if (lwp->li_next)
6537c478bd9Sstevel@tonic-gate lwp->li_next->li_prev = lwp->li_prev;
6547c478bd9Sstevel@tonic-gate else
6557c478bd9Sstevel@tonic-gate list->l_tail = lwp->li_prev; /* removing the tail */
6567c478bd9Sstevel@tonic-gate lwpid_del(lwp->li_info.pr_pid, lwp->li_info.pr_lwp.pr_lwpid);
6577c478bd9Sstevel@tonic-gate if (lwpid_pidcheck(lwp->li_info.pr_pid) == 0)
6587c478bd9Sstevel@tonic-gate fds_rm(lwp->li_info.pr_pid);
6597c478bd9Sstevel@tonic-gate list->l_count--;
6607c478bd9Sstevel@tonic-gate free(lwp);
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate
6637c478bd9Sstevel@tonic-gate static void
list_clear(list_t * list)6647c478bd9Sstevel@tonic-gate list_clear(list_t *list)
6657c478bd9Sstevel@tonic-gate {
6667c478bd9Sstevel@tonic-gate if (list->l_type == LT_LWPS) {
6677c478bd9Sstevel@tonic-gate lwp_info_t *lwp = list->l_tail;
6687c478bd9Sstevel@tonic-gate lwp_info_t *lwp_tmp;
6697c478bd9Sstevel@tonic-gate
6707c478bd9Sstevel@tonic-gate fd_closeall();
6717c478bd9Sstevel@tonic-gate while (lwp) {
6727c478bd9Sstevel@tonic-gate lwp_tmp = lwp;
6737c478bd9Sstevel@tonic-gate lwp = lwp->li_prev;
6747c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp_tmp);
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate } else {
6777c478bd9Sstevel@tonic-gate id_info_t *id = list->l_head;
6787c478bd9Sstevel@tonic-gate id_info_t *nextid;
6797c478bd9Sstevel@tonic-gate
6807c478bd9Sstevel@tonic-gate while (id) {
6817c478bd9Sstevel@tonic-gate nextid = id->id_next;
6827c478bd9Sstevel@tonic-gate free(id);
6837c478bd9Sstevel@tonic-gate id = nextid;
6847c478bd9Sstevel@tonic-gate }
6857c478bd9Sstevel@tonic-gate list->l_count = 0;
6867c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = NULL;
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate }
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate static void
list_update(list_t * list,lwp_info_t * lwp)6917c478bd9Sstevel@tonic-gate list_update(list_t *list, lwp_info_t *lwp)
6927c478bd9Sstevel@tonic-gate {
6937c478bd9Sstevel@tonic-gate id_info_t *id;
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate if (list->l_head == NULL) { /* first element */
6967c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = id = Zalloc(sizeof (id_info_t));
6977c478bd9Sstevel@tonic-gate goto update;
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate
7007c478bd9Sstevel@tonic-gate for (id = list->l_head; id; id = id->id_next) {
7017c478bd9Sstevel@tonic-gate if ((list->l_type == LT_USERS) &&
7027c478bd9Sstevel@tonic-gate (id->id_uid != lwp->li_info.pr_uid))
7037c478bd9Sstevel@tonic-gate continue;
7047c478bd9Sstevel@tonic-gate if ((list->l_type == LT_TASKS) &&
7057c478bd9Sstevel@tonic-gate (id->id_taskid != lwp->li_info.pr_taskid))
7067c478bd9Sstevel@tonic-gate continue;
7077c478bd9Sstevel@tonic-gate if ((list->l_type == LT_PROJECTS) &&
7087c478bd9Sstevel@tonic-gate (id->id_projid != lwp->li_info.pr_projid))
7097c478bd9Sstevel@tonic-gate continue;
7107c478bd9Sstevel@tonic-gate if ((list->l_type == LT_ZONES) &&
7117c478bd9Sstevel@tonic-gate (id->id_zoneid != lwp->li_info.pr_zoneid))
7127c478bd9Sstevel@tonic-gate continue;
713c6402783Sakolb if ((list->l_type == LT_LGRPS) &&
714c6402783Sakolb (id->id_lgroup != lwp->li_info.pr_lwp.pr_lgrp))
715c6402783Sakolb continue;
7167c478bd9Sstevel@tonic-gate id->id_nproc++;
7177c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid;
7187c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid;
7197c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid;
720c6402783Sakolb id->id_lgroup = lwp->li_info.pr_lwp.pr_lgrp;
721c6402783Sakolb
7227c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) {
7237c478bd9Sstevel@tonic-gate id->id_size += lwp->li_info.pr_size;
7247c478bd9Sstevel@tonic-gate id->id_rssize += lwp->li_info.pr_rssize;
7257c478bd9Sstevel@tonic-gate }
7267c478bd9Sstevel@tonic-gate id->id_pctcpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu);
7277c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
7287c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_lwp.pr_time);
7297c478bd9Sstevel@tonic-gate else
7307c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_time);
7317c478bd9Sstevel@tonic-gate id->id_pctmem += FRC2PCT(lwp->li_info.pr_pctmem);
7327c478bd9Sstevel@tonic-gate id->id_key += lwp->li_key;
7337c478bd9Sstevel@tonic-gate total_cpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu);
7347c478bd9Sstevel@tonic-gate total_mem += FRC2PCT(lwp->li_info.pr_pctmem);
7357c478bd9Sstevel@tonic-gate return;
7367c478bd9Sstevel@tonic-gate }
7377c478bd9Sstevel@tonic-gate
7387c478bd9Sstevel@tonic-gate id = list->l_tail;
7397c478bd9Sstevel@tonic-gate id->id_next = Zalloc(sizeof (id_info_t));
7407c478bd9Sstevel@tonic-gate id->id_next->id_prev = list->l_tail;
7417c478bd9Sstevel@tonic-gate id->id_next->id_next = NULL;
7427c478bd9Sstevel@tonic-gate list->l_tail = id->id_next;
7437c478bd9Sstevel@tonic-gate id = list->l_tail;
7447c478bd9Sstevel@tonic-gate update:
7457c478bd9Sstevel@tonic-gate id->id_uid = lwp->li_info.pr_uid;
7467c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid;
7477c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid;
7487c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid;
749c6402783Sakolb id->id_lgroup = lwp->li_info.pr_lwp.pr_lgrp;
7507c478bd9Sstevel@tonic-gate id->id_nproc++;
7510209230bSgjelinek id->id_sizematch = B_FALSE;
7527c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) {
7537c478bd9Sstevel@tonic-gate id->id_size = lwp->li_info.pr_size;
7547c478bd9Sstevel@tonic-gate id->id_rssize = lwp->li_info.pr_rssize;
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate id->id_pctcpu = FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu);
7577c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS)
7587c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_lwp.pr_time);
7597c478bd9Sstevel@tonic-gate else
7607c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_time);
7617c478bd9Sstevel@tonic-gate id->id_pctmem = FRC2PCT(lwp->li_info.pr_pctmem);
7627c478bd9Sstevel@tonic-gate id->id_key = lwp->li_key;
7637c478bd9Sstevel@tonic-gate total_cpu += id->id_pctcpu;
7647c478bd9Sstevel@tonic-gate total_mem += id->id_pctmem;
7657c478bd9Sstevel@tonic-gate list->l_count++;
7667c478bd9Sstevel@tonic-gate }
7677c478bd9Sstevel@tonic-gate
7687c478bd9Sstevel@tonic-gate static void
lwp_update(lwp_info_t * lwp,pid_t pid,id_t lwpid,struct prusage * usage)7697c478bd9Sstevel@tonic-gate lwp_update(lwp_info_t *lwp, pid_t pid, id_t lwpid, struct prusage *usage)
7707c478bd9Sstevel@tonic-gate {
7717c478bd9Sstevel@tonic-gate float period;
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate if (!lwpid_is_active(pid, lwpid)) {
7747c478bd9Sstevel@tonic-gate /*
7757c478bd9Sstevel@tonic-gate * If we are reading cpu times for the first time then
7767c478bd9Sstevel@tonic-gate * calculate average cpu times based on whole process
7777c478bd9Sstevel@tonic-gate * execution time.
7787c478bd9Sstevel@tonic-gate */
7797c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
7807c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime);
7817c478bd9Sstevel@tonic-gate period = period/(float)100;
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */
7847c478bd9Sstevel@tonic-gate period = 1;
7857c478bd9Sstevel@tonic-gate lwp->li_usr = 0;
7867c478bd9Sstevel@tonic-gate lwp->li_sys = 0;
7877c478bd9Sstevel@tonic-gate lwp->li_slp = 0;
7887c478bd9Sstevel@tonic-gate } else {
7897c478bd9Sstevel@tonic-gate lwp->li_usr = TIME2NSEC(usage->pr_utime)/period;
7907c478bd9Sstevel@tonic-gate lwp->li_sys = TIME2NSEC(usage->pr_stime)/period;
7917c478bd9Sstevel@tonic-gate lwp->li_slp = TIME2NSEC(usage->pr_slptime)/period;
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate lwp->li_trp = TIME2NSEC(usage->pr_ttime)/period;
7947c478bd9Sstevel@tonic-gate lwp->li_tfl = TIME2NSEC(usage->pr_tftime)/period;
7957c478bd9Sstevel@tonic-gate lwp->li_dfl = TIME2NSEC(usage->pr_dftime)/period;
7967c478bd9Sstevel@tonic-gate lwp->li_lck = TIME2NSEC(usage->pr_ltime)/period;
7977c478bd9Sstevel@tonic-gate lwp->li_lat = TIME2NSEC(usage->pr_wtime)/period;
7987c478bd9Sstevel@tonic-gate period = (period / NANOSEC)*(float)100; /* now in seconds */
7997c478bd9Sstevel@tonic-gate lwp->li_vcx = (ulong_t)
8007c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_vctx/period));
8017c478bd9Sstevel@tonic-gate lwp->li_icx = (ulong_t)
8027c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_ictx/period));
8037c478bd9Sstevel@tonic-gate lwp->li_scl = (ulong_t)
8047c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sysc/period));
8057c478bd9Sstevel@tonic-gate lwp->li_sig = (ulong_t)
8067c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sigs/period));
8077c478bd9Sstevel@tonic-gate (void) lwpid_set_active(pid, lwpid);
8087c478bd9Sstevel@tonic-gate } else {
8097c478bd9Sstevel@tonic-gate /*
8107c478bd9Sstevel@tonic-gate * If this is not a first time we are reading a process's
8117c478bd9Sstevel@tonic-gate * CPU times then recalculate CPU times based on fresh data
8127c478bd9Sstevel@tonic-gate * obtained from procfs and previous CPU time usage values.
8137c478bd9Sstevel@tonic-gate */
8147c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime)-
8157c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_rtime);
8167c478bd9Sstevel@tonic-gate period = period/(float)100;
8177c478bd9Sstevel@tonic-gate
8187c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */
8197c478bd9Sstevel@tonic-gate period = 1;
8207c478bd9Sstevel@tonic-gate lwp->li_usr = 0;
8217c478bd9Sstevel@tonic-gate lwp->li_sys = 0;
8227c478bd9Sstevel@tonic-gate lwp->li_slp = 0;
8237c478bd9Sstevel@tonic-gate } else {
8247c478bd9Sstevel@tonic-gate lwp->li_usr = (TIME2NSEC(usage->pr_utime)-
8257c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_utime))/period;
8267c478bd9Sstevel@tonic-gate lwp->li_sys = (TIME2NSEC(usage->pr_stime) -
8277c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_stime))/period;
8287c478bd9Sstevel@tonic-gate lwp->li_slp = (TIME2NSEC(usage->pr_slptime) -
8297c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_slptime))/period;
8307c478bd9Sstevel@tonic-gate }
8317c478bd9Sstevel@tonic-gate lwp->li_trp = (TIME2NSEC(usage->pr_ttime) -
8327c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ttime))/period;
8337c478bd9Sstevel@tonic-gate lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) -
8347c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_tftime))/period;
8357c478bd9Sstevel@tonic-gate lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) -
8367c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_dftime))/period;
8377c478bd9Sstevel@tonic-gate lwp->li_lck = (TIME2NSEC(usage->pr_ltime) -
8387c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ltime))/period;
8397c478bd9Sstevel@tonic-gate lwp->li_lat = (TIME2NSEC(usage->pr_wtime) -
8407c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_wtime))/period;
8417c478bd9Sstevel@tonic-gate lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx;
8427c478bd9Sstevel@tonic-gate lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx;
8437c478bd9Sstevel@tonic-gate lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc;
8447c478bd9Sstevel@tonic-gate lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs;
8457c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t));
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate }
8487c478bd9Sstevel@tonic-gate
8497c478bd9Sstevel@tonic-gate static int
read_procfile(fd_t ** fd,char * pidstr,char * file,void * buf,size_t bufsize)8507c478bd9Sstevel@tonic-gate read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize)
8517c478bd9Sstevel@tonic-gate {
8527c478bd9Sstevel@tonic-gate char procfile[MAX_PROCFS_PATH];
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gate (void) snprintf(procfile, MAX_PROCFS_PATH,
8557c478bd9Sstevel@tonic-gate "/proc/%s/%s", pidstr, file);
8567c478bd9Sstevel@tonic-gate if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL)
8577c478bd9Sstevel@tonic-gate return (1);
8587c478bd9Sstevel@tonic-gate if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) {
8597c478bd9Sstevel@tonic-gate fd_close(*fd);
8607c478bd9Sstevel@tonic-gate return (1);
8617c478bd9Sstevel@tonic-gate }
8627c478bd9Sstevel@tonic-gate return (0);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate static void
add_proc(psinfo_t * psinfo)8667c478bd9Sstevel@tonic-gate add_proc(psinfo_t *psinfo)
8677c478bd9Sstevel@tonic-gate {
8687c478bd9Sstevel@tonic-gate lwp_info_t *lwp;
8697c478bd9Sstevel@tonic-gate id_t lwpid;
8707c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid;
8717c478bd9Sstevel@tonic-gate
8727c478bd9Sstevel@tonic-gate lwpid = psinfo->pr_lwp.pr_lwpid;
8737c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL)
8747c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid);
8757c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE | LWP_REPRESENT;
8767c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo, sizeof (psinfo_t));
8777c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_pctcpu = lwp->li_info.pr_pctcpu;
8787c478bd9Sstevel@tonic-gate }
8797c478bd9Sstevel@tonic-gate
880*ab618543SJohn Levon static void
get_lwpname(pid_t pid,id_t lwpid,char * buf,size_t bufsize)881*ab618543SJohn Levon get_lwpname(pid_t pid, id_t lwpid, char *buf, size_t bufsize)
882*ab618543SJohn Levon {
883*ab618543SJohn Levon char *path = NULL;
884*ab618543SJohn Levon int fd;
885*ab618543SJohn Levon
886*ab618543SJohn Levon buf[0] = '\0';
887*ab618543SJohn Levon
888*ab618543SJohn Levon if (asprintf(&path, "/proc/%d/lwp/%d/lwpname",
889*ab618543SJohn Levon (int)pid, (int)lwpid) == -1)
890*ab618543SJohn Levon return;
891*ab618543SJohn Levon
892*ab618543SJohn Levon if ((fd = open(path, O_RDONLY)) != -1) {
893*ab618543SJohn Levon (void) read(fd, buf, bufsize);
894*ab618543SJohn Levon buf[bufsize - 1] = '\0';
895*ab618543SJohn Levon (void) close(fd);
896*ab618543SJohn Levon }
897*ab618543SJohn Levon
898*ab618543SJohn Levon free(path);
899*ab618543SJohn Levon }
900*ab618543SJohn Levon
9017c478bd9Sstevel@tonic-gate static void
add_lwp(psinfo_t * psinfo,lwpsinfo_t * lwpsinfo,int flags)9027c478bd9Sstevel@tonic-gate add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags)
9037c478bd9Sstevel@tonic-gate {
9047c478bd9Sstevel@tonic-gate lwp_info_t *lwp;
9057c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid;
9067c478bd9Sstevel@tonic-gate id_t lwpid = lwpsinfo->pr_lwpid;
9077c478bd9Sstevel@tonic-gate
9087c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL)
9097c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid);
9107c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_REPRESENT;
9117c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE;
9127c478bd9Sstevel@tonic-gate lwp->li_flags |= flags;
9137c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo,
9147c478bd9Sstevel@tonic-gate sizeof (psinfo_t) - sizeof (lwpsinfo_t));
9157c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t));
916*ab618543SJohn Levon get_lwpname(pid, lwpid, lwp->li_lwpname, sizeof (lwp->li_lwpname));
9177c478bd9Sstevel@tonic-gate }
9187c478bd9Sstevel@tonic-gate
9197c478bd9Sstevel@tonic-gate static void
prstat_scandir(DIR * procdir)9207c478bd9Sstevel@tonic-gate prstat_scandir(DIR *procdir)
9217c478bd9Sstevel@tonic-gate {
9227c478bd9Sstevel@tonic-gate char *pidstr;
9237c478bd9Sstevel@tonic-gate pid_t pid;
9247c478bd9Sstevel@tonic-gate id_t lwpid;
9257c478bd9Sstevel@tonic-gate size_t entsz;
9267c478bd9Sstevel@tonic-gate long nlwps, nent, i;
9277c478bd9Sstevel@tonic-gate char *buf, *ptr;
9287c478bd9Sstevel@tonic-gate
9297c478bd9Sstevel@tonic-gate fds_t *fds;
9307c478bd9Sstevel@tonic-gate lwp_info_t *lwp;
9317c478bd9Sstevel@tonic-gate dirent_t *direntp;
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate prheader_t header;
9347c478bd9Sstevel@tonic-gate psinfo_t psinfo;
9357c478bd9Sstevel@tonic-gate prusage_t usage;
9367c478bd9Sstevel@tonic-gate lwpsinfo_t *lwpsinfo;
9377c478bd9Sstevel@tonic-gate prusage_t *lwpusage;
9387c478bd9Sstevel@tonic-gate
9397c478bd9Sstevel@tonic-gate total_procs = 0;
9407c478bd9Sstevel@tonic-gate total_lwps = 0;
9417c478bd9Sstevel@tonic-gate total_cpu = 0;
9427c478bd9Sstevel@tonic-gate total_mem = 0;
9437c478bd9Sstevel@tonic-gate
9447c478bd9Sstevel@tonic-gate convert_zone(&zone_tbl);
9457c478bd9Sstevel@tonic-gate for (rewinddir(procdir); (direntp = readdir(procdir)); ) {
9467c478bd9Sstevel@tonic-gate pidstr = direntp->d_name;
9477c478bd9Sstevel@tonic-gate if (pidstr[0] == '.') /* skip "." and ".." */
9487c478bd9Sstevel@tonic-gate continue;
9497c478bd9Sstevel@tonic-gate pid = atoi(pidstr);
9507c478bd9Sstevel@tonic-gate if (pid == 0 || pid == 2 || pid == 3)
9517c478bd9Sstevel@tonic-gate continue; /* skip sched, pageout and fsflush */
9527c478bd9Sstevel@tonic-gate if (has_element(&pid_tbl, pid) == 0)
9537c478bd9Sstevel@tonic-gate continue; /* check if we really want this pid */
9547c478bd9Sstevel@tonic-gate fds = fds_get(pid); /* get ptr to file descriptors */
9557c478bd9Sstevel@tonic-gate
9567c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_psinfo, pidstr,
9577c478bd9Sstevel@tonic-gate "psinfo", &psinfo, sizeof (psinfo_t)) != 0)
9587c478bd9Sstevel@tonic-gate continue;
9597c478bd9Sstevel@tonic-gate if (!has_uid(&ruid_tbl, psinfo.pr_uid) ||
9607c478bd9Sstevel@tonic-gate !has_uid(&euid_tbl, psinfo.pr_euid) ||
9617c478bd9Sstevel@tonic-gate !has_element(&prj_tbl, psinfo.pr_projid) ||
9627c478bd9Sstevel@tonic-gate !has_element(&tsk_tbl, psinfo.pr_taskid) ||
9637c478bd9Sstevel@tonic-gate !has_zone(&zone_tbl, psinfo.pr_zoneid)) {
9647c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
9657c478bd9Sstevel@tonic-gate continue;
9667c478bd9Sstevel@tonic-gate }
9677c478bd9Sstevel@tonic-gate nlwps = psinfo.pr_nlwp + psinfo.pr_nzomb;
9687c478bd9Sstevel@tonic-gate
9697c478bd9Sstevel@tonic-gate if (nlwps > 1 && (opts.o_outpmode & (OPT_LWPS | OPT_PSETS))) {
9707c478bd9Sstevel@tonic-gate int rep_lwp = 0;
9717c478bd9Sstevel@tonic-gate
9727c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lpsinfo, pidstr, "lpsinfo",
9737c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) {
9747c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
9757c478bd9Sstevel@tonic-gate continue;
9767c478bd9Sstevel@tonic-gate }
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate nent = header.pr_nent;
9797c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent;
9807c478bd9Sstevel@tonic-gate ptr = buf = Malloc(entsz);
9817c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lpsinfo), buf,
9827c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) {
9837c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo);
9847c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
9857c478bd9Sstevel@tonic-gate free(buf);
9867c478bd9Sstevel@tonic-gate continue;
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate
9897c478bd9Sstevel@tonic-gate nlwps = 0;
9907c478bd9Sstevel@tonic-gate for (i = 0; i < nent; i++, ptr += header.pr_entsize) {
9917c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/
9927c478bd9Sstevel@tonic-gate lwpsinfo = (lwpsinfo_t *)ptr;
9937c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl,
9947c478bd9Sstevel@tonic-gate lwpsinfo->pr_onpro) ||
9957c478bd9Sstevel@tonic-gate !has_element(&set_tbl,
996c6402783Sakolb lwpsinfo->pr_bindpset) ||
9974944376cSJohn Levon !has_element(&lgr_tbl, lwpsinfo->pr_lgrp))
9987c478bd9Sstevel@tonic-gate continue;
9997c478bd9Sstevel@tonic-gate nlwps++;
10007c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & (OPT_PSETS | OPT_LWPS))
10017c478bd9Sstevel@tonic-gate == OPT_PSETS) {
10027c478bd9Sstevel@tonic-gate /*
10037c478bd9Sstevel@tonic-gate * If one of process's LWPs is bound
10047c478bd9Sstevel@tonic-gate * to a given processor set, report the
10057c478bd9Sstevel@tonic-gate * whole process. We may be doing this
10067c478bd9Sstevel@tonic-gate * a few times but we'll get an accurate
10077c478bd9Sstevel@tonic-gate * lwp count in return.
10087c478bd9Sstevel@tonic-gate */
10097c478bd9Sstevel@tonic-gate add_proc(&psinfo);
10107c478bd9Sstevel@tonic-gate } else {
10117c478bd9Sstevel@tonic-gate if (rep_lwp == 0) {
10127c478bd9Sstevel@tonic-gate rep_lwp = 1;
10137c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo,
10147c478bd9Sstevel@tonic-gate LWP_REPRESENT);
10157c478bd9Sstevel@tonic-gate } else {
10167c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo, 0);
10177c478bd9Sstevel@tonic-gate }
10187c478bd9Sstevel@tonic-gate }
10197c478bd9Sstevel@tonic-gate }
10207c478bd9Sstevel@tonic-gate free(buf);
10217c478bd9Sstevel@tonic-gate if (nlwps == 0) {
10227c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo);
10237c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
10247c478bd9Sstevel@tonic-gate continue;
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate } else {
10277c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl, psinfo.pr_lwp.pr_onpro) ||
1028c6402783Sakolb !has_element(&set_tbl, psinfo.pr_lwp.pr_bindpset) ||
1029c6402783Sakolb !has_element(&lgr_tbl, psinfo.pr_lwp.pr_lgrp)) {
10307c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
10317c478bd9Sstevel@tonic-gate continue;
10327c478bd9Sstevel@tonic-gate }
10337c478bd9Sstevel@tonic-gate add_proc(&psinfo);
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_MSACCT)) {
10367c478bd9Sstevel@tonic-gate total_procs++;
10377c478bd9Sstevel@tonic-gate total_lwps += nlwps;
10387c478bd9Sstevel@tonic-gate continue;
10397c478bd9Sstevel@tonic-gate }
10407c478bd9Sstevel@tonic-gate /*
10417c478bd9Sstevel@tonic-gate * Get more information about processes from /proc/pid/usage.
10427c478bd9Sstevel@tonic-gate * If process has more than one lwp, then we may have to
10437c478bd9Sstevel@tonic-gate * also look at the /proc/pid/lusage file.
10447c478bd9Sstevel@tonic-gate */
10457c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_LWPS) && (nlwps > 1)) {
10467c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lusage, pidstr, "lusage",
10477c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) {
10487c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo);
10497c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
10507c478bd9Sstevel@tonic-gate continue;
10517c478bd9Sstevel@tonic-gate }
10527c478bd9Sstevel@tonic-gate nent = header.pr_nent;
10537c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent;
10547c478bd9Sstevel@tonic-gate buf = Malloc(entsz);
10557c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lusage), buf,
10567c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) {
10577c478bd9Sstevel@tonic-gate fd_close(fds->fds_lusage);
10587c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo);
10597c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
10607c478bd9Sstevel@tonic-gate free(buf);
10617c478bd9Sstevel@tonic-gate continue;
10627c478bd9Sstevel@tonic-gate }
10637c478bd9Sstevel@tonic-gate for (i = 1, ptr = buf + header.pr_entsize; i < nent;
10647c478bd9Sstevel@tonic-gate i++, ptr += header.pr_entsize) {
10657c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/
10667c478bd9Sstevel@tonic-gate lwpusage = (prusage_t *)ptr;
10677c478bd9Sstevel@tonic-gate lwpid = lwpusage->pr_lwpid;
10687c478bd9Sstevel@tonic-gate /*
10697c478bd9Sstevel@tonic-gate * New LWPs created after we read lpsinfo
10707c478bd9Sstevel@tonic-gate * will be ignored. Don't want to do
10717c478bd9Sstevel@tonic-gate * everything all over again.
10727c478bd9Sstevel@tonic-gate */
10737c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL)
10747c478bd9Sstevel@tonic-gate continue;
10757c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, lwpusage);
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate free(buf);
10787c478bd9Sstevel@tonic-gate } else {
10797c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_usage, pidstr, "usage",
10807c478bd9Sstevel@tonic-gate &usage, sizeof (prusage_t)) != 0) {
10817c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo);
10827c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo);
10837c478bd9Sstevel@tonic-gate continue;
10847c478bd9Sstevel@tonic-gate }
10857c478bd9Sstevel@tonic-gate lwpid = psinfo.pr_lwp.pr_lwpid;
10867c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL)
10877c478bd9Sstevel@tonic-gate continue;
10887c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, &usage);
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate total_procs++;
10917c478bd9Sstevel@tonic-gate total_lwps += nlwps;
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate fd_update();
10947c478bd9Sstevel@tonic-gate }
10957c478bd9Sstevel@tonic-gate
10967c478bd9Sstevel@tonic-gate /*
10977c478bd9Sstevel@tonic-gate * This procedure removes all dead lwps from the linked list of all lwps.
10987c478bd9Sstevel@tonic-gate * It also creates linked list of ids if necessary.
10997c478bd9Sstevel@tonic-gate */
11007c478bd9Sstevel@tonic-gate static void
list_refresh(list_t * list)11017c478bd9Sstevel@tonic-gate list_refresh(list_t *list)
11027c478bd9Sstevel@tonic-gate {
11037c478bd9Sstevel@tonic-gate lwp_info_t *lwp, *lwp_next;
11047c478bd9Sstevel@tonic-gate
11057c478bd9Sstevel@tonic-gate if (!(list->l_type & LT_LWPS))
11067c478bd9Sstevel@tonic-gate return;
11077c478bd9Sstevel@tonic-gate
11087c478bd9Sstevel@tonic-gate for (lwp = list->l_head; lwp != NULL; ) {
11097c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_ALIVE) {
11107c478bd9Sstevel@tonic-gate /*
11117c478bd9Sstevel@tonic-gate * Process all live LWPs.
11127c478bd9Sstevel@tonic-gate * When we're done, mark them as dead.
11137c478bd9Sstevel@tonic-gate * They will be marked "alive" on the next
11147c478bd9Sstevel@tonic-gate * /proc scan if they still exist.
11157c478bd9Sstevel@tonic-gate */
11167c478bd9Sstevel@tonic-gate lwp->li_key = list_getkeyval(list, lwp);
11177c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS)
11187c478bd9Sstevel@tonic-gate list_update(&users, lwp);
11197c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS)
11207c478bd9Sstevel@tonic-gate list_update(&tasks, lwp);
11217c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS)
11227c478bd9Sstevel@tonic-gate list_update(&projects, lwp);
11237c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES)
11247c478bd9Sstevel@tonic-gate list_update(&zones, lwp);
1125c6402783Sakolb if (opts.o_outpmode & OPT_LGRP)
1126c6402783Sakolb list_update(&lgroups, lwp);
11277c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_ALIVE;
11287c478bd9Sstevel@tonic-gate lwp = lwp->li_next;
11297c478bd9Sstevel@tonic-gate
11307c478bd9Sstevel@tonic-gate } else {
11317c478bd9Sstevel@tonic-gate lwp_next = lwp->li_next;
11327c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp);
11337c478bd9Sstevel@tonic-gate lwp = lwp_next;
11347c478bd9Sstevel@tonic-gate }
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate }
11377c478bd9Sstevel@tonic-gate
11387c478bd9Sstevel@tonic-gate static void
curses_on(void)1139*ab618543SJohn Levon curses_on(void)
11407c478bd9Sstevel@tonic-gate {
11417c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
11427c478bd9Sstevel@tonic-gate (void) initscr();
11437c478bd9Sstevel@tonic-gate (void) nonl();
11447c478bd9Sstevel@tonic-gate (void) putp(t_smcup);
11457c478bd9Sstevel@tonic-gate is_curses_on = TRUE;
11467c478bd9Sstevel@tonic-gate }
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate
11497c478bd9Sstevel@tonic-gate static void
curses_off(void)1150*ab618543SJohn Levon curses_off(void)
11517c478bd9Sstevel@tonic-gate {
11527c478bd9Sstevel@tonic-gate if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
11537c478bd9Sstevel@tonic-gate (void) putp(t_rmcup);
11547c478bd9Sstevel@tonic-gate (void) endwin();
11557c478bd9Sstevel@tonic-gate is_curses_on = FALSE;
11567c478bd9Sstevel@tonic-gate }
11577c478bd9Sstevel@tonic-gate (void) fflush(stdout);
11587c478bd9Sstevel@tonic-gate }
11597c478bd9Sstevel@tonic-gate
11607c478bd9Sstevel@tonic-gate static int
nlines(int * linesp,int * colsp)1161*ab618543SJohn Levon nlines(int *linesp, int *colsp)
11627c478bd9Sstevel@tonic-gate {
11637c478bd9Sstevel@tonic-gate struct winsize ws;
11647c478bd9Sstevel@tonic-gate char *envp;
11657c478bd9Sstevel@tonic-gate int n;
1166*ab618543SJohn Levon
1167*ab618543SJohn Levon *linesp = -1;
1168*ab618543SJohn Levon *colsp = -1;
11697c478bd9Sstevel@tonic-gate if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
11707c478bd9Sstevel@tonic-gate if (ws.ws_row > 0)
1171*ab618543SJohn Levon *linesp = ws.ws_row;
1172*ab618543SJohn Levon if (ws.ws_col > 0)
1173*ab618543SJohn Levon *colsp = ws.ws_col;
1174*ab618543SJohn Levon if (ws.ws_row > 0 && ws.ws_col > 0)
1175*ab618543SJohn Levon return (0);
11767c478bd9Sstevel@tonic-gate }
1177*ab618543SJohn Levon
1178*ab618543SJohn Levon if ((envp = getenv("LINES")) != NULL) {
11797c478bd9Sstevel@tonic-gate if ((n = Atoi(envp)) > 0) {
11807c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME;
1181*ab618543SJohn Levon *linesp = n;
1182*ab618543SJohn Levon }
1183*ab618543SJohn Levon }
1184*ab618543SJohn Levon if ((envp = getenv("COLUMNS")) != NULL) {
1185*ab618543SJohn Levon if ((n = Atoi(envp)) > 0) {
1186*ab618543SJohn Levon *colsp = n;
11877c478bd9Sstevel@tonic-gate }
11887c478bd9Sstevel@tonic-gate }
1189*ab618543SJohn Levon
1190*ab618543SJohn Levon return ((*linesp > 0 && *colsp > 0) ? 0 : -1);
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate
11937c478bd9Sstevel@tonic-gate static void
setmovecur(void)1194*ab618543SJohn Levon setmovecur(void)
11957c478bd9Sstevel@tonic-gate {
11967c478bd9Sstevel@tonic-gate int i, n;
11977c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_FULLSCREEN) &&
11987c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_USEHOME)) {
11997c478bd9Sstevel@tonic-gate movecur = t_home;
12007c478bd9Sstevel@tonic-gate return;
12017c478bd9Sstevel@tonic-gate }
12027c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) {
1203156d6b3aSJerry Jelinek if (opts.o_ntop == 0)
1204156d6b3aSJerry Jelinek n = opts.o_nbottom + 1;
1205156d6b3aSJerry Jelinek else
1206156d6b3aSJerry Jelinek n = opts.o_ntop + opts.o_nbottom + 2;
12077c478bd9Sstevel@tonic-gate } else {
12087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS)
12097c478bd9Sstevel@tonic-gate n = opts.o_nbottom + 1;
12107c478bd9Sstevel@tonic-gate else
12117c478bd9Sstevel@tonic-gate n = opts.o_ntop + 1;
12127c478bd9Sstevel@tonic-gate }
12134944376cSJohn Levon if (((opts.o_outpmode & OPT_UDATE) || (opts.o_outpmode & OPT_DDATE)))
12144944376cSJohn Levon n++;
12154944376cSJohn Levon
12167c478bd9Sstevel@tonic-gate if (movecur != NULL && movecur != empty_string && movecur != t_home)
12177c478bd9Sstevel@tonic-gate free(movecur);
12187c478bd9Sstevel@tonic-gate movecur = Zalloc(strlen(t_up) * (n + 5));
12197c478bd9Sstevel@tonic-gate for (i = 0; i <= n; i++)
12207c478bd9Sstevel@tonic-gate (void) strcat(movecur, t_up);
12217c478bd9Sstevel@tonic-gate }
12227c478bd9Sstevel@tonic-gate
12237c478bd9Sstevel@tonic-gate static int
setsize(void)1224*ab618543SJohn Levon setsize(void)
12257c478bd9Sstevel@tonic-gate {
12267c478bd9Sstevel@tonic-gate static int oldn = 0;
1227*ab618543SJohn Levon int cols, n, ret;
12287c478bd9Sstevel@tonic-gate
12297c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) {
1230*ab618543SJohn Levon ret = nlines(&n, &cols);
1231*ab618543SJohn Levon if (ret != -1)
1232*ab618543SJohn Levon opts.o_cols = cols;
12337c478bd9Sstevel@tonic-gate if (n == oldn)
12347c478bd9Sstevel@tonic-gate return (0);
12357c478bd9Sstevel@tonic-gate oldn = n;
1236*ab618543SJohn Levon if (ret == -1) {
12377c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME;
12387c478bd9Sstevel@tonic-gate setmovecur(); /* set default window size */
12397c478bd9Sstevel@tonic-gate return (1);
12407c478bd9Sstevel@tonic-gate }
12417c478bd9Sstevel@tonic-gate n = n - 3; /* minus header, total and cursor lines */
12424944376cSJohn Levon if ((opts.o_outpmode & OPT_UDATE) ||
12434944376cSJohn Levon (opts.o_outpmode & OPT_DDATE))
12444944376cSJohn Levon n--; /* minus timestamp */
12457c478bd9Sstevel@tonic-gate if (n < 1)
12467c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n"));
12477c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) {
12487c478bd9Sstevel@tonic-gate if (n < 8) {
12497c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n"));
12507c478bd9Sstevel@tonic-gate } else {
12517c478bd9Sstevel@tonic-gate opts.o_ntop = (n / 4) * 3;
12527c478bd9Sstevel@tonic-gate opts.o_nbottom = n - 1 - opts.o_ntop;
12537c478bd9Sstevel@tonic-gate }
12547c478bd9Sstevel@tonic-gate } else {
12557c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS)
12567c478bd9Sstevel@tonic-gate opts.o_nbottom = n;
12577c478bd9Sstevel@tonic-gate else
12587c478bd9Sstevel@tonic-gate opts.o_ntop = n;
12597c478bd9Sstevel@tonic-gate }
12607c478bd9Sstevel@tonic-gate }
12617c478bd9Sstevel@tonic-gate setmovecur();
12627c478bd9Sstevel@tonic-gate return (1);
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate
12657c478bd9Sstevel@tonic-gate static void
ldtermcap()12667c478bd9Sstevel@tonic-gate ldtermcap()
12677c478bd9Sstevel@tonic-gate {
12687c478bd9Sstevel@tonic-gate int err;
12697c478bd9Sstevel@tonic-gate if (setupterm(NULL, STDIN_FILENO, &err) == ERR) {
12707c478bd9Sstevel@tonic-gate switch (err) {
12717c478bd9Sstevel@tonic-gate case 0:
12727c478bd9Sstevel@tonic-gate Warn(gettext("failed to load terminal info, "
12737c478bd9Sstevel@tonic-gate "defaulting to -c option\n"));
12747c478bd9Sstevel@tonic-gate break;
12757c478bd9Sstevel@tonic-gate case -1:
12767c478bd9Sstevel@tonic-gate Warn(gettext("terminfo database not found, "
12777c478bd9Sstevel@tonic-gate "defaulting to -c option\n"));
12787c478bd9Sstevel@tonic-gate break;
12797c478bd9Sstevel@tonic-gate default:
12807c478bd9Sstevel@tonic-gate Warn(gettext("failed to initialize terminal, "
12817c478bd9Sstevel@tonic-gate "defaulting to -c option\n"));
12827c478bd9Sstevel@tonic-gate }
12837c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP;
12847c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string;
12857c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string;
12867c478bd9Sstevel@tonic-gate return;
12877c478bd9Sstevel@tonic-gate }
12887c478bd9Sstevel@tonic-gate t_ulon = tigetstr("smul");
12897c478bd9Sstevel@tonic-gate t_uloff = tigetstr("rmul");
12907c478bd9Sstevel@tonic-gate t_up = tigetstr("cuu1");
12917c478bd9Sstevel@tonic-gate t_eol = tigetstr("el");
12927c478bd9Sstevel@tonic-gate t_smcup = tigetstr("smcup");
12937c478bd9Sstevel@tonic-gate t_rmcup = tigetstr("rmcup");
12947c478bd9Sstevel@tonic-gate t_home = tigetstr("home");
12957c478bd9Sstevel@tonic-gate if ((t_up == (char *)-1) || (t_eol == (char *)-1) ||
12967c478bd9Sstevel@tonic-gate (t_smcup == (char *)-1) || (t_rmcup == (char *)-1)) {
12977c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP;
12987c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string;
12997c478bd9Sstevel@tonic-gate return;
13007c478bd9Sstevel@tonic-gate }
13017c478bd9Sstevel@tonic-gate if (t_up == NULL || t_eol == NULL) {
13027c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP;
13037c478bd9Sstevel@tonic-gate t_eol = t_up = movecur = empty_string;
13047c478bd9Sstevel@tonic-gate return;
13057c478bd9Sstevel@tonic-gate }
13067c478bd9Sstevel@tonic-gate if (t_ulon == (char *)-1 || t_uloff == (char *)-1 ||
13077c478bd9Sstevel@tonic-gate t_ulon == NULL || t_uloff == NULL) {
13087c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string; /* can live without it */
13097c478bd9Sstevel@tonic-gate }
13107c478bd9Sstevel@tonic-gate if (t_smcup == NULL || t_rmcup == NULL)
13117c478bd9Sstevel@tonic-gate t_smcup = t_rmcup = empty_string;
13127c478bd9Sstevel@tonic-gate if (t_home == (char *)-1 || t_home == NULL) {
13137c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME;
13147c478bd9Sstevel@tonic-gate t_home = empty_string;
13157c478bd9Sstevel@tonic-gate }
13167c478bd9Sstevel@tonic-gate }
13177c478bd9Sstevel@tonic-gate
13187c478bd9Sstevel@tonic-gate static void
sig_handler(int sig)13197c478bd9Sstevel@tonic-gate sig_handler(int sig)
13207c478bd9Sstevel@tonic-gate {
13217c478bd9Sstevel@tonic-gate switch (sig) {
13227c478bd9Sstevel@tonic-gate case SIGTSTP: sigtstp = 1;
13237c478bd9Sstevel@tonic-gate break;
13247c478bd9Sstevel@tonic-gate case SIGWINCH: sigwinch = 1;
13257c478bd9Sstevel@tonic-gate break;
13267c478bd9Sstevel@tonic-gate case SIGINT:
13277c478bd9Sstevel@tonic-gate case SIGTERM: sigterm = 1;
13287c478bd9Sstevel@tonic-gate break;
13297c478bd9Sstevel@tonic-gate }
13307c478bd9Sstevel@tonic-gate }
13317c478bd9Sstevel@tonic-gate
13327c478bd9Sstevel@tonic-gate static void
set_signals()13337c478bd9Sstevel@tonic-gate set_signals()
13347c478bd9Sstevel@tonic-gate {
13357c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler);
13367c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sig_handler);
13377c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, sig_handler);
13387c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN)
13397c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler);
13407c478bd9Sstevel@tonic-gate }
13417c478bd9Sstevel@tonic-gate
13427c478bd9Sstevel@tonic-gate static void
fill_table(table_t * table,char * arg,char option)1343a851ab35Svb fill_table(table_t *table, char *arg, char option)
13447c478bd9Sstevel@tonic-gate {
13457c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", ");
13467c478bd9Sstevel@tonic-gate
1347a851ab35Svb if (p == NULL)
1348a851ab35Svb Die(gettext("invalid argument for -%c\n"), option);
1349a851ab35Svb
1350a851ab35Svb add_element(table, (long)Atoi(p));
1351a851ab35Svb while (p = strtok(NULL, ", "))
1352a851ab35Svb add_element(table, (long)Atoi(p));
13537c478bd9Sstevel@tonic-gate }
13547c478bd9Sstevel@tonic-gate
13557c478bd9Sstevel@tonic-gate static void
fill_prj_table(char * arg)13567c478bd9Sstevel@tonic-gate fill_prj_table(char *arg)
13577c478bd9Sstevel@tonic-gate {
13587c478bd9Sstevel@tonic-gate projid_t projid;
13597c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", ");
13607c478bd9Sstevel@tonic-gate
1361a851ab35Svb if (p == NULL)
1362a851ab35Svb Die(gettext("invalid argument for -j\n"));
1363a851ab35Svb
13647c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1)
13657c478bd9Sstevel@tonic-gate projid = Atoi(p);
13667c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid);
13677c478bd9Sstevel@tonic-gate
13687c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) {
13697c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1)
13707c478bd9Sstevel@tonic-gate projid = Atoi(p);
13717c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid);
13727c478bd9Sstevel@tonic-gate }
13737c478bd9Sstevel@tonic-gate }
13747c478bd9Sstevel@tonic-gate
13757c478bd9Sstevel@tonic-gate static void
fill_set_table(char * arg)13767c478bd9Sstevel@tonic-gate fill_set_table(char *arg)
13777c478bd9Sstevel@tonic-gate {
13787c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", ");
13797c478bd9Sstevel@tonic-gate psetid_t id;
13807c478bd9Sstevel@tonic-gate
1381a851ab35Svb if (p == NULL)
1382a851ab35Svb Die(gettext("invalid argument for -C\n"));
1383a851ab35Svb
13847c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0)
13857c478bd9Sstevel@tonic-gate id = PS_NONE;
13867c478bd9Sstevel@tonic-gate add_element(&set_tbl, id);
13877c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) {
13887c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0)
13897c478bd9Sstevel@tonic-gate id = PS_NONE;
13907c478bd9Sstevel@tonic-gate if (!has_element(&set_tbl, id))
13917c478bd9Sstevel@tonic-gate add_element(&set_tbl, id);
13927c478bd9Sstevel@tonic-gate }
13937c478bd9Sstevel@tonic-gate }
13947c478bd9Sstevel@tonic-gate
13957c478bd9Sstevel@tonic-gate static void
Exit()13967c478bd9Sstevel@tonic-gate Exit()
13977c478bd9Sstevel@tonic-gate {
13987c478bd9Sstevel@tonic-gate curses_off();
13997c478bd9Sstevel@tonic-gate list_clear(&lwps);
14007c478bd9Sstevel@tonic-gate list_clear(&users);
14017c478bd9Sstevel@tonic-gate list_clear(&tasks);
14027c478bd9Sstevel@tonic-gate list_clear(&projects);
14037c478bd9Sstevel@tonic-gate list_clear(&zones);
14047c478bd9Sstevel@tonic-gate fd_exit();
14057c478bd9Sstevel@tonic-gate }
14067c478bd9Sstevel@tonic-gate
14070209230bSgjelinek
14087c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)14097c478bd9Sstevel@tonic-gate main(int argc, char **argv)
14107c478bd9Sstevel@tonic-gate {
14117c478bd9Sstevel@tonic-gate DIR *procdir;
14127c478bd9Sstevel@tonic-gate char *p;
14137c478bd9Sstevel@tonic-gate char *sortk = "cpu"; /* default sort key */
14147c478bd9Sstevel@tonic-gate int opt;
14157c478bd9Sstevel@tonic-gate int timeout;
14167c478bd9Sstevel@tonic-gate struct pollfd pollset;
14177c478bd9Sstevel@tonic-gate char key;
14187c478bd9Sstevel@tonic-gate
14197c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
14207c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
14217c478bd9Sstevel@tonic-gate Progname(argv[0]);
14227c478bd9Sstevel@tonic-gate lwpid_init();
14237c478bd9Sstevel@tonic-gate fd_init(Setrlimit());
14247c478bd9Sstevel@tonic-gate
14250209230bSgjelinek pagesize = sysconf(_SC_PAGESIZE);
14260209230bSgjelinek
14274944376cSJohn Levon while ((opt = getopt(argc, argv,
14280a1278f2SGary Mills "vcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) {
14297c478bd9Sstevel@tonic-gate switch (opt) {
14307166d658SMenno Lageman case 'r':
14317166d658SMenno Lageman opts.o_outpmode |= OPT_NORESOLVE;
14327166d658SMenno Lageman break;
14337c478bd9Sstevel@tonic-gate case 'R':
14347c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_REALTIME;
14357c478bd9Sstevel@tonic-gate break;
14367c478bd9Sstevel@tonic-gate case 'c':
14377c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP;
14387c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN;
14397c478bd9Sstevel@tonic-gate break;
14404944376cSJohn Levon case 'd':
14414944376cSJohn Levon if (optarg) {
14424944376cSJohn Levon if (*optarg == 'u')
14434944376cSJohn Levon opts.o_outpmode |= OPT_UDATE;
14444944376cSJohn Levon else if (*optarg == 'd')
14454944376cSJohn Levon opts.o_outpmode |= OPT_DDATE;
14464944376cSJohn Levon else
14474944376cSJohn Levon Usage();
14484944376cSJohn Levon } else {
14494944376cSJohn Levon Usage();
14504944376cSJohn Levon }
14514944376cSJohn Levon break;
1452c6402783Sakolb case 'h':
1453c6402783Sakolb fill_table(&lgr_tbl, optarg, 'h');
1454c6402783Sakolb break;
1455c6402783Sakolb case 'H':
1456c6402783Sakolb opts.o_outpmode |= OPT_LGRP;
1457c6402783Sakolb break;
14587c478bd9Sstevel@tonic-gate case 'm':
14597c478bd9Sstevel@tonic-gate case 'v':
14607c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO;
14617c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_MSACCT;
14627c478bd9Sstevel@tonic-gate break;
14637c478bd9Sstevel@tonic-gate case 't':
14647c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO;
14657c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_USERS;
14667c478bd9Sstevel@tonic-gate break;
14677c478bd9Sstevel@tonic-gate case 'a':
14687c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_USERS;
14697c478bd9Sstevel@tonic-gate break;
14707c478bd9Sstevel@tonic-gate case 'T':
14717c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_TASKS;
14727c478bd9Sstevel@tonic-gate break;
14737c478bd9Sstevel@tonic-gate case 'J':
14747c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_PROJECTS;
14757c478bd9Sstevel@tonic-gate break;
14767c478bd9Sstevel@tonic-gate case 'n':
1477a851ab35Svb if ((p = strtok(optarg, ",")) == NULL)
1478a851ab35Svb Die(gettext("invalid argument for -n\n"));
14797c478bd9Sstevel@tonic-gate opts.o_ntop = Atoi(p);
14807c478bd9Sstevel@tonic-gate if (p = strtok(NULL, ","))
14817c478bd9Sstevel@tonic-gate opts.o_nbottom = Atoi(p);
1482156d6b3aSJerry Jelinek else if (opts.o_ntop == 0)
1483156d6b3aSJerry Jelinek opts.o_nbottom = 5;
14847c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN;
14857c478bd9Sstevel@tonic-gate break;
14867c478bd9Sstevel@tonic-gate case 's':
14877c478bd9Sstevel@tonic-gate opts.o_sortorder = -1;
14887c478bd9Sstevel@tonic-gate sortk = optarg;
14897c478bd9Sstevel@tonic-gate break;
14907c478bd9Sstevel@tonic-gate case 'S':
14917c478bd9Sstevel@tonic-gate opts.o_sortorder = 1;
14927c478bd9Sstevel@tonic-gate sortk = optarg;
14937c478bd9Sstevel@tonic-gate break;
14947c478bd9Sstevel@tonic-gate case 'u':
1495a851ab35Svb if ((p = strtok(optarg, ", ")) == NULL)
1496a851ab35Svb Die(gettext("invalid argument for -u\n"));
14977c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p);
14987c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", "))
14997c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p);
15007c478bd9Sstevel@tonic-gate break;
15017c478bd9Sstevel@tonic-gate case 'U':
1502a851ab35Svb if ((p = strtok(optarg, ", ")) == NULL)
1503a851ab35Svb Die(gettext("invalid argument for -U\n"));
15047c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p);
15057c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", "))
15067c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p);
15077c478bd9Sstevel@tonic-gate break;
15087c478bd9Sstevel@tonic-gate case 'p':
1509a851ab35Svb fill_table(&pid_tbl, optarg, 'p');
15107c478bd9Sstevel@tonic-gate break;
15117c478bd9Sstevel@tonic-gate case 'C':
15127c478bd9Sstevel@tonic-gate fill_set_table(optarg);
15137c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_PSETS;
15147c478bd9Sstevel@tonic-gate break;
15157c478bd9Sstevel@tonic-gate case 'P':
1516a851ab35Svb fill_table(&cpu_tbl, optarg, 'P');
15177c478bd9Sstevel@tonic-gate break;
15187c478bd9Sstevel@tonic-gate case 'k':
1519a851ab35Svb fill_table(&tsk_tbl, optarg, 'k');
15207c478bd9Sstevel@tonic-gate break;
15217c478bd9Sstevel@tonic-gate case 'j':
15227c478bd9Sstevel@tonic-gate fill_prj_table(optarg);
15237c478bd9Sstevel@tonic-gate break;
15247c478bd9Sstevel@tonic-gate case 'L':
15257c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_LWPS;
15267c478bd9Sstevel@tonic-gate break;
15270a1278f2SGary Mills case 'W':
15280a1278f2SGary Mills opts.o_outpmode |= OPT_TRUNC;
15290a1278f2SGary Mills break;
15307c478bd9Sstevel@tonic-gate case 'z':
1531a851ab35Svb if ((p = strtok(optarg, ", ")) == NULL)
1532a851ab35Svb Die(gettext("invalid argument for -z\n"));
15337c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p);
15347c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", "))
15357c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p);
15367c478bd9Sstevel@tonic-gate break;
15377c478bd9Sstevel@tonic-gate case 'Z':
15387c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_ZONES;
15397c478bd9Sstevel@tonic-gate break;
15407c478bd9Sstevel@tonic-gate default:
15417c478bd9Sstevel@tonic-gate Usage();
15427c478bd9Sstevel@tonic-gate }
15437c478bd9Sstevel@tonic-gate }
15447c478bd9Sstevel@tonic-gate
15457c478bd9Sstevel@tonic-gate (void) atexit(Exit);
15467c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) &&
15477c478bd9Sstevel@tonic-gate !(opts.o_outpmode & OPT_SPLIT))
15487c478bd9Sstevel@tonic-gate opts.o_nbottom = opts.o_ntop;
1549156d6b3aSJerry Jelinek if (!(opts.o_outpmode & OPT_SPLIT) && opts.o_ntop == 0)
1550156d6b3aSJerry Jelinek Die(gettext("invalid argument for -n\n"));
1551156d6b3aSJerry Jelinek if (opts.o_nbottom == 0)
15527c478bd9Sstevel@tonic-gate Die(gettext("invalid argument for -n\n"));
15537c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) &&
15547c478bd9Sstevel@tonic-gate ((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT))))
15557c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with -v or -m\n"));
15567c478bd9Sstevel@tonic-gate
155751de0612SRichard Lowe if ((opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) &&
15587c478bd9Sstevel@tonic-gate !((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT))))
15597c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with "
15607c478bd9Sstevel@tonic-gate "-a, -J, -T or -Z\n"));
15617c478bd9Sstevel@tonic-gate
15627c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) &&
15634944376cSJohn Levon (opts.o_outpmode & (OPT_TASKS | OPT_PROJECTS | OPT_ZONES)))
15647c478bd9Sstevel@tonic-gate Die(gettext("-a option cannot be used with "
15657c478bd9Sstevel@tonic-gate "-t, -J, -T or -Z\n"));
15667c478bd9Sstevel@tonic-gate
15677c478bd9Sstevel@tonic-gate if (((opts.o_outpmode & OPT_TASKS) &&
15687c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_PROJECTS|OPT_ZONES))) ||
15697c478bd9Sstevel@tonic-gate ((opts.o_outpmode & OPT_PROJECTS) &&
15704944376cSJohn Levon (opts.o_outpmode & (OPT_TASKS|OPT_ZONES)))) {
1571c6402783Sakolb Die(gettext(
1572c6402783Sakolb "-J, -T and -Z options are mutually exclusive\n"));
1573c6402783Sakolb }
1574c6402783Sakolb
1575c6402783Sakolb /*
1576c6402783Sakolb * There is not enough space to combine microstate information and
1577c6402783Sakolb * lgroup information and still fit in 80-column output.
1578c6402783Sakolb */
1579c6402783Sakolb if ((opts.o_outpmode & OPT_LGRP) && (opts.o_outpmode & OPT_MSACCT)) {
1580c6402783Sakolb Die(gettext("-H and -m options are mutually exclusive\n"));
15817c478bd9Sstevel@tonic-gate }
15827c478bd9Sstevel@tonic-gate
15837c478bd9Sstevel@tonic-gate if (argc > optind)
15847c478bd9Sstevel@tonic-gate opts.o_interval = Atoi(argv[optind++]);
15857c478bd9Sstevel@tonic-gate if (argc > optind)
15867c478bd9Sstevel@tonic-gate opts.o_count = Atoi(argv[optind++]);
15877c478bd9Sstevel@tonic-gate if (opts.o_count == 0)
15887c478bd9Sstevel@tonic-gate Die(gettext("invalid counter value\n"));
15897c478bd9Sstevel@tonic-gate if (argc > optind)
15907c478bd9Sstevel@tonic-gate Usage();
15917c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_REALTIME)
15927c478bd9Sstevel@tonic-gate Priocntl("RT");
15937c478bd9Sstevel@tonic-gate if (isatty(STDOUT_FILENO) == 1 && isatty(STDIN_FILENO))
15947c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_TTY; /* interactive */
15957c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_TTY)) {
15967c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; /* no termcap for pipes */
15977c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN;
15987c478bd9Sstevel@tonic-gate }
15997c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP)
16007c478bd9Sstevel@tonic-gate ldtermcap(); /* can turn OPT_TERMCAP off */
16017c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP)
16027c478bd9Sstevel@tonic-gate (void) setsize();
16037c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop);
16047c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom);
16057c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom);
16067c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom);
16077c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom);
1608c6402783Sakolb list_alloc(&lgroups, opts.o_nbottom);
16097c478bd9Sstevel@tonic-gate list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS);
16107c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &users, LT_USERS);
16117c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS);
16127c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS);
16137c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &zones, LT_ZONES);
1614c6402783Sakolb list_setkeyfunc(NULL, &opts, &lgroups, LT_LGRPS);
16157c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP)
16167c478bd9Sstevel@tonic-gate curses_on();
16177c478bd9Sstevel@tonic-gate if ((procdir = opendir("/proc")) == NULL)
16187c478bd9Sstevel@tonic-gate Die(gettext("cannot open /proc directory\n"));
16197c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) {
16207c478bd9Sstevel@tonic-gate (void) printf(gettext("Please wait...\r"));
16214944376cSJohn Levon if (!(opts.o_outpmode & OPT_TERMCAP))
16224944376cSJohn Levon (void) putchar('\n');
16237c478bd9Sstevel@tonic-gate (void) fflush(stdout);
16247c478bd9Sstevel@tonic-gate }
16257c478bd9Sstevel@tonic-gate set_signals();
16267c478bd9Sstevel@tonic-gate pollset.fd = STDIN_FILENO;
16277c478bd9Sstevel@tonic-gate pollset.events = POLLIN;
16287c478bd9Sstevel@tonic-gate timeout = opts.o_interval * MILLISEC;
16297c478bd9Sstevel@tonic-gate
16307c478bd9Sstevel@tonic-gate /*
16317c478bd9Sstevel@tonic-gate * main program loop
16327c478bd9Sstevel@tonic-gate */
16337c478bd9Sstevel@tonic-gate do {
16347c478bd9Sstevel@tonic-gate if (sigterm == 1)
16357c478bd9Sstevel@tonic-gate break;
16367c478bd9Sstevel@tonic-gate if (sigtstp == 1) {
16377c478bd9Sstevel@tonic-gate curses_off();
16387c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, SIG_DFL);
16397c478bd9Sstevel@tonic-gate (void) kill(0, SIGTSTP);
16407c478bd9Sstevel@tonic-gate /*
16417c478bd9Sstevel@tonic-gate * prstat stops here until it receives SIGCONT signal.
16427c478bd9Sstevel@tonic-gate */
16437c478bd9Sstevel@tonic-gate sigtstp = 0;
16447c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler);
16457c478bd9Sstevel@tonic-gate curses_on();
16467c478bd9Sstevel@tonic-gate print_movecur = FALSE;
16477c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN)
16487c478bd9Sstevel@tonic-gate sigwinch = 1;
16497c478bd9Sstevel@tonic-gate }
16507c478bd9Sstevel@tonic-gate if (sigwinch == 1) {
16517c478bd9Sstevel@tonic-gate if (setsize() == 1) {
16527c478bd9Sstevel@tonic-gate list_free(&lwps);
16537c478bd9Sstevel@tonic-gate list_free(&users);
16547c478bd9Sstevel@tonic-gate list_free(&tasks);
16557c478bd9Sstevel@tonic-gate list_free(&projects);
16567c478bd9Sstevel@tonic-gate list_free(&zones);
16577c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop);
16587c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom);
16597c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom);
16607c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom);
16617c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom);
16627c478bd9Sstevel@tonic-gate }
16637c478bd9Sstevel@tonic-gate sigwinch = 0;
16647c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler);
16657c478bd9Sstevel@tonic-gate }
16667c478bd9Sstevel@tonic-gate prstat_scandir(procdir);
16677c478bd9Sstevel@tonic-gate list_refresh(&lwps);
16687c478bd9Sstevel@tonic-gate if (print_movecur)
16697c478bd9Sstevel@tonic-gate (void) putp(movecur);
16707c478bd9Sstevel@tonic-gate print_movecur = TRUE;
16717c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_PSINFO) ||
16727c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_MSACCT)) {
16737c478bd9Sstevel@tonic-gate list_sort(&lwps);
16747c478bd9Sstevel@tonic-gate list_print(&lwps);
16757c478bd9Sstevel@tonic-gate }
16767c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) {
16770209230bSgjelinek list_getsize(&users);
16787c478bd9Sstevel@tonic-gate list_sort(&users);
16797c478bd9Sstevel@tonic-gate list_print(&users);
16807c478bd9Sstevel@tonic-gate list_clear(&users);
16817c478bd9Sstevel@tonic-gate }
16827c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS) {
16830209230bSgjelinek list_getsize(&tasks);
16847c478bd9Sstevel@tonic-gate list_sort(&tasks);
16857c478bd9Sstevel@tonic-gate list_print(&tasks);
16867c478bd9Sstevel@tonic-gate list_clear(&tasks);
16877c478bd9Sstevel@tonic-gate }
16887c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS) {
16890209230bSgjelinek list_getsize(&projects);
16907c478bd9Sstevel@tonic-gate list_sort(&projects);
16917c478bd9Sstevel@tonic-gate list_print(&projects);
16927c478bd9Sstevel@tonic-gate list_clear(&projects);
16937c478bd9Sstevel@tonic-gate }
16947c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES) {
16950209230bSgjelinek list_getsize(&zones);
16967c478bd9Sstevel@tonic-gate list_sort(&zones);
16977c478bd9Sstevel@tonic-gate list_print(&zones);
16987c478bd9Sstevel@tonic-gate list_clear(&zones);
16997c478bd9Sstevel@tonic-gate }
17007c478bd9Sstevel@tonic-gate if (opts.o_count == 1)
17017c478bd9Sstevel@tonic-gate break;
17027c478bd9Sstevel@tonic-gate /*
17037c478bd9Sstevel@tonic-gate * If poll() returns -1 and sets errno to EINTR here because
17047c478bd9Sstevel@tonic-gate * the process received a signal, it is Ok to abort this
17057c478bd9Sstevel@tonic-gate * timeout and loop around because we check the signals at the
17067c478bd9Sstevel@tonic-gate * top of the loop.
17077c478bd9Sstevel@tonic-gate */
17087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) {
17097c478bd9Sstevel@tonic-gate if (poll(&pollset, (nfds_t)1, timeout) > 0) {
17107c478bd9Sstevel@tonic-gate if (read(STDIN_FILENO, &key, 1) == 1) {
17117c478bd9Sstevel@tonic-gate if (tolower(key) == 'q')
17127c478bd9Sstevel@tonic-gate break;
17137c478bd9Sstevel@tonic-gate }
17147c478bd9Sstevel@tonic-gate }
17157c478bd9Sstevel@tonic-gate } else {
17167c478bd9Sstevel@tonic-gate (void) sleep(opts.o_interval);
17177c478bd9Sstevel@tonic-gate }
17187c478bd9Sstevel@tonic-gate } while (opts.o_count == (-1) || --opts.o_count);
17197c478bd9Sstevel@tonic-gate
17207c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY)
17217c478bd9Sstevel@tonic-gate (void) putchar('\r');
17227c478bd9Sstevel@tonic-gate return (0);
17237c478bd9Sstevel@tonic-gate }
1724