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 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/resource.h> 337c478bd9Sstevel@tonic-gate #include <sys/loadavg.h> 347c478bd9Sstevel@tonic-gate #include <sys/time.h> 357c478bd9Sstevel@tonic-gate #include <sys/pset.h> 360209230bSgjelinek #include <sys/vm_usage.h> 377c478bd9Sstevel@tonic-gate #include <zone.h> 387c478bd9Sstevel@tonic-gate #include <libzonecfg.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include <stdio.h> 417c478bd9Sstevel@tonic-gate #include <stdlib.h> 427c478bd9Sstevel@tonic-gate #include <unistd.h> 437c478bd9Sstevel@tonic-gate #include <dirent.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <errno.h> 467c478bd9Sstevel@tonic-gate #include <poll.h> 477c478bd9Sstevel@tonic-gate #include <ctype.h> 487c478bd9Sstevel@tonic-gate #include <fcntl.h> 497c478bd9Sstevel@tonic-gate #include <limits.h> 507c478bd9Sstevel@tonic-gate #include <signal.h> 517c478bd9Sstevel@tonic-gate #include <time.h> 527c478bd9Sstevel@tonic-gate #include <project.h> 537c478bd9Sstevel@tonic-gate 544944376cSJohn Levon #include <langinfo.h> 557c478bd9Sstevel@tonic-gate #include <libintl.h> 567c478bd9Sstevel@tonic-gate #include <locale.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #include "prstat.h" 597c478bd9Sstevel@tonic-gate #include "prutil.h" 607c478bd9Sstevel@tonic-gate #include "prtable.h" 617c478bd9Sstevel@tonic-gate #include "prsort.h" 627c478bd9Sstevel@tonic-gate #include "prfile.h" 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * x86 <sys/regs.h> ERR conflicts with <curses.h> ERR. For the purposes 667c478bd9Sstevel@tonic-gate * of this file, we care about the curses.h ERR so include that last. 677c478bd9Sstevel@tonic-gate */ 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate #if defined(ERR) 707c478bd9Sstevel@tonic-gate #undef ERR 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN /* should be defined by cc -D */ 747c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* use this only if it wasn't */ 757c478bd9Sstevel@tonic-gate #endif 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate #include <curses.h> 787c478bd9Sstevel@tonic-gate #include <term.h> 797c478bd9Sstevel@tonic-gate 800a1278f2SGary Mills #define LOGIN_WIDTH 8 810a1278f2SGary Mills #define ZONE_WIDTH 28 820a1278f2SGary Mills #define PROJECT_WIDTH 28 830a1278f2SGary Mills 847c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_PROC \ 857c478bd9Sstevel@tonic-gate " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP " 86c6402783Sakolb #define PSINFO_HEADER_PROC_LGRP \ 87c6402783Sakolb " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/NLWP " 887c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_LWP \ 897c478bd9Sstevel@tonic-gate " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID " 90c6402783Sakolb #define PSINFO_HEADER_LWP_LGRP \ 91c6402783Sakolb " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWPID " 927c478bd9Sstevel@tonic-gate #define USAGE_HEADER_PROC \ 937c478bd9Sstevel@tonic-gate " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP " 947c478bd9Sstevel@tonic-gate #define USAGE_HEADER_LWP \ 957c478bd9Sstevel@tonic-gate " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID " 967c478bd9Sstevel@tonic-gate #define USER_HEADER_PROC \ 970209230bSgjelinek " NPROC USERNAME SWAP RSS MEMORY TIME CPU " 987c478bd9Sstevel@tonic-gate #define USER_HEADER_LWP \ 990209230bSgjelinek " NLWP USERNAME SWAP RSS MEMORY TIME CPU " 1007c478bd9Sstevel@tonic-gate #define TASK_HEADER_PROC \ 1010209230bSgjelinek "TASKID NPROC SWAP RSS MEMORY TIME CPU PROJECT " 1027c478bd9Sstevel@tonic-gate #define TASK_HEADER_LWP \ 1030209230bSgjelinek "TASKID NLWP SWAP RSS MEMORY TIME CPU PROJECT " 1047c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_PROC \ 1050209230bSgjelinek "PROJID NPROC SWAP RSS MEMORY TIME CPU PROJECT " 1067c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_LWP \ 1070209230bSgjelinek "PROJID NLWP SWAP RSS MEMORY TIME CPU PROJECT " 1087c478bd9Sstevel@tonic-gate #define ZONE_HEADER_PROC \ 1090209230bSgjelinek "ZONEID NPROC SWAP RSS MEMORY TIME CPU ZONE " 1107c478bd9Sstevel@tonic-gate #define ZONE_HEADER_LWP \ 1110209230bSgjelinek "ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE " 1127c478bd9Sstevel@tonic-gate #define PSINFO_LINE \ 1137c478bd9Sstevel@tonic-gate "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d" 114c6402783Sakolb #define PSINFO_LINE_LGRP \ 115c6402783Sakolb "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d" 1167c478bd9Sstevel@tonic-gate #define USAGE_LINE \ 1170a1278f2SGary Mills "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\ 1180a1278f2SGary Mills "%3.3s %3.3s %-.12s/%d" 1197c478bd9Sstevel@tonic-gate #define USER_LINE \ 1207c478bd9Sstevel@tonic-gate "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%" 1217c478bd9Sstevel@tonic-gate #define TASK_LINE \ 1227c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 1237c478bd9Sstevel@tonic-gate #define PROJECT_LINE \ 1247c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 1257c478bd9Sstevel@tonic-gate #define ZONE_LINE \ 1267c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate #define TOTAL_LINE \ 1297c478bd9Sstevel@tonic-gate "Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f" 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* global variables */ 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate static char *t_ulon; /* termcap: start underline */ 1347c478bd9Sstevel@tonic-gate static char *t_uloff; /* termcap: end underline */ 1357c478bd9Sstevel@tonic-gate static char *t_up; /* termcap: cursor 1 line up */ 1367c478bd9Sstevel@tonic-gate static char *t_eol; /* termcap: clear end of line */ 1377c478bd9Sstevel@tonic-gate static char *t_smcup; /* termcap: cursor mvcap on */ 1387c478bd9Sstevel@tonic-gate static char *t_rmcup; /* termcap: cursor mvcap off */ 1397c478bd9Sstevel@tonic-gate static char *t_home; /* termcap: move cursor home */ 1407c478bd9Sstevel@tonic-gate static char *movecur = NULL; /* termcap: move up string */ 1417c478bd9Sstevel@tonic-gate static char *empty_string = "\0"; /* termcap: empty string */ 1427c478bd9Sstevel@tonic-gate static uint_t print_movecur = FALSE; /* print movecur or not */ 1437c478bd9Sstevel@tonic-gate static int is_curses_on = FALSE; /* current curses state */ 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate static table_t pid_tbl = {0, 0, NULL}; /* selected processes */ 1467c478bd9Sstevel@tonic-gate static table_t cpu_tbl = {0, 0, NULL}; /* selected processors */ 1477c478bd9Sstevel@tonic-gate static table_t set_tbl = {0, 0, NULL}; /* selected processor sets */ 1487c478bd9Sstevel@tonic-gate static table_t prj_tbl = {0, 0, NULL}; /* selected projects */ 1497c478bd9Sstevel@tonic-gate static table_t tsk_tbl = {0, 0, NULL}; /* selected tasks */ 150c6402783Sakolb static table_t lgr_tbl = {0, 0, NULL}; /* selected lgroups */ 1517c478bd9Sstevel@tonic-gate static zonetbl_t zone_tbl = {0, 0, NULL}; /* selected zones */ 1527166d658SMenno Lageman static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */ 1537166d658SMenno Lageman static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */ 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate static uint_t total_procs; /* total number of procs */ 1567c478bd9Sstevel@tonic-gate static uint_t total_lwps; /* total number of lwps */ 1577c478bd9Sstevel@tonic-gate static float total_cpu; /* total cpu usage */ 1587c478bd9Sstevel@tonic-gate static float total_mem; /* total memory usage */ 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate static list_t lwps; /* list of lwps/processes */ 1617c478bd9Sstevel@tonic-gate static list_t users; /* list of users */ 1627c478bd9Sstevel@tonic-gate static list_t tasks; /* list of tasks */ 1637c478bd9Sstevel@tonic-gate static list_t projects; /* list of projects */ 1647c478bd9Sstevel@tonic-gate static list_t zones; /* list of zones */ 165c6402783Sakolb static list_t lgroups; /* list of lgroups */ 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate static volatile uint_t sigwinch = 0; 1687c478bd9Sstevel@tonic-gate static volatile uint_t sigtstp = 0; 1697c478bd9Sstevel@tonic-gate static volatile uint_t sigterm = 0; 1707c478bd9Sstevel@tonic-gate 1710209230bSgjelinek static long pagesize; 1720209230bSgjelinek 1737c478bd9Sstevel@tonic-gate /* default settings */ 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate static optdesc_t opts = { 1767c478bd9Sstevel@tonic-gate 5, /* interval between updates, seconds */ 1777c478bd9Sstevel@tonic-gate 15, /* number of lines in top part */ 1787c478bd9Sstevel@tonic-gate 5, /* number of lines in bottom part */ 1797c478bd9Sstevel@tonic-gate -1, /* number of iterations; infinitely */ 1807c478bd9Sstevel@tonic-gate OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP, 1817c478bd9Sstevel@tonic-gate -1 /* sort in decreasing order */ 1827c478bd9Sstevel@tonic-gate }; 1837c478bd9Sstevel@tonic-gate 1844944376cSJohn Levon /* 1854944376cSJohn Levon * Print timestamp as decimal reprentation of time_t value (-d u was specified) 1864944376cSJohn Levon * or the standard date format (-d d was specified). 1874944376cSJohn Levon */ 1884944376cSJohn Levon static void 1894944376cSJohn Levon print_timestamp(void) 1904944376cSJohn Levon { 1914944376cSJohn Levon time_t t = time(NULL); 1924944376cSJohn Levon static char *fmt = NULL; 1934944376cSJohn Levon 1944944376cSJohn Levon /* We only need to retrieve this once per invocation */ 1954944376cSJohn Levon if (fmt == NULL) 1964944376cSJohn Levon fmt = nl_langinfo(_DATE_FMT); 1974944376cSJohn Levon 1984944376cSJohn Levon if (opts.o_outpmode & OPT_UDATE) { 1994944376cSJohn Levon (void) printf("%ld", t); 2004944376cSJohn Levon } else if (opts.o_outpmode & OPT_DDATE) { 2014944376cSJohn Levon char dstr[64]; 2024944376cSJohn Levon int len; 2034944376cSJohn Levon 2044944376cSJohn Levon len = strftime(dstr, sizeof (dstr), fmt, localtime(&t)); 2054944376cSJohn Levon if (len > 0) 2064944376cSJohn Levon (void) printf("%s", dstr); 2074944376cSJohn Levon } 2084944376cSJohn Levon (void) putp(t_eol); 2094944376cSJohn Levon (void) putchar('\n'); 2104944376cSJohn Levon } 2114944376cSJohn Levon 2127c478bd9Sstevel@tonic-gate static void 2137c478bd9Sstevel@tonic-gate psetloadavg(long psetid, void *ptr) 2147c478bd9Sstevel@tonic-gate { 2157c478bd9Sstevel@tonic-gate double psetloadavg[3]; 2167c478bd9Sstevel@tonic-gate double *loadavg = ptr; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate if (pset_getloadavg((psetid_t)psetid, psetloadavg, 3) != -1) { 2197c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[0]; 2207c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[1]; 2217c478bd9Sstevel@tonic-gate *loadavg += psetloadavg[2]; 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate /* 2260209230bSgjelinek * Queries the memory virtual and rss size for each member of a list. 2270209230bSgjelinek * This will override the values computed by /proc aggregation. 2280209230bSgjelinek */ 2290209230bSgjelinek static void 2300209230bSgjelinek list_getsize(list_t *list) 2310209230bSgjelinek { 2320209230bSgjelinek id_info_t *id; 2330209230bSgjelinek vmusage_t *results, *next; 2340209230bSgjelinek vmusage_t *match; 2350209230bSgjelinek size_t nres = 0; 2360209230bSgjelinek size_t i; 2370209230bSgjelinek uint_t flags = 0; 2380209230bSgjelinek int ret; 2390209230bSgjelinek size_t physmem = sysconf(_SC_PHYS_PAGES) * pagesize; 2400209230bSgjelinek 2410209230bSgjelinek /* 2420209230bSgjelinek * Determine what swap/rss results to calculate. getvmusage() will 2430209230bSgjelinek * prune results returned to non-global zones automatically, so 2440209230bSgjelinek * there is no need to pass different flags when calling from a 2450209230bSgjelinek * non-global zone. 2460209230bSgjelinek * 2470209230bSgjelinek * Currently list_getsize() is only called with a single flag. This 2480209230bSgjelinek * is because -Z, -J, -T, and -a are mutually exclusive. Regardless 2490209230bSgjelinek * of this, we handle multiple flags. 2500209230bSgjelinek */ 2510209230bSgjelinek if (opts.o_outpmode & OPT_USERS) { 2520209230bSgjelinek /* 2530209230bSgjelinek * Gather rss for all users in all zones. Treat the same 2540209230bSgjelinek * uid in different zones as the same user. 2550209230bSgjelinek */ 2560209230bSgjelinek flags |= VMUSAGE_COL_RUSERS; 2570209230bSgjelinek 2580209230bSgjelinek } else if (opts.o_outpmode & OPT_TASKS) { 2590209230bSgjelinek /* Gather rss for all tasks in all zones */ 2600209230bSgjelinek flags |= VMUSAGE_ALL_TASKS; 2610209230bSgjelinek 2620209230bSgjelinek } else if (opts.o_outpmode & OPT_PROJECTS) { 2630209230bSgjelinek /* 2640209230bSgjelinek * Gather rss for all projects in all zones. Treat the same 2650209230bSgjelinek * projid in diffrent zones as the same project. 2660209230bSgjelinek */ 2670209230bSgjelinek flags |= VMUSAGE_COL_PROJECTS; 2680209230bSgjelinek 2690209230bSgjelinek } else if (opts.o_outpmode & OPT_ZONES) { 2700209230bSgjelinek /* Gather rss for all zones */ 2710209230bSgjelinek flags |= VMUSAGE_ALL_ZONES; 2720209230bSgjelinek 2730209230bSgjelinek } else { 2740209230bSgjelinek Die(gettext( 2750209230bSgjelinek "Cannot determine rss flags for output options %x\n"), 2760209230bSgjelinek opts.o_outpmode); 2770209230bSgjelinek } 2780209230bSgjelinek 2790209230bSgjelinek /* 2800209230bSgjelinek * getvmusage() returns an array of result structures. One for 2810209230bSgjelinek * each zone, project, task, or user on the system, depending on 2820209230bSgjelinek * flags. 2830209230bSgjelinek * 2840209230bSgjelinek * If getvmusage() fails, prstat will use the size already gathered 2850209230bSgjelinek * from psinfo 2860209230bSgjelinek */ 2870209230bSgjelinek if (getvmusage(flags, opts.o_interval, NULL, &nres) != 0) 2880209230bSgjelinek return; 2890209230bSgjelinek 2900209230bSgjelinek results = (vmusage_t *)Malloc(sizeof (vmusage_t) * nres); 2910209230bSgjelinek for (;;) { 2920209230bSgjelinek ret = getvmusage(flags, opts.o_interval, results, &nres); 2930209230bSgjelinek if (ret == 0) 2940209230bSgjelinek break; 2950209230bSgjelinek if (errno == EOVERFLOW) { 2960209230bSgjelinek results = (vmusage_t *)Realloc(results, 2970209230bSgjelinek sizeof (vmusage_t) * nres); 2980209230bSgjelinek continue; 2990209230bSgjelinek } 3000209230bSgjelinek /* 3010209230bSgjelinek * Failure for some other reason. Prstat will use the size 3020209230bSgjelinek * already gathered from psinfo. 3030209230bSgjelinek */ 304e1009cb0S free(results); 3050209230bSgjelinek return; 3060209230bSgjelinek } 3070209230bSgjelinek for (id = list->l_head; id != NULL; id = id->id_next) { 3080209230bSgjelinek 3090209230bSgjelinek match = NULL; 3100209230bSgjelinek next = results; 3110209230bSgjelinek for (i = 0; i < nres; i++, next++) { 3120209230bSgjelinek switch (flags) { 3130209230bSgjelinek case VMUSAGE_COL_RUSERS: 3140209230bSgjelinek if (next->vmu_id == id->id_uid) 3150209230bSgjelinek match = next; 3160209230bSgjelinek break; 3170209230bSgjelinek case VMUSAGE_ALL_TASKS: 3180209230bSgjelinek if (next->vmu_id == id->id_taskid) 3190209230bSgjelinek match = next; 3200209230bSgjelinek break; 3210209230bSgjelinek case VMUSAGE_COL_PROJECTS: 3220209230bSgjelinek if (next->vmu_id == id->id_projid) 3230209230bSgjelinek match = next; 3240209230bSgjelinek break; 3250209230bSgjelinek case VMUSAGE_ALL_ZONES: 3260209230bSgjelinek if (next->vmu_id == id->id_zoneid) 3270209230bSgjelinek match = next; 3280209230bSgjelinek break; 3290209230bSgjelinek default: 3300209230bSgjelinek Die(gettext( 3310209230bSgjelinek "Unknown vmusage flags %d\n"), flags); 3320209230bSgjelinek } 3330209230bSgjelinek } 3340209230bSgjelinek if (match != NULL) { 3350209230bSgjelinek id->id_size = match->vmu_swap_all / 1024; 3360209230bSgjelinek id->id_rssize = match->vmu_rss_all / 1024; 3370209230bSgjelinek id->id_pctmem = (100.0 * (float)match->vmu_rss_all) / 3380209230bSgjelinek (float)physmem; 3390209230bSgjelinek /* Output using data from getvmusage() */ 3400209230bSgjelinek id->id_sizematch = B_TRUE; 3410209230bSgjelinek } 3420209230bSgjelinek /* 3430209230bSgjelinek * If no match is found, prstat will use the size already 3440209230bSgjelinek * gathered from psinfo. 3450209230bSgjelinek */ 3460209230bSgjelinek } 347e1009cb0S free(results); 3480209230bSgjelinek } 3490209230bSgjelinek 3500209230bSgjelinek /* 3517c478bd9Sstevel@tonic-gate * A routine to display the contents of the list on the screen 3527c478bd9Sstevel@tonic-gate */ 3537c478bd9Sstevel@tonic-gate static void 3547c478bd9Sstevel@tonic-gate list_print(list_t *list) 3557c478bd9Sstevel@tonic-gate { 3567c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 3577c478bd9Sstevel@tonic-gate id_info_t *id; 3587c478bd9Sstevel@tonic-gate char usr[4], sys[4], trp[4], tfl[4]; 3597c478bd9Sstevel@tonic-gate char dfl[4], lck[4], slp[4], lat[4]; 3607c478bd9Sstevel@tonic-gate char vcx[4], icx[4], scl[4], sig[4]; 3617c478bd9Sstevel@tonic-gate char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12]; 3627c478bd9Sstevel@tonic-gate char pstate[7], pnice[4], ppri[4]; 3637c478bd9Sstevel@tonic-gate char pname[LOGNAME_MAX+1]; 3647c478bd9Sstevel@tonic-gate char projname[PROJNAME_MAX+1]; 3657c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX+1]; 3667c478bd9Sstevel@tonic-gate float cpu, mem; 3677c478bd9Sstevel@tonic-gate double loadavg[3] = {0, 0, 0}; 3687c478bd9Sstevel@tonic-gate int i, lwpid; 3697c478bd9Sstevel@tonic-gate 370*156d6b3aSJerry Jelinek if (list->l_size == 0) 371*156d6b3aSJerry Jelinek return; 372*156d6b3aSJerry Jelinek 3737c478bd9Sstevel@tonic-gate if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) { 3747c478bd9Sstevel@tonic-gate /* 3757c478bd9Sstevel@tonic-gate * If processor sets aren't specified, we display system-wide 3767c478bd9Sstevel@tonic-gate * load averages. 3777c478bd9Sstevel@tonic-gate */ 3787c478bd9Sstevel@tonic-gate (void) getloadavg(loadavg, 3); 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3814944376cSJohn Levon if (((opts.o_outpmode & OPT_UDATE) || (opts.o_outpmode & OPT_DDATE)) && 3824944376cSJohn Levon ((list->l_type == LT_LWPS) || !(opts.o_outpmode & OPT_SPLIT))) 3834944376cSJohn Levon print_timestamp(); 3847c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 3857c478bd9Sstevel@tonic-gate (void) putchar('\r'); 3867c478bd9Sstevel@tonic-gate (void) putp(t_ulon); 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate switch (list->l_type) { 3897c478bd9Sstevel@tonic-gate case LT_PROJECTS: 3907c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 3917c478bd9Sstevel@tonic-gate (void) printf(PROJECT_HEADER_LWP); 3927c478bd9Sstevel@tonic-gate else 3937c478bd9Sstevel@tonic-gate (void) printf(PROJECT_HEADER_PROC); 3947c478bd9Sstevel@tonic-gate break; 3957c478bd9Sstevel@tonic-gate case LT_TASKS: 3967c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 3977c478bd9Sstevel@tonic-gate (void) printf(TASK_HEADER_LWP); 3987c478bd9Sstevel@tonic-gate else 3997c478bd9Sstevel@tonic-gate (void) printf(TASK_HEADER_PROC); 4007c478bd9Sstevel@tonic-gate break; 4017c478bd9Sstevel@tonic-gate case LT_ZONES: 4027c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 4037c478bd9Sstevel@tonic-gate (void) printf(ZONE_HEADER_LWP); 4047c478bd9Sstevel@tonic-gate else 4057c478bd9Sstevel@tonic-gate (void) printf(ZONE_HEADER_PROC); 4067c478bd9Sstevel@tonic-gate break; 4077c478bd9Sstevel@tonic-gate case LT_USERS: 4087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 4097c478bd9Sstevel@tonic-gate (void) printf(USER_HEADER_LWP); 4107c478bd9Sstevel@tonic-gate else 4117c478bd9Sstevel@tonic-gate (void) printf(USER_HEADER_PROC); 4127c478bd9Sstevel@tonic-gate break; 4137c478bd9Sstevel@tonic-gate case LT_LWPS: 4147c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) { 415c6402783Sakolb if (opts.o_outpmode & OPT_PSINFO) { 416c6402783Sakolb if (opts.o_outpmode & OPT_LGRP) 417c6402783Sakolb (void) printf(PSINFO_HEADER_LWP_LGRP); 418c6402783Sakolb else 4197c478bd9Sstevel@tonic-gate (void) printf(PSINFO_HEADER_LWP); 420c6402783Sakolb } 4217c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) 4227c478bd9Sstevel@tonic-gate (void) printf(USAGE_HEADER_LWP); 4237c478bd9Sstevel@tonic-gate } else { 424c6402783Sakolb if (opts.o_outpmode & OPT_PSINFO) { 425c6402783Sakolb if (opts.o_outpmode & OPT_LGRP) 426c6402783Sakolb (void) printf(PSINFO_HEADER_PROC_LGRP); 427c6402783Sakolb else 4287c478bd9Sstevel@tonic-gate (void) printf(PSINFO_HEADER_PROC); 429c6402783Sakolb } 4307c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) 4317c478bd9Sstevel@tonic-gate (void) printf(USAGE_HEADER_PROC); 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate break; 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate (void) putp(t_uloff); 4377c478bd9Sstevel@tonic-gate (void) putp(t_eol); 4387c478bd9Sstevel@tonic-gate (void) putchar('\n'); 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate for (i = 0; i < list->l_used; i++) { 4417c478bd9Sstevel@tonic-gate switch (list->l_type) { 4427c478bd9Sstevel@tonic-gate case LT_PROJECTS: 4437c478bd9Sstevel@tonic-gate case LT_TASKS: 4447c478bd9Sstevel@tonic-gate case LT_USERS: 4457c478bd9Sstevel@tonic-gate case LT_ZONES: 4467c478bd9Sstevel@tonic-gate id = list->l_ptrs[i]; 4477c478bd9Sstevel@tonic-gate /* 4487c478bd9Sstevel@tonic-gate * CPU usage and memory usage normalization 4497c478bd9Sstevel@tonic-gate */ 4507c478bd9Sstevel@tonic-gate if (total_cpu >= 100) 4517c478bd9Sstevel@tonic-gate cpu = (100 * id->id_pctcpu) / total_cpu; 4527c478bd9Sstevel@tonic-gate else 4537c478bd9Sstevel@tonic-gate cpu = id->id_pctcpu; 4540209230bSgjelinek if (id->id_sizematch == B_FALSE && total_mem >= 100) 4557c478bd9Sstevel@tonic-gate mem = (100 * id->id_pctmem) / total_mem; 4567c478bd9Sstevel@tonic-gate else 4577c478bd9Sstevel@tonic-gate mem = id->id_pctmem; 4580a1278f2SGary Mills if (list->l_type == LT_USERS) { 4590a1278f2SGary Mills pwd_getname(id->id_uid, pname, sizeof (pname), 4600a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE, 4610a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC), 4620a1278f2SGary Mills LOGIN_WIDTH); 4630a1278f2SGary Mills } else if (list->l_type == LT_ZONES) { 4647c478bd9Sstevel@tonic-gate getzonename(id->id_zoneid, zonename, 4650a1278f2SGary Mills sizeof (zonename), 4660a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC), 4670a1278f2SGary Mills ZONE_WIDTH); 4680a1278f2SGary Mills } else { 4697c478bd9Sstevel@tonic-gate getprojname(id->id_projid, projname, 4700a1278f2SGary Mills sizeof (projname), 4710a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE, 4720a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC), 4730a1278f2SGary Mills PROJECT_WIDTH); 4740a1278f2SGary Mills } 4757c478bd9Sstevel@tonic-gate Format_size(psize, id->id_size, 6); 4767c478bd9Sstevel@tonic-gate Format_size(prssize, id->id_rssize, 6); 4777c478bd9Sstevel@tonic-gate Format_pct(pmem, mem, 4); 4787c478bd9Sstevel@tonic-gate Format_pct(pcpu, cpu, 4); 4797c478bd9Sstevel@tonic-gate Format_time(ptime, id->id_time, 10); 4807c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 4817c478bd9Sstevel@tonic-gate (void) putchar('\r'); 4827c478bd9Sstevel@tonic-gate if (list->l_type == LT_PROJECTS) 4837c478bd9Sstevel@tonic-gate (void) printf(PROJECT_LINE, (int)id->id_projid, 4847c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 4857c478bd9Sstevel@tonic-gate pcpu, projname); 4867c478bd9Sstevel@tonic-gate else if (list->l_type == LT_TASKS) 4877c478bd9Sstevel@tonic-gate (void) printf(TASK_LINE, (int)id->id_taskid, 4887c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 4897c478bd9Sstevel@tonic-gate pcpu, projname); 4907c478bd9Sstevel@tonic-gate else if (list->l_type == LT_ZONES) 4917c478bd9Sstevel@tonic-gate (void) printf(ZONE_LINE, (int)id->id_zoneid, 4927c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 4937c478bd9Sstevel@tonic-gate pcpu, zonename); 4947c478bd9Sstevel@tonic-gate else 4957c478bd9Sstevel@tonic-gate (void) printf(USER_LINE, id->id_nproc, pname, 4967c478bd9Sstevel@tonic-gate psize, prssize, pmem, ptime, pcpu); 4977c478bd9Sstevel@tonic-gate (void) putp(t_eol); 4987c478bd9Sstevel@tonic-gate (void) putchar('\n'); 4997c478bd9Sstevel@tonic-gate break; 5007c478bd9Sstevel@tonic-gate case LT_LWPS: 5017c478bd9Sstevel@tonic-gate lwp = list->l_ptrs[i]; 5027c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 5037c478bd9Sstevel@tonic-gate lwpid = lwp->li_info.pr_lwp.pr_lwpid; 5047c478bd9Sstevel@tonic-gate else 5057c478bd9Sstevel@tonic-gate lwpid = lwp->li_info.pr_nlwp + 5067c478bd9Sstevel@tonic-gate lwp->li_info.pr_nzomb; 5070a1278f2SGary Mills pwd_getname(lwp->li_info.pr_uid, pname, sizeof (pname), 5080a1278f2SGary Mills opts.o_outpmode & OPT_NORESOLVE, 5090a1278f2SGary Mills opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC), 5100a1278f2SGary Mills LOGIN_WIDTH); 5117c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PSINFO) { 5127c478bd9Sstevel@tonic-gate Format_size(psize, lwp->li_info.pr_size, 6); 5137c478bd9Sstevel@tonic-gate Format_size(prssize, lwp->li_info.pr_rssize, 6); 5147c478bd9Sstevel@tonic-gate Format_state(pstate, 5157c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname, 5167c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_onpro, 7); 5177c478bd9Sstevel@tonic-gate if (strcmp(lwp->li_info.pr_lwp.pr_clname, 5187c478bd9Sstevel@tonic-gate "RT") == 0 || 5197c478bd9Sstevel@tonic-gate strcmp(lwp->li_info.pr_lwp.pr_clname, 5207c478bd9Sstevel@tonic-gate "SYS") == 0 || 5217c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname == 'Z') 5227c478bd9Sstevel@tonic-gate (void) strcpy(pnice, " -"); 5237c478bd9Sstevel@tonic-gate else 5247c478bd9Sstevel@tonic-gate Format_num(pnice, 5257c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_nice - NZERO, 5267c478bd9Sstevel@tonic-gate 4); 5277c478bd9Sstevel@tonic-gate Format_num(ppri, lwp->li_info.pr_lwp.pr_pri, 4); 5287c478bd9Sstevel@tonic-gate Format_pct(pcpu, 5297c478bd9Sstevel@tonic-gate FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu), 4); 5307c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 5317c478bd9Sstevel@tonic-gate Format_time(ptime, 5327c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_time.tv_sec, 5337c478bd9Sstevel@tonic-gate 10); 5347c478bd9Sstevel@tonic-gate else 5357c478bd9Sstevel@tonic-gate Format_time(ptime, 5367c478bd9Sstevel@tonic-gate lwp->li_info.pr_time.tv_sec, 10); 5377c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 5387c478bd9Sstevel@tonic-gate (void) putchar('\r'); 5397c478bd9Sstevel@tonic-gate stripfname(lwp->li_info.pr_fname); 540c6402783Sakolb if (opts.o_outpmode & OPT_LGRP) { 541c6402783Sakolb (void) printf(PSINFO_LINE_LGRP, 542c6402783Sakolb (int)lwp->li_info.pr_pid, pname, 5430a1278f2SGary Mills psize, prssize, pstate, 5440a1278f2SGary Mills ppri, pnice, ptime, pcpu, 545c6402783Sakolb (int)lwp->li_info.pr_lwp.pr_lgrp, 546c6402783Sakolb lwp->li_info.pr_fname, lwpid); 547c6402783Sakolb } else { 5487c478bd9Sstevel@tonic-gate (void) printf(PSINFO_LINE, 5497c478bd9Sstevel@tonic-gate (int)lwp->li_info.pr_pid, pname, 5500a1278f2SGary Mills psize, prssize, 5510a1278f2SGary Mills pstate, ppri, pnice, 552c6402783Sakolb ptime, pcpu, 553c6402783Sakolb lwp->li_info.pr_fname, lwpid); 554c6402783Sakolb } 5557c478bd9Sstevel@tonic-gate (void) putp(t_eol); 5567c478bd9Sstevel@tonic-gate (void) putchar('\n'); 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) { 5597c478bd9Sstevel@tonic-gate Format_pct(usr, lwp->li_usr, 4); 5607c478bd9Sstevel@tonic-gate Format_pct(sys, lwp->li_sys, 4); 5617c478bd9Sstevel@tonic-gate Format_pct(slp, lwp->li_slp, 4); 5627c478bd9Sstevel@tonic-gate Format_num(vcx, lwp->li_vcx, 4); 5637c478bd9Sstevel@tonic-gate Format_num(icx, lwp->li_icx, 4); 5647c478bd9Sstevel@tonic-gate Format_num(scl, lwp->li_scl, 4); 5657c478bd9Sstevel@tonic-gate Format_num(sig, lwp->li_sig, 4); 5667c478bd9Sstevel@tonic-gate Format_pct(trp, lwp->li_trp, 4); 5677c478bd9Sstevel@tonic-gate Format_pct(tfl, lwp->li_tfl, 4); 5687c478bd9Sstevel@tonic-gate Format_pct(dfl, lwp->li_dfl, 4); 5697c478bd9Sstevel@tonic-gate Format_pct(lck, lwp->li_lck, 4); 5707c478bd9Sstevel@tonic-gate Format_pct(lat, lwp->li_lat, 4); 5717c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 5727c478bd9Sstevel@tonic-gate (void) putchar('\r'); 5737c478bd9Sstevel@tonic-gate stripfname(lwp->li_info.pr_fname); 5747c478bd9Sstevel@tonic-gate (void) printf(USAGE_LINE, 5757c478bd9Sstevel@tonic-gate (int)lwp->li_info.pr_pid, pname, 5767c478bd9Sstevel@tonic-gate usr, sys, trp, tfl, dfl, lck, 5777c478bd9Sstevel@tonic-gate slp, lat, vcx, icx, scl, sig, 5787c478bd9Sstevel@tonic-gate lwp->li_info.pr_fname, lwpid); 5797c478bd9Sstevel@tonic-gate (void) putp(t_eol); 5807c478bd9Sstevel@tonic-gate (void) putchar('\n'); 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate break; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 5877c478bd9Sstevel@tonic-gate (void) putchar('\r'); 5887c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) { 5897c478bd9Sstevel@tonic-gate switch (list->l_type) { 5907c478bd9Sstevel@tonic-gate case LT_PROJECTS: 5917c478bd9Sstevel@tonic-gate case LT_USERS: 5927c478bd9Sstevel@tonic-gate case LT_TASKS: 5937c478bd9Sstevel@tonic-gate case LT_ZONES: 5947c478bd9Sstevel@tonic-gate while (i++ < opts.o_nbottom) { 5957c478bd9Sstevel@tonic-gate (void) putp(t_eol); 5967c478bd9Sstevel@tonic-gate (void) putchar('\n'); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate break; 5997c478bd9Sstevel@tonic-gate case LT_LWPS: 6007c478bd9Sstevel@tonic-gate while (i++ < opts.o_ntop) { 6017c478bd9Sstevel@tonic-gate (void) putp(t_eol); 6027c478bd9Sstevel@tonic-gate (void) putchar('\n'); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate } 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 6087c478bd9Sstevel@tonic-gate (void) putchar('\r'); 6097c478bd9Sstevel@tonic-gate 6107c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_SPLIT) && list->l_type == LT_LWPS) 6117c478bd9Sstevel@tonic-gate return; 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate (void) printf(TOTAL_LINE, total_procs, total_lwps, 6147c478bd9Sstevel@tonic-gate loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN], 6157c478bd9Sstevel@tonic-gate loadavg[LOADAVG_15MIN]); 6167c478bd9Sstevel@tonic-gate (void) putp(t_eol); 6177c478bd9Sstevel@tonic-gate (void) putchar('\n'); 6187c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 6197c478bd9Sstevel@tonic-gate (void) putchar('\r'); 6207c478bd9Sstevel@tonic-gate (void) putp(t_eol); 6217c478bd9Sstevel@tonic-gate (void) fflush(stdout); 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate static lwp_info_t * 6257c478bd9Sstevel@tonic-gate list_add_lwp(list_t *list, pid_t pid, id_t lwpid) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate if (list->l_head == NULL) { 6307c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = lwp = Zalloc(sizeof (lwp_info_t)); 6317c478bd9Sstevel@tonic-gate } else { 6327c478bd9Sstevel@tonic-gate lwp = Zalloc(sizeof (lwp_info_t)); 6337c478bd9Sstevel@tonic-gate lwp->li_prev = list->l_tail; 6347c478bd9Sstevel@tonic-gate ((lwp_info_t *)list->l_tail)->li_next = lwp; 6357c478bd9Sstevel@tonic-gate list->l_tail = lwp; 6367c478bd9Sstevel@tonic-gate } 6377c478bd9Sstevel@tonic-gate lwp->li_info.pr_pid = pid; 6387c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_lwpid = lwpid; 6397c478bd9Sstevel@tonic-gate lwpid_add(lwp, pid, lwpid); 6407c478bd9Sstevel@tonic-gate list->l_count++; 6417c478bd9Sstevel@tonic-gate return (lwp); 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate static void 6457c478bd9Sstevel@tonic-gate list_remove_lwp(list_t *list, lwp_info_t *lwp) 6467c478bd9Sstevel@tonic-gate { 6477c478bd9Sstevel@tonic-gate if (lwp->li_prev) 6487c478bd9Sstevel@tonic-gate lwp->li_prev->li_next = lwp->li_next; 6497c478bd9Sstevel@tonic-gate else 6507c478bd9Sstevel@tonic-gate list->l_head = lwp->li_next; /* removing the head */ 6517c478bd9Sstevel@tonic-gate if (lwp->li_next) 6527c478bd9Sstevel@tonic-gate lwp->li_next->li_prev = lwp->li_prev; 6537c478bd9Sstevel@tonic-gate else 6547c478bd9Sstevel@tonic-gate list->l_tail = lwp->li_prev; /* removing the tail */ 6557c478bd9Sstevel@tonic-gate lwpid_del(lwp->li_info.pr_pid, lwp->li_info.pr_lwp.pr_lwpid); 6567c478bd9Sstevel@tonic-gate if (lwpid_pidcheck(lwp->li_info.pr_pid) == 0) 6577c478bd9Sstevel@tonic-gate fds_rm(lwp->li_info.pr_pid); 6587c478bd9Sstevel@tonic-gate list->l_count--; 6597c478bd9Sstevel@tonic-gate free(lwp); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate static void 6637c478bd9Sstevel@tonic-gate list_clear(list_t *list) 6647c478bd9Sstevel@tonic-gate { 6657c478bd9Sstevel@tonic-gate if (list->l_type == LT_LWPS) { 6667c478bd9Sstevel@tonic-gate lwp_info_t *lwp = list->l_tail; 6677c478bd9Sstevel@tonic-gate lwp_info_t *lwp_tmp; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate fd_closeall(); 6707c478bd9Sstevel@tonic-gate while (lwp) { 6717c478bd9Sstevel@tonic-gate lwp_tmp = lwp; 6727c478bd9Sstevel@tonic-gate lwp = lwp->li_prev; 6737c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp_tmp); 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate } else { 6767c478bd9Sstevel@tonic-gate id_info_t *id = list->l_head; 6777c478bd9Sstevel@tonic-gate id_info_t *nextid; 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate while (id) { 6807c478bd9Sstevel@tonic-gate nextid = id->id_next; 6817c478bd9Sstevel@tonic-gate free(id); 6827c478bd9Sstevel@tonic-gate id = nextid; 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate list->l_count = 0; 6857c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = NULL; 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate } 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate static void 6907c478bd9Sstevel@tonic-gate list_update(list_t *list, lwp_info_t *lwp) 6917c478bd9Sstevel@tonic-gate { 6927c478bd9Sstevel@tonic-gate id_info_t *id; 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate if (list->l_head == NULL) { /* first element */ 6957c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = id = Zalloc(sizeof (id_info_t)); 6967c478bd9Sstevel@tonic-gate goto update; 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate for (id = list->l_head; id; id = id->id_next) { 7007c478bd9Sstevel@tonic-gate if ((list->l_type == LT_USERS) && 7017c478bd9Sstevel@tonic-gate (id->id_uid != lwp->li_info.pr_uid)) 7027c478bd9Sstevel@tonic-gate continue; 7037c478bd9Sstevel@tonic-gate if ((list->l_type == LT_TASKS) && 7047c478bd9Sstevel@tonic-gate (id->id_taskid != lwp->li_info.pr_taskid)) 7057c478bd9Sstevel@tonic-gate continue; 7067c478bd9Sstevel@tonic-gate if ((list->l_type == LT_PROJECTS) && 7077c478bd9Sstevel@tonic-gate (id->id_projid != lwp->li_info.pr_projid)) 7087c478bd9Sstevel@tonic-gate continue; 7097c478bd9Sstevel@tonic-gate if ((list->l_type == LT_ZONES) && 7107c478bd9Sstevel@tonic-gate (id->id_zoneid != lwp->li_info.pr_zoneid)) 7117c478bd9Sstevel@tonic-gate continue; 712c6402783Sakolb if ((list->l_type == LT_LGRPS) && 713c6402783Sakolb (id->id_lgroup != lwp->li_info.pr_lwp.pr_lgrp)) 714c6402783Sakolb continue; 7157c478bd9Sstevel@tonic-gate id->id_nproc++; 7167c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid; 7177c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid; 7187c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid; 719c6402783Sakolb id->id_lgroup = lwp->li_info.pr_lwp.pr_lgrp; 720c6402783Sakolb 7217c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) { 7227c478bd9Sstevel@tonic-gate id->id_size += lwp->li_info.pr_size; 7237c478bd9Sstevel@tonic-gate id->id_rssize += lwp->li_info.pr_rssize; 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate id->id_pctcpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 7267c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 7277c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_lwp.pr_time); 7287c478bd9Sstevel@tonic-gate else 7297c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_time); 7307c478bd9Sstevel@tonic-gate id->id_pctmem += FRC2PCT(lwp->li_info.pr_pctmem); 7317c478bd9Sstevel@tonic-gate id->id_key += lwp->li_key; 7327c478bd9Sstevel@tonic-gate total_cpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 7337c478bd9Sstevel@tonic-gate total_mem += FRC2PCT(lwp->li_info.pr_pctmem); 7347c478bd9Sstevel@tonic-gate return; 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate id = list->l_tail; 7387c478bd9Sstevel@tonic-gate id->id_next = Zalloc(sizeof (id_info_t)); 7397c478bd9Sstevel@tonic-gate id->id_next->id_prev = list->l_tail; 7407c478bd9Sstevel@tonic-gate id->id_next->id_next = NULL; 7417c478bd9Sstevel@tonic-gate list->l_tail = id->id_next; 7427c478bd9Sstevel@tonic-gate id = list->l_tail; 7437c478bd9Sstevel@tonic-gate update: 7447c478bd9Sstevel@tonic-gate id->id_uid = lwp->li_info.pr_uid; 7457c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid; 7467c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid; 7477c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid; 748c6402783Sakolb id->id_lgroup = lwp->li_info.pr_lwp.pr_lgrp; 7497c478bd9Sstevel@tonic-gate id->id_nproc++; 7500209230bSgjelinek id->id_sizematch = B_FALSE; 7517c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) { 7527c478bd9Sstevel@tonic-gate id->id_size = lwp->li_info.pr_size; 7537c478bd9Sstevel@tonic-gate id->id_rssize = lwp->li_info.pr_rssize; 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate id->id_pctcpu = FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 7567c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 7577c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_lwp.pr_time); 7587c478bd9Sstevel@tonic-gate else 7597c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_time); 7607c478bd9Sstevel@tonic-gate id->id_pctmem = FRC2PCT(lwp->li_info.pr_pctmem); 7617c478bd9Sstevel@tonic-gate id->id_key = lwp->li_key; 7627c478bd9Sstevel@tonic-gate total_cpu += id->id_pctcpu; 7637c478bd9Sstevel@tonic-gate total_mem += id->id_pctmem; 7647c478bd9Sstevel@tonic-gate list->l_count++; 7657c478bd9Sstevel@tonic-gate } 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate static void 7687c478bd9Sstevel@tonic-gate lwp_update(lwp_info_t *lwp, pid_t pid, id_t lwpid, struct prusage *usage) 7697c478bd9Sstevel@tonic-gate { 7707c478bd9Sstevel@tonic-gate float period; 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate if (!lwpid_is_active(pid, lwpid)) { 7737c478bd9Sstevel@tonic-gate /* 7747c478bd9Sstevel@tonic-gate * If we are reading cpu times for the first time then 7757c478bd9Sstevel@tonic-gate * calculate average cpu times based on whole process 7767c478bd9Sstevel@tonic-gate * execution time. 7777c478bd9Sstevel@tonic-gate */ 7787c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t)); 7797c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime); 7807c478bd9Sstevel@tonic-gate period = period/(float)100; 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */ 7837c478bd9Sstevel@tonic-gate period = 1; 7847c478bd9Sstevel@tonic-gate lwp->li_usr = 0; 7857c478bd9Sstevel@tonic-gate lwp->li_sys = 0; 7867c478bd9Sstevel@tonic-gate lwp->li_slp = 0; 7877c478bd9Sstevel@tonic-gate } else { 7887c478bd9Sstevel@tonic-gate lwp->li_usr = TIME2NSEC(usage->pr_utime)/period; 7897c478bd9Sstevel@tonic-gate lwp->li_sys = TIME2NSEC(usage->pr_stime)/period; 7907c478bd9Sstevel@tonic-gate lwp->li_slp = TIME2NSEC(usage->pr_slptime)/period; 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate lwp->li_trp = TIME2NSEC(usage->pr_ttime)/period; 7937c478bd9Sstevel@tonic-gate lwp->li_tfl = TIME2NSEC(usage->pr_tftime)/period; 7947c478bd9Sstevel@tonic-gate lwp->li_dfl = TIME2NSEC(usage->pr_dftime)/period; 7957c478bd9Sstevel@tonic-gate lwp->li_lck = TIME2NSEC(usage->pr_ltime)/period; 7967c478bd9Sstevel@tonic-gate lwp->li_lat = TIME2NSEC(usage->pr_wtime)/period; 7977c478bd9Sstevel@tonic-gate period = (period / NANOSEC)*(float)100; /* now in seconds */ 7987c478bd9Sstevel@tonic-gate lwp->li_vcx = (ulong_t) 7997c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_vctx/period)); 8007c478bd9Sstevel@tonic-gate lwp->li_icx = (ulong_t) 8017c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_ictx/period)); 8027c478bd9Sstevel@tonic-gate lwp->li_scl = (ulong_t) 8037c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sysc/period)); 8047c478bd9Sstevel@tonic-gate lwp->li_sig = (ulong_t) 8057c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sigs/period)); 8067c478bd9Sstevel@tonic-gate (void) lwpid_set_active(pid, lwpid); 8077c478bd9Sstevel@tonic-gate } else { 8087c478bd9Sstevel@tonic-gate /* 8097c478bd9Sstevel@tonic-gate * If this is not a first time we are reading a process's 8107c478bd9Sstevel@tonic-gate * CPU times then recalculate CPU times based on fresh data 8117c478bd9Sstevel@tonic-gate * obtained from procfs and previous CPU time usage values. 8127c478bd9Sstevel@tonic-gate */ 8137c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime)- 8147c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_rtime); 8157c478bd9Sstevel@tonic-gate period = period/(float)100; 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */ 8187c478bd9Sstevel@tonic-gate period = 1; 8197c478bd9Sstevel@tonic-gate lwp->li_usr = 0; 8207c478bd9Sstevel@tonic-gate lwp->li_sys = 0; 8217c478bd9Sstevel@tonic-gate lwp->li_slp = 0; 8227c478bd9Sstevel@tonic-gate } else { 8237c478bd9Sstevel@tonic-gate lwp->li_usr = (TIME2NSEC(usage->pr_utime)- 8247c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_utime))/period; 8257c478bd9Sstevel@tonic-gate lwp->li_sys = (TIME2NSEC(usage->pr_stime) - 8267c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_stime))/period; 8277c478bd9Sstevel@tonic-gate lwp->li_slp = (TIME2NSEC(usage->pr_slptime) - 8287c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_slptime))/period; 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate lwp->li_trp = (TIME2NSEC(usage->pr_ttime) - 8317c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ttime))/period; 8327c478bd9Sstevel@tonic-gate lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) - 8337c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_tftime))/period; 8347c478bd9Sstevel@tonic-gate lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) - 8357c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_dftime))/period; 8367c478bd9Sstevel@tonic-gate lwp->li_lck = (TIME2NSEC(usage->pr_ltime) - 8377c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ltime))/period; 8387c478bd9Sstevel@tonic-gate lwp->li_lat = (TIME2NSEC(usage->pr_wtime) - 8397c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_wtime))/period; 8407c478bd9Sstevel@tonic-gate lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx; 8417c478bd9Sstevel@tonic-gate lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx; 8427c478bd9Sstevel@tonic-gate lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc; 8437c478bd9Sstevel@tonic-gate lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs; 8447c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t)); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate static int 8497c478bd9Sstevel@tonic-gate read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize) 8507c478bd9Sstevel@tonic-gate { 8517c478bd9Sstevel@tonic-gate char procfile[MAX_PROCFS_PATH]; 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate (void) snprintf(procfile, MAX_PROCFS_PATH, 8547c478bd9Sstevel@tonic-gate "/proc/%s/%s", pidstr, file); 8557c478bd9Sstevel@tonic-gate if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL) 8567c478bd9Sstevel@tonic-gate return (1); 8577c478bd9Sstevel@tonic-gate if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) { 8587c478bd9Sstevel@tonic-gate fd_close(*fd); 8597c478bd9Sstevel@tonic-gate return (1); 8607c478bd9Sstevel@tonic-gate } 8617c478bd9Sstevel@tonic-gate return (0); 8627c478bd9Sstevel@tonic-gate } 8637c478bd9Sstevel@tonic-gate 8647c478bd9Sstevel@tonic-gate static void 8657c478bd9Sstevel@tonic-gate add_proc(psinfo_t *psinfo) 8667c478bd9Sstevel@tonic-gate { 8677c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 8687c478bd9Sstevel@tonic-gate id_t lwpid; 8697c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid; 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate lwpid = psinfo->pr_lwp.pr_lwpid; 8727c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 8737c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid); 8747c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE | LWP_REPRESENT; 8757c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo, sizeof (psinfo_t)); 8767c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_pctcpu = lwp->li_info.pr_pctcpu; 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate static void 8807c478bd9Sstevel@tonic-gate add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags) 8817c478bd9Sstevel@tonic-gate { 8827c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 8837c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid; 8847c478bd9Sstevel@tonic-gate id_t lwpid = lwpsinfo->pr_lwpid; 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 8877c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid); 8887c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_REPRESENT; 8897c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE; 8907c478bd9Sstevel@tonic-gate lwp->li_flags |= flags; 8917c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo, 8927c478bd9Sstevel@tonic-gate sizeof (psinfo_t) - sizeof (lwpsinfo_t)); 8937c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t)); 8947c478bd9Sstevel@tonic-gate } 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate static void 8977c478bd9Sstevel@tonic-gate prstat_scandir(DIR *procdir) 8987c478bd9Sstevel@tonic-gate { 8997c478bd9Sstevel@tonic-gate char *pidstr; 9007c478bd9Sstevel@tonic-gate pid_t pid; 9017c478bd9Sstevel@tonic-gate id_t lwpid; 9027c478bd9Sstevel@tonic-gate size_t entsz; 9037c478bd9Sstevel@tonic-gate long nlwps, nent, i; 9047c478bd9Sstevel@tonic-gate char *buf, *ptr; 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate fds_t *fds; 9077c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 9087c478bd9Sstevel@tonic-gate dirent_t *direntp; 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate prheader_t header; 9117c478bd9Sstevel@tonic-gate psinfo_t psinfo; 9127c478bd9Sstevel@tonic-gate prusage_t usage; 9137c478bd9Sstevel@tonic-gate lwpsinfo_t *lwpsinfo; 9147c478bd9Sstevel@tonic-gate prusage_t *lwpusage; 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate total_procs = 0; 9177c478bd9Sstevel@tonic-gate total_lwps = 0; 9187c478bd9Sstevel@tonic-gate total_cpu = 0; 9197c478bd9Sstevel@tonic-gate total_mem = 0; 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate convert_zone(&zone_tbl); 9227c478bd9Sstevel@tonic-gate for (rewinddir(procdir); (direntp = readdir(procdir)); ) { 9237c478bd9Sstevel@tonic-gate pidstr = direntp->d_name; 9247c478bd9Sstevel@tonic-gate if (pidstr[0] == '.') /* skip "." and ".." */ 9257c478bd9Sstevel@tonic-gate continue; 9267c478bd9Sstevel@tonic-gate pid = atoi(pidstr); 9277c478bd9Sstevel@tonic-gate if (pid == 0 || pid == 2 || pid == 3) 9287c478bd9Sstevel@tonic-gate continue; /* skip sched, pageout and fsflush */ 9297c478bd9Sstevel@tonic-gate if (has_element(&pid_tbl, pid) == 0) 9307c478bd9Sstevel@tonic-gate continue; /* check if we really want this pid */ 9317c478bd9Sstevel@tonic-gate fds = fds_get(pid); /* get ptr to file descriptors */ 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_psinfo, pidstr, 9347c478bd9Sstevel@tonic-gate "psinfo", &psinfo, sizeof (psinfo_t)) != 0) 9357c478bd9Sstevel@tonic-gate continue; 9367c478bd9Sstevel@tonic-gate if (!has_uid(&ruid_tbl, psinfo.pr_uid) || 9377c478bd9Sstevel@tonic-gate !has_uid(&euid_tbl, psinfo.pr_euid) || 9387c478bd9Sstevel@tonic-gate !has_element(&prj_tbl, psinfo.pr_projid) || 9397c478bd9Sstevel@tonic-gate !has_element(&tsk_tbl, psinfo.pr_taskid) || 9407c478bd9Sstevel@tonic-gate !has_zone(&zone_tbl, psinfo.pr_zoneid)) { 9417c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 9427c478bd9Sstevel@tonic-gate continue; 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate nlwps = psinfo.pr_nlwp + psinfo.pr_nzomb; 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate if (nlwps > 1 && (opts.o_outpmode & (OPT_LWPS | OPT_PSETS))) { 9477c478bd9Sstevel@tonic-gate int rep_lwp = 0; 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lpsinfo, pidstr, "lpsinfo", 9507c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) { 9517c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 9527c478bd9Sstevel@tonic-gate continue; 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate nent = header.pr_nent; 9567c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent; 9577c478bd9Sstevel@tonic-gate ptr = buf = Malloc(entsz); 9587c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lpsinfo), buf, 9597c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) { 9607c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 9617c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 9627c478bd9Sstevel@tonic-gate free(buf); 9637c478bd9Sstevel@tonic-gate continue; 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate nlwps = 0; 9677c478bd9Sstevel@tonic-gate for (i = 0; i < nent; i++, ptr += header.pr_entsize) { 9687c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/ 9697c478bd9Sstevel@tonic-gate lwpsinfo = (lwpsinfo_t *)ptr; 9707c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl, 9717c478bd9Sstevel@tonic-gate lwpsinfo->pr_onpro) || 9727c478bd9Sstevel@tonic-gate !has_element(&set_tbl, 973c6402783Sakolb lwpsinfo->pr_bindpset) || 9744944376cSJohn Levon !has_element(&lgr_tbl, lwpsinfo->pr_lgrp)) 9757c478bd9Sstevel@tonic-gate continue; 9767c478bd9Sstevel@tonic-gate nlwps++; 9777c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & (OPT_PSETS | OPT_LWPS)) 9787c478bd9Sstevel@tonic-gate == OPT_PSETS) { 9797c478bd9Sstevel@tonic-gate /* 9807c478bd9Sstevel@tonic-gate * If one of process's LWPs is bound 9817c478bd9Sstevel@tonic-gate * to a given processor set, report the 9827c478bd9Sstevel@tonic-gate * whole process. We may be doing this 9837c478bd9Sstevel@tonic-gate * a few times but we'll get an accurate 9847c478bd9Sstevel@tonic-gate * lwp count in return. 9857c478bd9Sstevel@tonic-gate */ 9867c478bd9Sstevel@tonic-gate add_proc(&psinfo); 9877c478bd9Sstevel@tonic-gate } else { 9887c478bd9Sstevel@tonic-gate if (rep_lwp == 0) { 9897c478bd9Sstevel@tonic-gate rep_lwp = 1; 9907c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo, 9917c478bd9Sstevel@tonic-gate LWP_REPRESENT); 9927c478bd9Sstevel@tonic-gate } else { 9937c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo, 0); 9947c478bd9Sstevel@tonic-gate } 9957c478bd9Sstevel@tonic-gate } 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate free(buf); 9987c478bd9Sstevel@tonic-gate if (nlwps == 0) { 9997c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 10007c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 10017c478bd9Sstevel@tonic-gate continue; 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate } else { 10047c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl, psinfo.pr_lwp.pr_onpro) || 1005c6402783Sakolb !has_element(&set_tbl, psinfo.pr_lwp.pr_bindpset) || 1006c6402783Sakolb !has_element(&lgr_tbl, psinfo.pr_lwp.pr_lgrp)) { 10077c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 10087c478bd9Sstevel@tonic-gate continue; 10097c478bd9Sstevel@tonic-gate } 10107c478bd9Sstevel@tonic-gate add_proc(&psinfo); 10117c478bd9Sstevel@tonic-gate } 10127c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_MSACCT)) { 10137c478bd9Sstevel@tonic-gate total_procs++; 10147c478bd9Sstevel@tonic-gate total_lwps += nlwps; 10157c478bd9Sstevel@tonic-gate continue; 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate /* 10187c478bd9Sstevel@tonic-gate * Get more information about processes from /proc/pid/usage. 10197c478bd9Sstevel@tonic-gate * If process has more than one lwp, then we may have to 10207c478bd9Sstevel@tonic-gate * also look at the /proc/pid/lusage file. 10217c478bd9Sstevel@tonic-gate */ 10227c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_LWPS) && (nlwps > 1)) { 10237c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lusage, pidstr, "lusage", 10247c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) { 10257c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 10267c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 10277c478bd9Sstevel@tonic-gate continue; 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate nent = header.pr_nent; 10307c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent; 10317c478bd9Sstevel@tonic-gate buf = Malloc(entsz); 10327c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lusage), buf, 10337c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) { 10347c478bd9Sstevel@tonic-gate fd_close(fds->fds_lusage); 10357c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 10367c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 10377c478bd9Sstevel@tonic-gate free(buf); 10387c478bd9Sstevel@tonic-gate continue; 10397c478bd9Sstevel@tonic-gate } 10407c478bd9Sstevel@tonic-gate for (i = 1, ptr = buf + header.pr_entsize; i < nent; 10417c478bd9Sstevel@tonic-gate i++, ptr += header.pr_entsize) { 10427c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/ 10437c478bd9Sstevel@tonic-gate lwpusage = (prusage_t *)ptr; 10447c478bd9Sstevel@tonic-gate lwpid = lwpusage->pr_lwpid; 10457c478bd9Sstevel@tonic-gate /* 10467c478bd9Sstevel@tonic-gate * New LWPs created after we read lpsinfo 10477c478bd9Sstevel@tonic-gate * will be ignored. Don't want to do 10487c478bd9Sstevel@tonic-gate * everything all over again. 10497c478bd9Sstevel@tonic-gate */ 10507c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 10517c478bd9Sstevel@tonic-gate continue; 10527c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, lwpusage); 10537c478bd9Sstevel@tonic-gate } 10547c478bd9Sstevel@tonic-gate free(buf); 10557c478bd9Sstevel@tonic-gate } else { 10567c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_usage, pidstr, "usage", 10577c478bd9Sstevel@tonic-gate &usage, sizeof (prusage_t)) != 0) { 10587c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 10597c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 10607c478bd9Sstevel@tonic-gate continue; 10617c478bd9Sstevel@tonic-gate } 10627c478bd9Sstevel@tonic-gate lwpid = psinfo.pr_lwp.pr_lwpid; 10637c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 10647c478bd9Sstevel@tonic-gate continue; 10657c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, &usage); 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate total_procs++; 10687c478bd9Sstevel@tonic-gate total_lwps += nlwps; 10697c478bd9Sstevel@tonic-gate } 10707c478bd9Sstevel@tonic-gate fd_update(); 10717c478bd9Sstevel@tonic-gate } 10727c478bd9Sstevel@tonic-gate 10737c478bd9Sstevel@tonic-gate /* 10747c478bd9Sstevel@tonic-gate * This procedure removes all dead lwps from the linked list of all lwps. 10757c478bd9Sstevel@tonic-gate * It also creates linked list of ids if necessary. 10767c478bd9Sstevel@tonic-gate */ 10777c478bd9Sstevel@tonic-gate static void 10787c478bd9Sstevel@tonic-gate list_refresh(list_t *list) 10797c478bd9Sstevel@tonic-gate { 10807c478bd9Sstevel@tonic-gate lwp_info_t *lwp, *lwp_next; 10817c478bd9Sstevel@tonic-gate 10827c478bd9Sstevel@tonic-gate if (!(list->l_type & LT_LWPS)) 10837c478bd9Sstevel@tonic-gate return; 10847c478bd9Sstevel@tonic-gate 10857c478bd9Sstevel@tonic-gate for (lwp = list->l_head; lwp != NULL; ) { 10867c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_ALIVE) { 10877c478bd9Sstevel@tonic-gate /* 10887c478bd9Sstevel@tonic-gate * Process all live LWPs. 10897c478bd9Sstevel@tonic-gate * When we're done, mark them as dead. 10907c478bd9Sstevel@tonic-gate * They will be marked "alive" on the next 10917c478bd9Sstevel@tonic-gate * /proc scan if they still exist. 10927c478bd9Sstevel@tonic-gate */ 10937c478bd9Sstevel@tonic-gate lwp->li_key = list_getkeyval(list, lwp); 10947c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 10957c478bd9Sstevel@tonic-gate list_update(&users, lwp); 10967c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS) 10977c478bd9Sstevel@tonic-gate list_update(&tasks, lwp); 10987c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS) 10997c478bd9Sstevel@tonic-gate list_update(&projects, lwp); 11007c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES) 11017c478bd9Sstevel@tonic-gate list_update(&zones, lwp); 1102c6402783Sakolb if (opts.o_outpmode & OPT_LGRP) 1103c6402783Sakolb list_update(&lgroups, lwp); 11047c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_ALIVE; 11057c478bd9Sstevel@tonic-gate lwp = lwp->li_next; 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate } else { 11087c478bd9Sstevel@tonic-gate lwp_next = lwp->li_next; 11097c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp); 11107c478bd9Sstevel@tonic-gate lwp = lwp_next; 11117c478bd9Sstevel@tonic-gate } 11127c478bd9Sstevel@tonic-gate } 11137c478bd9Sstevel@tonic-gate } 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate static void 11167c478bd9Sstevel@tonic-gate curses_on() 11177c478bd9Sstevel@tonic-gate { 11187c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) { 11197c478bd9Sstevel@tonic-gate (void) initscr(); 11207c478bd9Sstevel@tonic-gate (void) nonl(); 11217c478bd9Sstevel@tonic-gate (void) putp(t_smcup); 11227c478bd9Sstevel@tonic-gate is_curses_on = TRUE; 11237c478bd9Sstevel@tonic-gate } 11247c478bd9Sstevel@tonic-gate } 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate static void 11277c478bd9Sstevel@tonic-gate curses_off() 11287c478bd9Sstevel@tonic-gate { 11297c478bd9Sstevel@tonic-gate if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) { 11307c478bd9Sstevel@tonic-gate (void) putp(t_rmcup); 11317c478bd9Sstevel@tonic-gate (void) endwin(); 11327c478bd9Sstevel@tonic-gate is_curses_on = FALSE; 11337c478bd9Sstevel@tonic-gate } 11347c478bd9Sstevel@tonic-gate (void) fflush(stdout); 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate static int 11387c478bd9Sstevel@tonic-gate nlines() 11397c478bd9Sstevel@tonic-gate { 11407c478bd9Sstevel@tonic-gate struct winsize ws; 11417c478bd9Sstevel@tonic-gate char *envp; 11427c478bd9Sstevel@tonic-gate int n; 11437c478bd9Sstevel@tonic-gate if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) { 11447c478bd9Sstevel@tonic-gate if (ws.ws_row > 0) 11457c478bd9Sstevel@tonic-gate return (ws.ws_row); 11467c478bd9Sstevel@tonic-gate } 11477c478bd9Sstevel@tonic-gate if (envp = getenv("LINES")) { 11487c478bd9Sstevel@tonic-gate if ((n = Atoi(envp)) > 0) { 11497c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 11507c478bd9Sstevel@tonic-gate return (n); 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate return (-1); 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate static void 11577c478bd9Sstevel@tonic-gate setmovecur() 11587c478bd9Sstevel@tonic-gate { 11597c478bd9Sstevel@tonic-gate int i, n; 11607c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_FULLSCREEN) && 11617c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_USEHOME)) { 11627c478bd9Sstevel@tonic-gate movecur = t_home; 11637c478bd9Sstevel@tonic-gate return; 11647c478bd9Sstevel@tonic-gate } 11657c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) { 1166*156d6b3aSJerry Jelinek if (opts.o_ntop == 0) 1167*156d6b3aSJerry Jelinek n = opts.o_nbottom + 1; 1168*156d6b3aSJerry Jelinek else 11697c478bd9Sstevel@tonic-gate n = opts.o_ntop + opts.o_nbottom + 2; 11707c478bd9Sstevel@tonic-gate } else { 11717c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 11727c478bd9Sstevel@tonic-gate n = opts.o_nbottom + 1; 11737c478bd9Sstevel@tonic-gate else 11747c478bd9Sstevel@tonic-gate n = opts.o_ntop + 1; 11757c478bd9Sstevel@tonic-gate } 11764944376cSJohn Levon if (((opts.o_outpmode & OPT_UDATE) || (opts.o_outpmode & OPT_DDATE))) 11774944376cSJohn Levon n++; 11784944376cSJohn Levon 11797c478bd9Sstevel@tonic-gate if (movecur != NULL && movecur != empty_string && movecur != t_home) 11807c478bd9Sstevel@tonic-gate free(movecur); 11817c478bd9Sstevel@tonic-gate movecur = Zalloc(strlen(t_up) * (n + 5)); 11827c478bd9Sstevel@tonic-gate for (i = 0; i <= n; i++) 11837c478bd9Sstevel@tonic-gate (void) strcat(movecur, t_up); 11847c478bd9Sstevel@tonic-gate } 11857c478bd9Sstevel@tonic-gate 11867c478bd9Sstevel@tonic-gate static int 11877c478bd9Sstevel@tonic-gate setsize() 11887c478bd9Sstevel@tonic-gate { 11897c478bd9Sstevel@tonic-gate static int oldn = 0; 11907c478bd9Sstevel@tonic-gate int n; 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) { 11937c478bd9Sstevel@tonic-gate n = nlines(); 11947c478bd9Sstevel@tonic-gate if (n == oldn) 11957c478bd9Sstevel@tonic-gate return (0); 11967c478bd9Sstevel@tonic-gate oldn = n; 11977c478bd9Sstevel@tonic-gate if (n == -1) { 11987c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 11997c478bd9Sstevel@tonic-gate setmovecur(); /* set default window size */ 12007c478bd9Sstevel@tonic-gate return (1); 12017c478bd9Sstevel@tonic-gate } 12027c478bd9Sstevel@tonic-gate n = n - 3; /* minus header, total and cursor lines */ 12034944376cSJohn Levon if ((opts.o_outpmode & OPT_UDATE) || 12044944376cSJohn Levon (opts.o_outpmode & OPT_DDATE)) 12054944376cSJohn Levon n--; /* minus timestamp */ 12067c478bd9Sstevel@tonic-gate if (n < 1) 12077c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n")); 12087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) { 12097c478bd9Sstevel@tonic-gate if (n < 8) { 12107c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n")); 12117c478bd9Sstevel@tonic-gate } else { 12127c478bd9Sstevel@tonic-gate opts.o_ntop = (n / 4) * 3; 12137c478bd9Sstevel@tonic-gate opts.o_nbottom = n - 1 - opts.o_ntop; 12147c478bd9Sstevel@tonic-gate } 12157c478bd9Sstevel@tonic-gate } else { 12167c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 12177c478bd9Sstevel@tonic-gate opts.o_nbottom = n; 12187c478bd9Sstevel@tonic-gate else 12197c478bd9Sstevel@tonic-gate opts.o_ntop = n; 12207c478bd9Sstevel@tonic-gate } 12217c478bd9Sstevel@tonic-gate } 12227c478bd9Sstevel@tonic-gate setmovecur(); 12237c478bd9Sstevel@tonic-gate return (1); 12247c478bd9Sstevel@tonic-gate } 12257c478bd9Sstevel@tonic-gate 12267c478bd9Sstevel@tonic-gate static void 12277c478bd9Sstevel@tonic-gate ldtermcap() 12287c478bd9Sstevel@tonic-gate { 12297c478bd9Sstevel@tonic-gate int err; 12307c478bd9Sstevel@tonic-gate if (setupterm(NULL, STDIN_FILENO, &err) == ERR) { 12317c478bd9Sstevel@tonic-gate switch (err) { 12327c478bd9Sstevel@tonic-gate case 0: 12337c478bd9Sstevel@tonic-gate Warn(gettext("failed to load terminal info, " 12347c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 12357c478bd9Sstevel@tonic-gate break; 12367c478bd9Sstevel@tonic-gate case -1: 12377c478bd9Sstevel@tonic-gate Warn(gettext("terminfo database not found, " 12387c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 12397c478bd9Sstevel@tonic-gate break; 12407c478bd9Sstevel@tonic-gate default: 12417c478bd9Sstevel@tonic-gate Warn(gettext("failed to initialize terminal, " 12427c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 12457c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string; 12467c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string; 12477c478bd9Sstevel@tonic-gate return; 12487c478bd9Sstevel@tonic-gate } 12497c478bd9Sstevel@tonic-gate t_ulon = tigetstr("smul"); 12507c478bd9Sstevel@tonic-gate t_uloff = tigetstr("rmul"); 12517c478bd9Sstevel@tonic-gate t_up = tigetstr("cuu1"); 12527c478bd9Sstevel@tonic-gate t_eol = tigetstr("el"); 12537c478bd9Sstevel@tonic-gate t_smcup = tigetstr("smcup"); 12547c478bd9Sstevel@tonic-gate t_rmcup = tigetstr("rmcup"); 12557c478bd9Sstevel@tonic-gate t_home = tigetstr("home"); 12567c478bd9Sstevel@tonic-gate if ((t_up == (char *)-1) || (t_eol == (char *)-1) || 12577c478bd9Sstevel@tonic-gate (t_smcup == (char *)-1) || (t_rmcup == (char *)-1)) { 12587c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 12597c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string; 12607c478bd9Sstevel@tonic-gate return; 12617c478bd9Sstevel@tonic-gate } 12627c478bd9Sstevel@tonic-gate if (t_up == NULL || t_eol == NULL) { 12637c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 12647c478bd9Sstevel@tonic-gate t_eol = t_up = movecur = empty_string; 12657c478bd9Sstevel@tonic-gate return; 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate if (t_ulon == (char *)-1 || t_uloff == (char *)-1 || 12687c478bd9Sstevel@tonic-gate t_ulon == NULL || t_uloff == NULL) { 12697c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string; /* can live without it */ 12707c478bd9Sstevel@tonic-gate } 12717c478bd9Sstevel@tonic-gate if (t_smcup == NULL || t_rmcup == NULL) 12727c478bd9Sstevel@tonic-gate t_smcup = t_rmcup = empty_string; 12737c478bd9Sstevel@tonic-gate if (t_home == (char *)-1 || t_home == NULL) { 12747c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 12757c478bd9Sstevel@tonic-gate t_home = empty_string; 12767c478bd9Sstevel@tonic-gate } 12777c478bd9Sstevel@tonic-gate } 12787c478bd9Sstevel@tonic-gate 12797c478bd9Sstevel@tonic-gate static void 12807c478bd9Sstevel@tonic-gate sig_handler(int sig) 12817c478bd9Sstevel@tonic-gate { 12827c478bd9Sstevel@tonic-gate switch (sig) { 12837c478bd9Sstevel@tonic-gate case SIGTSTP: sigtstp = 1; 12847c478bd9Sstevel@tonic-gate break; 12857c478bd9Sstevel@tonic-gate case SIGWINCH: sigwinch = 1; 12867c478bd9Sstevel@tonic-gate break; 12877c478bd9Sstevel@tonic-gate case SIGINT: 12887c478bd9Sstevel@tonic-gate case SIGTERM: sigterm = 1; 12897c478bd9Sstevel@tonic-gate break; 12907c478bd9Sstevel@tonic-gate } 12917c478bd9Sstevel@tonic-gate } 12927c478bd9Sstevel@tonic-gate 12937c478bd9Sstevel@tonic-gate static void 12947c478bd9Sstevel@tonic-gate set_signals() 12957c478bd9Sstevel@tonic-gate { 12967c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler); 12977c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sig_handler); 12987c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, sig_handler); 12997c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) 13007c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler); 13017c478bd9Sstevel@tonic-gate } 13027c478bd9Sstevel@tonic-gate 13037c478bd9Sstevel@tonic-gate static void 1304a851ab35Svb160487 fill_table(table_t *table, char *arg, char option) 13057c478bd9Sstevel@tonic-gate { 13067c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 13077c478bd9Sstevel@tonic-gate 1308a851ab35Svb160487 if (p == NULL) 1309a851ab35Svb160487 Die(gettext("invalid argument for -%c\n"), option); 1310a851ab35Svb160487 1311a851ab35Svb160487 add_element(table, (long)Atoi(p)); 1312a851ab35Svb160487 while (p = strtok(NULL, ", ")) 1313a851ab35Svb160487 add_element(table, (long)Atoi(p)); 13147c478bd9Sstevel@tonic-gate } 13157c478bd9Sstevel@tonic-gate 13167c478bd9Sstevel@tonic-gate static void 13177c478bd9Sstevel@tonic-gate fill_prj_table(char *arg) 13187c478bd9Sstevel@tonic-gate { 13197c478bd9Sstevel@tonic-gate projid_t projid; 13207c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 13217c478bd9Sstevel@tonic-gate 1322a851ab35Svb160487 if (p == NULL) 1323a851ab35Svb160487 Die(gettext("invalid argument for -j\n")); 1324a851ab35Svb160487 13257c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1) 13267c478bd9Sstevel@tonic-gate projid = Atoi(p); 13277c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid); 13287c478bd9Sstevel@tonic-gate 13297c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) { 13307c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1) 13317c478bd9Sstevel@tonic-gate projid = Atoi(p); 13327c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid); 13337c478bd9Sstevel@tonic-gate } 13347c478bd9Sstevel@tonic-gate } 13357c478bd9Sstevel@tonic-gate 13367c478bd9Sstevel@tonic-gate static void 13377c478bd9Sstevel@tonic-gate fill_set_table(char *arg) 13387c478bd9Sstevel@tonic-gate { 13397c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 13407c478bd9Sstevel@tonic-gate psetid_t id; 13417c478bd9Sstevel@tonic-gate 1342a851ab35Svb160487 if (p == NULL) 1343a851ab35Svb160487 Die(gettext("invalid argument for -C\n")); 1344a851ab35Svb160487 13457c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0) 13467c478bd9Sstevel@tonic-gate id = PS_NONE; 13477c478bd9Sstevel@tonic-gate add_element(&set_tbl, id); 13487c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) { 13497c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0) 13507c478bd9Sstevel@tonic-gate id = PS_NONE; 13517c478bd9Sstevel@tonic-gate if (!has_element(&set_tbl, id)) 13527c478bd9Sstevel@tonic-gate add_element(&set_tbl, id); 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate } 13557c478bd9Sstevel@tonic-gate 13567c478bd9Sstevel@tonic-gate static void 13577c478bd9Sstevel@tonic-gate Exit() 13587c478bd9Sstevel@tonic-gate { 13597c478bd9Sstevel@tonic-gate curses_off(); 13607c478bd9Sstevel@tonic-gate list_clear(&lwps); 13617c478bd9Sstevel@tonic-gate list_clear(&users); 13627c478bd9Sstevel@tonic-gate list_clear(&tasks); 13637c478bd9Sstevel@tonic-gate list_clear(&projects); 13647c478bd9Sstevel@tonic-gate list_clear(&zones); 13657c478bd9Sstevel@tonic-gate fd_exit(); 13667c478bd9Sstevel@tonic-gate } 13677c478bd9Sstevel@tonic-gate 13680209230bSgjelinek 13697c478bd9Sstevel@tonic-gate int 13707c478bd9Sstevel@tonic-gate main(int argc, char **argv) 13717c478bd9Sstevel@tonic-gate { 13727c478bd9Sstevel@tonic-gate DIR *procdir; 13737c478bd9Sstevel@tonic-gate char *p; 13747c478bd9Sstevel@tonic-gate char *sortk = "cpu"; /* default sort key */ 13757c478bd9Sstevel@tonic-gate int opt; 13767c478bd9Sstevel@tonic-gate int timeout; 13777c478bd9Sstevel@tonic-gate struct pollfd pollset; 13787c478bd9Sstevel@tonic-gate char key; 13797c478bd9Sstevel@tonic-gate 13807c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 13817c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 13827c478bd9Sstevel@tonic-gate Progname(argv[0]); 13837c478bd9Sstevel@tonic-gate lwpid_init(); 13847c478bd9Sstevel@tonic-gate fd_init(Setrlimit()); 13857c478bd9Sstevel@tonic-gate 13860209230bSgjelinek pagesize = sysconf(_SC_PAGESIZE); 13870209230bSgjelinek 13884944376cSJohn Levon while ((opt = getopt(argc, argv, 13890a1278f2SGary Mills "vcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) { 13907c478bd9Sstevel@tonic-gate switch (opt) { 13917166d658SMenno Lageman case 'r': 13927166d658SMenno Lageman opts.o_outpmode |= OPT_NORESOLVE; 13937166d658SMenno Lageman break; 13947c478bd9Sstevel@tonic-gate case 'R': 13957c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_REALTIME; 13967c478bd9Sstevel@tonic-gate break; 13977c478bd9Sstevel@tonic-gate case 'c': 13987c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 13997c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 14007c478bd9Sstevel@tonic-gate break; 14014944376cSJohn Levon case 'd': 14024944376cSJohn Levon if (optarg) { 14034944376cSJohn Levon if (*optarg == 'u') 14044944376cSJohn Levon opts.o_outpmode |= OPT_UDATE; 14054944376cSJohn Levon else if (*optarg == 'd') 14064944376cSJohn Levon opts.o_outpmode |= OPT_DDATE; 14074944376cSJohn Levon else 14084944376cSJohn Levon Usage(); 14094944376cSJohn Levon } else { 14104944376cSJohn Levon Usage(); 14114944376cSJohn Levon } 14124944376cSJohn Levon break; 1413c6402783Sakolb case 'h': 1414c6402783Sakolb fill_table(&lgr_tbl, optarg, 'h'); 1415c6402783Sakolb break; 1416c6402783Sakolb case 'H': 1417c6402783Sakolb opts.o_outpmode |= OPT_LGRP; 1418c6402783Sakolb break; 14197c478bd9Sstevel@tonic-gate case 'm': 14207c478bd9Sstevel@tonic-gate case 'v': 14217c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO; 14227c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_MSACCT; 14237c478bd9Sstevel@tonic-gate break; 14247c478bd9Sstevel@tonic-gate case 't': 14257c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO; 14267c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_USERS; 14277c478bd9Sstevel@tonic-gate break; 14287c478bd9Sstevel@tonic-gate case 'a': 14297c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_USERS; 14307c478bd9Sstevel@tonic-gate break; 14317c478bd9Sstevel@tonic-gate case 'T': 14327c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_TASKS; 14337c478bd9Sstevel@tonic-gate break; 14347c478bd9Sstevel@tonic-gate case 'J': 14357c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_PROJECTS; 14367c478bd9Sstevel@tonic-gate break; 14377c478bd9Sstevel@tonic-gate case 'n': 1438a851ab35Svb160487 if ((p = strtok(optarg, ",")) == NULL) 1439a851ab35Svb160487 Die(gettext("invalid argument for -n\n")); 14407c478bd9Sstevel@tonic-gate opts.o_ntop = Atoi(p); 14417c478bd9Sstevel@tonic-gate if (p = strtok(NULL, ",")) 14427c478bd9Sstevel@tonic-gate opts.o_nbottom = Atoi(p); 1443*156d6b3aSJerry Jelinek else if (opts.o_ntop == 0) 1444*156d6b3aSJerry Jelinek opts.o_nbottom = 5; 14457c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 14467c478bd9Sstevel@tonic-gate break; 14477c478bd9Sstevel@tonic-gate case 's': 14487c478bd9Sstevel@tonic-gate opts.o_sortorder = -1; 14497c478bd9Sstevel@tonic-gate sortk = optarg; 14507c478bd9Sstevel@tonic-gate break; 14517c478bd9Sstevel@tonic-gate case 'S': 14527c478bd9Sstevel@tonic-gate opts.o_sortorder = 1; 14537c478bd9Sstevel@tonic-gate sortk = optarg; 14547c478bd9Sstevel@tonic-gate break; 14557c478bd9Sstevel@tonic-gate case 'u': 1456a851ab35Svb160487 if ((p = strtok(optarg, ", ")) == NULL) 1457a851ab35Svb160487 Die(gettext("invalid argument for -u\n")); 14587c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p); 14597c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 14607c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p); 14617c478bd9Sstevel@tonic-gate break; 14627c478bd9Sstevel@tonic-gate case 'U': 1463a851ab35Svb160487 if ((p = strtok(optarg, ", ")) == NULL) 1464a851ab35Svb160487 Die(gettext("invalid argument for -U\n")); 14657c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p); 14667c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 14677c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p); 14687c478bd9Sstevel@tonic-gate break; 14697c478bd9Sstevel@tonic-gate case 'p': 1470a851ab35Svb160487 fill_table(&pid_tbl, optarg, 'p'); 14717c478bd9Sstevel@tonic-gate break; 14727c478bd9Sstevel@tonic-gate case 'C': 14737c478bd9Sstevel@tonic-gate fill_set_table(optarg); 14747c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_PSETS; 14757c478bd9Sstevel@tonic-gate break; 14767c478bd9Sstevel@tonic-gate case 'P': 1477a851ab35Svb160487 fill_table(&cpu_tbl, optarg, 'P'); 14787c478bd9Sstevel@tonic-gate break; 14797c478bd9Sstevel@tonic-gate case 'k': 1480a851ab35Svb160487 fill_table(&tsk_tbl, optarg, 'k'); 14817c478bd9Sstevel@tonic-gate break; 14827c478bd9Sstevel@tonic-gate case 'j': 14837c478bd9Sstevel@tonic-gate fill_prj_table(optarg); 14847c478bd9Sstevel@tonic-gate break; 14857c478bd9Sstevel@tonic-gate case 'L': 14867c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_LWPS; 14877c478bd9Sstevel@tonic-gate break; 14880a1278f2SGary Mills case 'W': 14890a1278f2SGary Mills opts.o_outpmode |= OPT_TRUNC; 14900a1278f2SGary Mills break; 14917c478bd9Sstevel@tonic-gate case 'z': 1492a851ab35Svb160487 if ((p = strtok(optarg, ", ")) == NULL) 1493a851ab35Svb160487 Die(gettext("invalid argument for -z\n")); 14947c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p); 14957c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 14967c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p); 14977c478bd9Sstevel@tonic-gate break; 14987c478bd9Sstevel@tonic-gate case 'Z': 14997c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_ZONES; 15007c478bd9Sstevel@tonic-gate break; 15017c478bd9Sstevel@tonic-gate default: 15027c478bd9Sstevel@tonic-gate Usage(); 15037c478bd9Sstevel@tonic-gate } 15047c478bd9Sstevel@tonic-gate } 15057c478bd9Sstevel@tonic-gate 15067c478bd9Sstevel@tonic-gate (void) atexit(Exit); 15077c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) && 15087c478bd9Sstevel@tonic-gate !(opts.o_outpmode & OPT_SPLIT)) 15097c478bd9Sstevel@tonic-gate opts.o_nbottom = opts.o_ntop; 1510*156d6b3aSJerry Jelinek if (!(opts.o_outpmode & OPT_SPLIT) && opts.o_ntop == 0) 1511*156d6b3aSJerry Jelinek Die(gettext("invalid argument for -n\n")); 1512*156d6b3aSJerry Jelinek if (opts.o_nbottom == 0) 15137c478bd9Sstevel@tonic-gate Die(gettext("invalid argument for -n\n")); 15147c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) && 15157c478bd9Sstevel@tonic-gate ((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT)))) 15167c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with -v or -m\n")); 15177c478bd9Sstevel@tonic-gate 151851de0612SRichard Lowe if ((opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) && 15197c478bd9Sstevel@tonic-gate !((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT)))) 15207c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with " 15217c478bd9Sstevel@tonic-gate "-a, -J, -T or -Z\n")); 15227c478bd9Sstevel@tonic-gate 15237c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) && 15244944376cSJohn Levon (opts.o_outpmode & (OPT_TASKS | OPT_PROJECTS | OPT_ZONES))) 15257c478bd9Sstevel@tonic-gate Die(gettext("-a option cannot be used with " 15267c478bd9Sstevel@tonic-gate "-t, -J, -T or -Z\n")); 15277c478bd9Sstevel@tonic-gate 15287c478bd9Sstevel@tonic-gate if (((opts.o_outpmode & OPT_TASKS) && 15297c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_PROJECTS|OPT_ZONES))) || 15307c478bd9Sstevel@tonic-gate ((opts.o_outpmode & OPT_PROJECTS) && 15317c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_TASKS|OPT_ZONES)))) { 1532c6402783Sakolb Die(gettext( 1533c6402783Sakolb "-J, -T and -Z options are mutually exclusive\n")); 1534c6402783Sakolb } 1535c6402783Sakolb 1536c6402783Sakolb /* 1537c6402783Sakolb * There is not enough space to combine microstate information and 1538c6402783Sakolb * lgroup information and still fit in 80-column output. 1539c6402783Sakolb */ 1540c6402783Sakolb if ((opts.o_outpmode & OPT_LGRP) && (opts.o_outpmode & OPT_MSACCT)) { 1541c6402783Sakolb Die(gettext("-H and -m options are mutually exclusive\n")); 15427c478bd9Sstevel@tonic-gate } 15437c478bd9Sstevel@tonic-gate 15447c478bd9Sstevel@tonic-gate if (argc > optind) 15457c478bd9Sstevel@tonic-gate opts.o_interval = Atoi(argv[optind++]); 15467c478bd9Sstevel@tonic-gate if (argc > optind) 15477c478bd9Sstevel@tonic-gate opts.o_count = Atoi(argv[optind++]); 15487c478bd9Sstevel@tonic-gate if (opts.o_count == 0) 15497c478bd9Sstevel@tonic-gate Die(gettext("invalid counter value\n")); 15507c478bd9Sstevel@tonic-gate if (argc > optind) 15517c478bd9Sstevel@tonic-gate Usage(); 15527c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_REALTIME) 15537c478bd9Sstevel@tonic-gate Priocntl("RT"); 15547c478bd9Sstevel@tonic-gate if (isatty(STDOUT_FILENO) == 1 && isatty(STDIN_FILENO)) 15557c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_TTY; /* interactive */ 15567c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_TTY)) { 15577c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; /* no termcap for pipes */ 15587c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 15597c478bd9Sstevel@tonic-gate } 15607c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 15617c478bd9Sstevel@tonic-gate ldtermcap(); /* can turn OPT_TERMCAP off */ 15627c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 15637c478bd9Sstevel@tonic-gate (void) setsize(); 15647c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop); 15657c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom); 15667c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom); 15677c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom); 15687c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom); 1569c6402783Sakolb list_alloc(&lgroups, opts.o_nbottom); 15707c478bd9Sstevel@tonic-gate list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS); 15717c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &users, LT_USERS); 15727c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS); 15737c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS); 15747c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &zones, LT_ZONES); 1575c6402783Sakolb list_setkeyfunc(NULL, &opts, &lgroups, LT_LGRPS); 15767c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 15777c478bd9Sstevel@tonic-gate curses_on(); 15787c478bd9Sstevel@tonic-gate if ((procdir = opendir("/proc")) == NULL) 15797c478bd9Sstevel@tonic-gate Die(gettext("cannot open /proc directory\n")); 15807c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) { 15817c478bd9Sstevel@tonic-gate (void) printf(gettext("Please wait...\r")); 15824944376cSJohn Levon if (!(opts.o_outpmode & OPT_TERMCAP)) 15834944376cSJohn Levon (void) putchar('\n'); 15847c478bd9Sstevel@tonic-gate (void) fflush(stdout); 15857c478bd9Sstevel@tonic-gate } 15867c478bd9Sstevel@tonic-gate set_signals(); 15877c478bd9Sstevel@tonic-gate pollset.fd = STDIN_FILENO; 15887c478bd9Sstevel@tonic-gate pollset.events = POLLIN; 15897c478bd9Sstevel@tonic-gate timeout = opts.o_interval * MILLISEC; 15907c478bd9Sstevel@tonic-gate 15917c478bd9Sstevel@tonic-gate /* 15927c478bd9Sstevel@tonic-gate * main program loop 15937c478bd9Sstevel@tonic-gate */ 15947c478bd9Sstevel@tonic-gate do { 15957c478bd9Sstevel@tonic-gate if (sigterm == 1) 15967c478bd9Sstevel@tonic-gate break; 15977c478bd9Sstevel@tonic-gate if (sigtstp == 1) { 15987c478bd9Sstevel@tonic-gate curses_off(); 15997c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, SIG_DFL); 16007c478bd9Sstevel@tonic-gate (void) kill(0, SIGTSTP); 16017c478bd9Sstevel@tonic-gate /* 16027c478bd9Sstevel@tonic-gate * prstat stops here until it receives SIGCONT signal. 16037c478bd9Sstevel@tonic-gate */ 16047c478bd9Sstevel@tonic-gate sigtstp = 0; 16057c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler); 16067c478bd9Sstevel@tonic-gate curses_on(); 16077c478bd9Sstevel@tonic-gate print_movecur = FALSE; 16087c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) 16097c478bd9Sstevel@tonic-gate sigwinch = 1; 16107c478bd9Sstevel@tonic-gate } 16117c478bd9Sstevel@tonic-gate if (sigwinch == 1) { 16127c478bd9Sstevel@tonic-gate if (setsize() == 1) { 16137c478bd9Sstevel@tonic-gate list_free(&lwps); 16147c478bd9Sstevel@tonic-gate list_free(&users); 16157c478bd9Sstevel@tonic-gate list_free(&tasks); 16167c478bd9Sstevel@tonic-gate list_free(&projects); 16177c478bd9Sstevel@tonic-gate list_free(&zones); 16187c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop); 16197c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom); 16207c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom); 16217c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom); 16227c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom); 16237c478bd9Sstevel@tonic-gate } 16247c478bd9Sstevel@tonic-gate sigwinch = 0; 16257c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler); 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate prstat_scandir(procdir); 16287c478bd9Sstevel@tonic-gate list_refresh(&lwps); 16297c478bd9Sstevel@tonic-gate if (print_movecur) 16307c478bd9Sstevel@tonic-gate (void) putp(movecur); 16317c478bd9Sstevel@tonic-gate print_movecur = TRUE; 16327c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_PSINFO) || 16337c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_MSACCT)) { 16347c478bd9Sstevel@tonic-gate list_sort(&lwps); 16357c478bd9Sstevel@tonic-gate list_print(&lwps); 16367c478bd9Sstevel@tonic-gate } 16377c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) { 16380209230bSgjelinek list_getsize(&users); 16397c478bd9Sstevel@tonic-gate list_sort(&users); 16407c478bd9Sstevel@tonic-gate list_print(&users); 16417c478bd9Sstevel@tonic-gate list_clear(&users); 16427c478bd9Sstevel@tonic-gate } 16437c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS) { 16440209230bSgjelinek list_getsize(&tasks); 16457c478bd9Sstevel@tonic-gate list_sort(&tasks); 16467c478bd9Sstevel@tonic-gate list_print(&tasks); 16477c478bd9Sstevel@tonic-gate list_clear(&tasks); 16487c478bd9Sstevel@tonic-gate } 16497c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS) { 16500209230bSgjelinek list_getsize(&projects); 16517c478bd9Sstevel@tonic-gate list_sort(&projects); 16527c478bd9Sstevel@tonic-gate list_print(&projects); 16537c478bd9Sstevel@tonic-gate list_clear(&projects); 16547c478bd9Sstevel@tonic-gate } 16557c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES) { 16560209230bSgjelinek list_getsize(&zones); 16577c478bd9Sstevel@tonic-gate list_sort(&zones); 16587c478bd9Sstevel@tonic-gate list_print(&zones); 16597c478bd9Sstevel@tonic-gate list_clear(&zones); 16607c478bd9Sstevel@tonic-gate } 16617c478bd9Sstevel@tonic-gate if (opts.o_count == 1) 16627c478bd9Sstevel@tonic-gate break; 16637c478bd9Sstevel@tonic-gate /* 16647c478bd9Sstevel@tonic-gate * If poll() returns -1 and sets errno to EINTR here because 16657c478bd9Sstevel@tonic-gate * the process received a signal, it is Ok to abort this 16667c478bd9Sstevel@tonic-gate * timeout and loop around because we check the signals at the 16677c478bd9Sstevel@tonic-gate * top of the loop. 16687c478bd9Sstevel@tonic-gate */ 16697c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) { 16707c478bd9Sstevel@tonic-gate if (poll(&pollset, (nfds_t)1, timeout) > 0) { 16717c478bd9Sstevel@tonic-gate if (read(STDIN_FILENO, &key, 1) == 1) { 16727c478bd9Sstevel@tonic-gate if (tolower(key) == 'q') 16737c478bd9Sstevel@tonic-gate break; 16747c478bd9Sstevel@tonic-gate } 16757c478bd9Sstevel@tonic-gate } 16767c478bd9Sstevel@tonic-gate } else { 16777c478bd9Sstevel@tonic-gate (void) sleep(opts.o_interval); 16787c478bd9Sstevel@tonic-gate } 16797c478bd9Sstevel@tonic-gate } while (opts.o_count == (-1) || --opts.o_count); 16807c478bd9Sstevel@tonic-gate 16817c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 16827c478bd9Sstevel@tonic-gate (void) putchar('\r'); 16837c478bd9Sstevel@tonic-gate return (0); 16847c478bd9Sstevel@tonic-gate } 1685