1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/resource.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/loadavg.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/pset.h> 34*7c478bd9Sstevel@tonic-gate #include <zone.h> 35*7c478bd9Sstevel@tonic-gate #include <libzonecfg.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <stdio.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate #include <dirent.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate #include <errno.h> 43*7c478bd9Sstevel@tonic-gate #include <poll.h> 44*7c478bd9Sstevel@tonic-gate #include <ctype.h> 45*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 46*7c478bd9Sstevel@tonic-gate #include <limits.h> 47*7c478bd9Sstevel@tonic-gate #include <signal.h> 48*7c478bd9Sstevel@tonic-gate #include <time.h> 49*7c478bd9Sstevel@tonic-gate #include <project.h> 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate #include <libintl.h> 52*7c478bd9Sstevel@tonic-gate #include <locale.h> 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #include "prstat.h" 55*7c478bd9Sstevel@tonic-gate #include "prutil.h" 56*7c478bd9Sstevel@tonic-gate #include "prtable.h" 57*7c478bd9Sstevel@tonic-gate #include "prsort.h" 58*7c478bd9Sstevel@tonic-gate #include "prfile.h" 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * x86 <sys/regs.h> ERR conflicts with <curses.h> ERR. For the purposes 62*7c478bd9Sstevel@tonic-gate * of this file, we care about the curses.h ERR so include that last. 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate #if defined(ERR) 66*7c478bd9Sstevel@tonic-gate #undef ERR 67*7c478bd9Sstevel@tonic-gate #endif 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN /* should be defined by cc -D */ 70*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* use this only if it wasn't */ 71*7c478bd9Sstevel@tonic-gate #endif 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #include <curses.h> 74*7c478bd9Sstevel@tonic-gate #include <term.h> 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_PROC \ 77*7c478bd9Sstevel@tonic-gate " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP " 78*7c478bd9Sstevel@tonic-gate #define PSINFO_HEADER_LWP \ 79*7c478bd9Sstevel@tonic-gate " PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID " 80*7c478bd9Sstevel@tonic-gate #define USAGE_HEADER_PROC \ 81*7c478bd9Sstevel@tonic-gate " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP " 82*7c478bd9Sstevel@tonic-gate #define USAGE_HEADER_LWP \ 83*7c478bd9Sstevel@tonic-gate " PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID " 84*7c478bd9Sstevel@tonic-gate #define USER_HEADER_PROC \ 85*7c478bd9Sstevel@tonic-gate " NPROC USERNAME SIZE RSS MEMORY TIME CPU " 86*7c478bd9Sstevel@tonic-gate #define USER_HEADER_LWP \ 87*7c478bd9Sstevel@tonic-gate " NLWP USERNAME SIZE RSS MEMORY TIME CPU " 88*7c478bd9Sstevel@tonic-gate #define TASK_HEADER_PROC \ 89*7c478bd9Sstevel@tonic-gate "TASKID NPROC SIZE RSS MEMORY TIME CPU PROJECT " 90*7c478bd9Sstevel@tonic-gate #define TASK_HEADER_LWP \ 91*7c478bd9Sstevel@tonic-gate "TASKID NLWP SIZE RSS MEMORY TIME CPU PROJECT " 92*7c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_PROC \ 93*7c478bd9Sstevel@tonic-gate "PROJID NPROC SIZE RSS MEMORY TIME CPU PROJECT " 94*7c478bd9Sstevel@tonic-gate #define PROJECT_HEADER_LWP \ 95*7c478bd9Sstevel@tonic-gate "PROJID NLWP SIZE RSS MEMORY TIME CPU PROJECT " 96*7c478bd9Sstevel@tonic-gate #define ZONE_HEADER_PROC \ 97*7c478bd9Sstevel@tonic-gate "ZONEID NPROC SIZE RSS MEMORY TIME CPU ZONE " 98*7c478bd9Sstevel@tonic-gate #define ZONE_HEADER_LWP \ 99*7c478bd9Sstevel@tonic-gate "ZONEID NLWP SIZE RSS MEMORY TIME CPU ZONE " 100*7c478bd9Sstevel@tonic-gate #define PSINFO_LINE \ 101*7c478bd9Sstevel@tonic-gate "%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d" 102*7c478bd9Sstevel@tonic-gate #define USAGE_LINE \ 103*7c478bd9Sstevel@tonic-gate "%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\ 104*7c478bd9Sstevel@tonic-gate "%3.3s %-.12s/%d" 105*7c478bd9Sstevel@tonic-gate #define USER_LINE \ 106*7c478bd9Sstevel@tonic-gate "%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%" 107*7c478bd9Sstevel@tonic-gate #define TASK_LINE \ 108*7c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 109*7c478bd9Sstevel@tonic-gate #define PROJECT_LINE \ 110*7c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 111*7c478bd9Sstevel@tonic-gate #define ZONE_LINE \ 112*7c478bd9Sstevel@tonic-gate "%6d %8d %5s %5s %3.3s%% %9s %3.3s%% %28s" 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate #define TOTAL_LINE \ 115*7c478bd9Sstevel@tonic-gate "Total: %d processes, %d lwps, load averages: %3.2f, %3.2f, %3.2f" 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* global variables */ 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate static char *t_ulon; /* termcap: start underline */ 120*7c478bd9Sstevel@tonic-gate static char *t_uloff; /* termcap: end underline */ 121*7c478bd9Sstevel@tonic-gate static char *t_up; /* termcap: cursor 1 line up */ 122*7c478bd9Sstevel@tonic-gate static char *t_eol; /* termcap: clear end of line */ 123*7c478bd9Sstevel@tonic-gate static char *t_smcup; /* termcap: cursor mvcap on */ 124*7c478bd9Sstevel@tonic-gate static char *t_rmcup; /* termcap: cursor mvcap off */ 125*7c478bd9Sstevel@tonic-gate static char *t_home; /* termcap: move cursor home */ 126*7c478bd9Sstevel@tonic-gate static char *movecur = NULL; /* termcap: move up string */ 127*7c478bd9Sstevel@tonic-gate static char *empty_string = "\0"; /* termcap: empty string */ 128*7c478bd9Sstevel@tonic-gate static uint_t print_movecur = FALSE; /* print movecur or not */ 129*7c478bd9Sstevel@tonic-gate static int is_curses_on = FALSE; /* current curses state */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate static table_t pid_tbl = {0, 0, NULL}; /* selected processes */ 132*7c478bd9Sstevel@tonic-gate static table_t cpu_tbl = {0, 0, NULL}; /* selected processors */ 133*7c478bd9Sstevel@tonic-gate static table_t set_tbl = {0, 0, NULL}; /* selected processor sets */ 134*7c478bd9Sstevel@tonic-gate static table_t prj_tbl = {0, 0, NULL}; /* selected projects */ 135*7c478bd9Sstevel@tonic-gate static table_t tsk_tbl = {0, 0, NULL}; /* selected tasks */ 136*7c478bd9Sstevel@tonic-gate static zonetbl_t zone_tbl = {0, 0, NULL}; /* selected zones */ 137*7c478bd9Sstevel@tonic-gate static nametbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */ 138*7c478bd9Sstevel@tonic-gate static nametbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */ 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate static uint_t total_procs; /* total number of procs */ 141*7c478bd9Sstevel@tonic-gate static uint_t total_lwps; /* total number of lwps */ 142*7c478bd9Sstevel@tonic-gate static float total_cpu; /* total cpu usage */ 143*7c478bd9Sstevel@tonic-gate static float total_mem; /* total memory usage */ 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate static list_t lwps; /* list of lwps/processes */ 146*7c478bd9Sstevel@tonic-gate static list_t users; /* list of users */ 147*7c478bd9Sstevel@tonic-gate static list_t tasks; /* list of tasks */ 148*7c478bd9Sstevel@tonic-gate static list_t projects; /* list of projects */ 149*7c478bd9Sstevel@tonic-gate static list_t zones; /* list of zones */ 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate static volatile uint_t sigwinch = 0; 152*7c478bd9Sstevel@tonic-gate static volatile uint_t sigtstp = 0; 153*7c478bd9Sstevel@tonic-gate static volatile uint_t sigterm = 0; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* default settings */ 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate static optdesc_t opts = { 158*7c478bd9Sstevel@tonic-gate 5, /* interval between updates, seconds */ 159*7c478bd9Sstevel@tonic-gate 15, /* number of lines in top part */ 160*7c478bd9Sstevel@tonic-gate 5, /* number of lines in bottom part */ 161*7c478bd9Sstevel@tonic-gate -1, /* number of iterations; infinitely */ 162*7c478bd9Sstevel@tonic-gate OPT_PSINFO | OPT_FULLSCREEN | OPT_USEHOME | OPT_TERMCAP, 163*7c478bd9Sstevel@tonic-gate -1 /* sort in decreasing order */ 164*7c478bd9Sstevel@tonic-gate }; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate static void 167*7c478bd9Sstevel@tonic-gate psetloadavg(long psetid, void *ptr) 168*7c478bd9Sstevel@tonic-gate { 169*7c478bd9Sstevel@tonic-gate double psetloadavg[3]; 170*7c478bd9Sstevel@tonic-gate double *loadavg = ptr; 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (pset_getloadavg((psetid_t)psetid, psetloadavg, 3) != -1) { 173*7c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[0]; 174*7c478bd9Sstevel@tonic-gate *loadavg++ += psetloadavg[1]; 175*7c478bd9Sstevel@tonic-gate *loadavg += psetloadavg[2]; 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate * A routine to display the contents of the list on the screen 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate static void 183*7c478bd9Sstevel@tonic-gate list_print(list_t *list) 184*7c478bd9Sstevel@tonic-gate { 185*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 186*7c478bd9Sstevel@tonic-gate id_info_t *id; 187*7c478bd9Sstevel@tonic-gate char usr[4], sys[4], trp[4], tfl[4]; 188*7c478bd9Sstevel@tonic-gate char dfl[4], lck[4], slp[4], lat[4]; 189*7c478bd9Sstevel@tonic-gate char vcx[4], icx[4], scl[4], sig[4]; 190*7c478bd9Sstevel@tonic-gate char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12]; 191*7c478bd9Sstevel@tonic-gate char pstate[7], pnice[4], ppri[4]; 192*7c478bd9Sstevel@tonic-gate char pname[LOGNAME_MAX+1]; 193*7c478bd9Sstevel@tonic-gate char projname[PROJNAME_MAX+1]; 194*7c478bd9Sstevel@tonic-gate char zonename[ZONENAME_MAX+1]; 195*7c478bd9Sstevel@tonic-gate float cpu, mem; 196*7c478bd9Sstevel@tonic-gate double loadavg[3] = {0, 0, 0}; 197*7c478bd9Sstevel@tonic-gate int i, lwpid; 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate if (foreach_element(&set_tbl, &loadavg, psetloadavg) == 0) { 200*7c478bd9Sstevel@tonic-gate /* 201*7c478bd9Sstevel@tonic-gate * If processor sets aren't specified, we display system-wide 202*7c478bd9Sstevel@tonic-gate * load averages. 203*7c478bd9Sstevel@tonic-gate */ 204*7c478bd9Sstevel@tonic-gate (void) getloadavg(loadavg, 3); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 208*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 209*7c478bd9Sstevel@tonic-gate (void) putp(t_ulon); 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate switch (list->l_type) { 212*7c478bd9Sstevel@tonic-gate case LT_PROJECTS: 213*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 214*7c478bd9Sstevel@tonic-gate (void) printf(PROJECT_HEADER_LWP); 215*7c478bd9Sstevel@tonic-gate else 216*7c478bd9Sstevel@tonic-gate (void) printf(PROJECT_HEADER_PROC); 217*7c478bd9Sstevel@tonic-gate break; 218*7c478bd9Sstevel@tonic-gate case LT_TASKS: 219*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 220*7c478bd9Sstevel@tonic-gate (void) printf(TASK_HEADER_LWP); 221*7c478bd9Sstevel@tonic-gate else 222*7c478bd9Sstevel@tonic-gate (void) printf(TASK_HEADER_PROC); 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate case LT_ZONES: 225*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 226*7c478bd9Sstevel@tonic-gate (void) printf(ZONE_HEADER_LWP); 227*7c478bd9Sstevel@tonic-gate else 228*7c478bd9Sstevel@tonic-gate (void) printf(ZONE_HEADER_PROC); 229*7c478bd9Sstevel@tonic-gate break; 230*7c478bd9Sstevel@tonic-gate case LT_USERS: 231*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 232*7c478bd9Sstevel@tonic-gate (void) printf(USER_HEADER_LWP); 233*7c478bd9Sstevel@tonic-gate else 234*7c478bd9Sstevel@tonic-gate (void) printf(USER_HEADER_PROC); 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate case LT_LWPS: 237*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) { 238*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PSINFO) 239*7c478bd9Sstevel@tonic-gate (void) printf(PSINFO_HEADER_LWP); 240*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) 241*7c478bd9Sstevel@tonic-gate (void) printf(USAGE_HEADER_LWP); 242*7c478bd9Sstevel@tonic-gate } else { 243*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PSINFO) 244*7c478bd9Sstevel@tonic-gate (void) printf(PSINFO_HEADER_PROC); 245*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) 246*7c478bd9Sstevel@tonic-gate (void) printf(USAGE_HEADER_PROC); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate break; 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate (void) putp(t_uloff); 252*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 253*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate for (i = 0; i < list->l_used; i++) { 256*7c478bd9Sstevel@tonic-gate switch (list->l_type) { 257*7c478bd9Sstevel@tonic-gate case LT_PROJECTS: 258*7c478bd9Sstevel@tonic-gate case LT_TASKS: 259*7c478bd9Sstevel@tonic-gate case LT_USERS: 260*7c478bd9Sstevel@tonic-gate case LT_ZONES: 261*7c478bd9Sstevel@tonic-gate id = list->l_ptrs[i]; 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * CPU usage and memory usage normalization 264*7c478bd9Sstevel@tonic-gate */ 265*7c478bd9Sstevel@tonic-gate if (total_cpu >= 100) 266*7c478bd9Sstevel@tonic-gate cpu = (100 * id->id_pctcpu) / total_cpu; 267*7c478bd9Sstevel@tonic-gate else 268*7c478bd9Sstevel@tonic-gate cpu = id->id_pctcpu; 269*7c478bd9Sstevel@tonic-gate if (total_mem >= 100) 270*7c478bd9Sstevel@tonic-gate mem = (100 * id->id_pctmem) / total_mem; 271*7c478bd9Sstevel@tonic-gate else 272*7c478bd9Sstevel@tonic-gate mem = id->id_pctmem; 273*7c478bd9Sstevel@tonic-gate if (list->l_type == LT_USERS) 274*7c478bd9Sstevel@tonic-gate pwd_getname(id->id_uid, pname, LOGNAME_MAX + 1); 275*7c478bd9Sstevel@tonic-gate else if (list->l_type == LT_ZONES) 276*7c478bd9Sstevel@tonic-gate getzonename(id->id_zoneid, zonename, 277*7c478bd9Sstevel@tonic-gate ZONENAME_MAX); 278*7c478bd9Sstevel@tonic-gate else 279*7c478bd9Sstevel@tonic-gate getprojname(id->id_projid, projname, 280*7c478bd9Sstevel@tonic-gate PROJNAME_MAX); 281*7c478bd9Sstevel@tonic-gate Format_size(psize, id->id_size, 6); 282*7c478bd9Sstevel@tonic-gate Format_size(prssize, id->id_rssize, 6); 283*7c478bd9Sstevel@tonic-gate Format_pct(pmem, mem, 4); 284*7c478bd9Sstevel@tonic-gate Format_pct(pcpu, cpu, 4); 285*7c478bd9Sstevel@tonic-gate Format_time(ptime, id->id_time, 10); 286*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 287*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 288*7c478bd9Sstevel@tonic-gate if (list->l_type == LT_PROJECTS) 289*7c478bd9Sstevel@tonic-gate (void) printf(PROJECT_LINE, (int)id->id_projid, 290*7c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 291*7c478bd9Sstevel@tonic-gate pcpu, projname); 292*7c478bd9Sstevel@tonic-gate else if (list->l_type == LT_TASKS) 293*7c478bd9Sstevel@tonic-gate (void) printf(TASK_LINE, (int)id->id_taskid, 294*7c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 295*7c478bd9Sstevel@tonic-gate pcpu, projname); 296*7c478bd9Sstevel@tonic-gate else if (list->l_type == LT_ZONES) 297*7c478bd9Sstevel@tonic-gate (void) printf(ZONE_LINE, (int)id->id_zoneid, 298*7c478bd9Sstevel@tonic-gate id->id_nproc, psize, prssize, pmem, ptime, 299*7c478bd9Sstevel@tonic-gate pcpu, zonename); 300*7c478bd9Sstevel@tonic-gate else 301*7c478bd9Sstevel@tonic-gate (void) printf(USER_LINE, id->id_nproc, pname, 302*7c478bd9Sstevel@tonic-gate psize, prssize, pmem, ptime, pcpu); 303*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 304*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 305*7c478bd9Sstevel@tonic-gate break; 306*7c478bd9Sstevel@tonic-gate case LT_LWPS: 307*7c478bd9Sstevel@tonic-gate lwp = list->l_ptrs[i]; 308*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 309*7c478bd9Sstevel@tonic-gate lwpid = lwp->li_info.pr_lwp.pr_lwpid; 310*7c478bd9Sstevel@tonic-gate else 311*7c478bd9Sstevel@tonic-gate lwpid = lwp->li_info.pr_nlwp + 312*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_nzomb; 313*7c478bd9Sstevel@tonic-gate pwd_getname(lwp->li_info.pr_uid, pname, 314*7c478bd9Sstevel@tonic-gate LOGNAME_MAX + 1); 315*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PSINFO) { 316*7c478bd9Sstevel@tonic-gate Format_size(psize, lwp->li_info.pr_size, 6); 317*7c478bd9Sstevel@tonic-gate Format_size(prssize, lwp->li_info.pr_rssize, 6); 318*7c478bd9Sstevel@tonic-gate Format_state(pstate, 319*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname, 320*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_onpro, 7); 321*7c478bd9Sstevel@tonic-gate if (strcmp(lwp->li_info.pr_lwp.pr_clname, 322*7c478bd9Sstevel@tonic-gate "RT") == 0 || 323*7c478bd9Sstevel@tonic-gate strcmp(lwp->li_info.pr_lwp.pr_clname, 324*7c478bd9Sstevel@tonic-gate "SYS") == 0 || 325*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_sname == 'Z') 326*7c478bd9Sstevel@tonic-gate (void) strcpy(pnice, " -"); 327*7c478bd9Sstevel@tonic-gate else 328*7c478bd9Sstevel@tonic-gate Format_num(pnice, 329*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_nice - NZERO, 330*7c478bd9Sstevel@tonic-gate 4); 331*7c478bd9Sstevel@tonic-gate Format_num(ppri, lwp->li_info.pr_lwp.pr_pri, 4); 332*7c478bd9Sstevel@tonic-gate Format_pct(pcpu, 333*7c478bd9Sstevel@tonic-gate FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu), 4); 334*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 335*7c478bd9Sstevel@tonic-gate Format_time(ptime, 336*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_time.tv_sec, 337*7c478bd9Sstevel@tonic-gate 10); 338*7c478bd9Sstevel@tonic-gate else 339*7c478bd9Sstevel@tonic-gate Format_time(ptime, 340*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_time.tv_sec, 10); 341*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 342*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 343*7c478bd9Sstevel@tonic-gate stripfname(lwp->li_info.pr_fname); 344*7c478bd9Sstevel@tonic-gate (void) printf(PSINFO_LINE, 345*7c478bd9Sstevel@tonic-gate (int)lwp->li_info.pr_pid, pname, 346*7c478bd9Sstevel@tonic-gate psize, prssize, pstate, ppri, pnice, 347*7c478bd9Sstevel@tonic-gate ptime, pcpu, lwp->li_info.pr_fname, lwpid); 348*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 349*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_MSACCT) { 352*7c478bd9Sstevel@tonic-gate Format_pct(usr, lwp->li_usr, 4); 353*7c478bd9Sstevel@tonic-gate Format_pct(sys, lwp->li_sys, 4); 354*7c478bd9Sstevel@tonic-gate Format_pct(slp, lwp->li_slp, 4); 355*7c478bd9Sstevel@tonic-gate Format_num(vcx, lwp->li_vcx, 4); 356*7c478bd9Sstevel@tonic-gate Format_num(icx, lwp->li_icx, 4); 357*7c478bd9Sstevel@tonic-gate Format_num(scl, lwp->li_scl, 4); 358*7c478bd9Sstevel@tonic-gate Format_num(sig, lwp->li_sig, 4); 359*7c478bd9Sstevel@tonic-gate Format_pct(trp, lwp->li_trp, 4); 360*7c478bd9Sstevel@tonic-gate Format_pct(tfl, lwp->li_tfl, 4); 361*7c478bd9Sstevel@tonic-gate Format_pct(dfl, lwp->li_dfl, 4); 362*7c478bd9Sstevel@tonic-gate Format_pct(lck, lwp->li_lck, 4); 363*7c478bd9Sstevel@tonic-gate Format_pct(lat, lwp->li_lat, 4); 364*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 365*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 366*7c478bd9Sstevel@tonic-gate stripfname(lwp->li_info.pr_fname); 367*7c478bd9Sstevel@tonic-gate (void) printf(USAGE_LINE, 368*7c478bd9Sstevel@tonic-gate (int)lwp->li_info.pr_pid, pname, 369*7c478bd9Sstevel@tonic-gate usr, sys, trp, tfl, dfl, lck, 370*7c478bd9Sstevel@tonic-gate slp, lat, vcx, icx, scl, sig, 371*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_fname, lwpid); 372*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 373*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate break; 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 380*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 381*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) { 382*7c478bd9Sstevel@tonic-gate switch (list->l_type) { 383*7c478bd9Sstevel@tonic-gate case LT_PROJECTS: 384*7c478bd9Sstevel@tonic-gate case LT_USERS: 385*7c478bd9Sstevel@tonic-gate case LT_TASKS: 386*7c478bd9Sstevel@tonic-gate case LT_ZONES: 387*7c478bd9Sstevel@tonic-gate while (i++ < opts.o_nbottom) { 388*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 389*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate break; 392*7c478bd9Sstevel@tonic-gate case LT_LWPS: 393*7c478bd9Sstevel@tonic-gate while (i++ < opts.o_ntop) { 394*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 395*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 401*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_SPLIT) && list->l_type == LT_LWPS) 404*7c478bd9Sstevel@tonic-gate return; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate (void) printf(TOTAL_LINE, total_procs, total_lwps, 407*7c478bd9Sstevel@tonic-gate loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN], 408*7c478bd9Sstevel@tonic-gate loadavg[LOADAVG_15MIN]); 409*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 410*7c478bd9Sstevel@tonic-gate (void) putchar('\n'); 411*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 412*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 413*7c478bd9Sstevel@tonic-gate (void) putp(t_eol); 414*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate 417*7c478bd9Sstevel@tonic-gate static lwp_info_t * 418*7c478bd9Sstevel@tonic-gate list_add_lwp(list_t *list, pid_t pid, id_t lwpid) 419*7c478bd9Sstevel@tonic-gate { 420*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate if (list->l_head == NULL) { 423*7c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = lwp = Zalloc(sizeof (lwp_info_t)); 424*7c478bd9Sstevel@tonic-gate } else { 425*7c478bd9Sstevel@tonic-gate lwp = Zalloc(sizeof (lwp_info_t)); 426*7c478bd9Sstevel@tonic-gate lwp->li_prev = list->l_tail; 427*7c478bd9Sstevel@tonic-gate ((lwp_info_t *)list->l_tail)->li_next = lwp; 428*7c478bd9Sstevel@tonic-gate list->l_tail = lwp; 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_pid = pid; 431*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_lwpid = lwpid; 432*7c478bd9Sstevel@tonic-gate lwpid_add(lwp, pid, lwpid); 433*7c478bd9Sstevel@tonic-gate list->l_count++; 434*7c478bd9Sstevel@tonic-gate return (lwp); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate static void 438*7c478bd9Sstevel@tonic-gate list_remove_lwp(list_t *list, lwp_info_t *lwp) 439*7c478bd9Sstevel@tonic-gate { 440*7c478bd9Sstevel@tonic-gate if (lwp->li_prev) 441*7c478bd9Sstevel@tonic-gate lwp->li_prev->li_next = lwp->li_next; 442*7c478bd9Sstevel@tonic-gate else 443*7c478bd9Sstevel@tonic-gate list->l_head = lwp->li_next; /* removing the head */ 444*7c478bd9Sstevel@tonic-gate if (lwp->li_next) 445*7c478bd9Sstevel@tonic-gate lwp->li_next->li_prev = lwp->li_prev; 446*7c478bd9Sstevel@tonic-gate else 447*7c478bd9Sstevel@tonic-gate list->l_tail = lwp->li_prev; /* removing the tail */ 448*7c478bd9Sstevel@tonic-gate lwpid_del(lwp->li_info.pr_pid, lwp->li_info.pr_lwp.pr_lwpid); 449*7c478bd9Sstevel@tonic-gate if (lwpid_pidcheck(lwp->li_info.pr_pid) == 0) 450*7c478bd9Sstevel@tonic-gate fds_rm(lwp->li_info.pr_pid); 451*7c478bd9Sstevel@tonic-gate list->l_count--; 452*7c478bd9Sstevel@tonic-gate free(lwp); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate static void 456*7c478bd9Sstevel@tonic-gate list_clear(list_t *list) 457*7c478bd9Sstevel@tonic-gate { 458*7c478bd9Sstevel@tonic-gate if (list->l_type == LT_LWPS) { 459*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp = list->l_tail; 460*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp_tmp; 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate fd_closeall(); 463*7c478bd9Sstevel@tonic-gate while (lwp) { 464*7c478bd9Sstevel@tonic-gate lwp_tmp = lwp; 465*7c478bd9Sstevel@tonic-gate lwp = lwp->li_prev; 466*7c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp_tmp); 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate } else { 469*7c478bd9Sstevel@tonic-gate id_info_t *id = list->l_head; 470*7c478bd9Sstevel@tonic-gate id_info_t *nextid; 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate while (id) { 473*7c478bd9Sstevel@tonic-gate nextid = id->id_next; 474*7c478bd9Sstevel@tonic-gate free(id); 475*7c478bd9Sstevel@tonic-gate id = nextid; 476*7c478bd9Sstevel@tonic-gate } 477*7c478bd9Sstevel@tonic-gate list->l_count = 0; 478*7c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = NULL; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate static void 483*7c478bd9Sstevel@tonic-gate list_update(list_t *list, lwp_info_t *lwp) 484*7c478bd9Sstevel@tonic-gate { 485*7c478bd9Sstevel@tonic-gate id_info_t *id; 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate if (list->l_head == NULL) { /* first element */ 488*7c478bd9Sstevel@tonic-gate list->l_head = list->l_tail = id = Zalloc(sizeof (id_info_t)); 489*7c478bd9Sstevel@tonic-gate goto update; 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate for (id = list->l_head; id; id = id->id_next) { 493*7c478bd9Sstevel@tonic-gate if ((list->l_type == LT_USERS) && 494*7c478bd9Sstevel@tonic-gate (id->id_uid != lwp->li_info.pr_uid)) 495*7c478bd9Sstevel@tonic-gate continue; 496*7c478bd9Sstevel@tonic-gate if ((list->l_type == LT_TASKS) && 497*7c478bd9Sstevel@tonic-gate (id->id_taskid != lwp->li_info.pr_taskid)) 498*7c478bd9Sstevel@tonic-gate continue; 499*7c478bd9Sstevel@tonic-gate if ((list->l_type == LT_PROJECTS) && 500*7c478bd9Sstevel@tonic-gate (id->id_projid != lwp->li_info.pr_projid)) 501*7c478bd9Sstevel@tonic-gate continue; 502*7c478bd9Sstevel@tonic-gate if ((list->l_type == LT_ZONES) && 503*7c478bd9Sstevel@tonic-gate (id->id_zoneid != lwp->li_info.pr_zoneid)) 504*7c478bd9Sstevel@tonic-gate continue; 505*7c478bd9Sstevel@tonic-gate id->id_nproc++; 506*7c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid; 507*7c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid; 508*7c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid; 509*7c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) { 510*7c478bd9Sstevel@tonic-gate id->id_size += lwp->li_info.pr_size; 511*7c478bd9Sstevel@tonic-gate id->id_rssize += lwp->li_info.pr_rssize; 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate id->id_pctcpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 514*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 515*7c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_lwp.pr_time); 516*7c478bd9Sstevel@tonic-gate else 517*7c478bd9Sstevel@tonic-gate id->id_time += TIME2SEC(lwp->li_info.pr_time); 518*7c478bd9Sstevel@tonic-gate id->id_pctmem += FRC2PCT(lwp->li_info.pr_pctmem); 519*7c478bd9Sstevel@tonic-gate id->id_key += lwp->li_key; 520*7c478bd9Sstevel@tonic-gate total_cpu += FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 521*7c478bd9Sstevel@tonic-gate total_mem += FRC2PCT(lwp->li_info.pr_pctmem); 522*7c478bd9Sstevel@tonic-gate return; 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate id = list->l_tail; 526*7c478bd9Sstevel@tonic-gate id->id_next = Zalloc(sizeof (id_info_t)); 527*7c478bd9Sstevel@tonic-gate id->id_next->id_prev = list->l_tail; 528*7c478bd9Sstevel@tonic-gate id->id_next->id_next = NULL; 529*7c478bd9Sstevel@tonic-gate list->l_tail = id->id_next; 530*7c478bd9Sstevel@tonic-gate id = list->l_tail; 531*7c478bd9Sstevel@tonic-gate update: 532*7c478bd9Sstevel@tonic-gate id->id_uid = lwp->li_info.pr_uid; 533*7c478bd9Sstevel@tonic-gate id->id_projid = lwp->li_info.pr_projid; 534*7c478bd9Sstevel@tonic-gate id->id_taskid = lwp->li_info.pr_taskid; 535*7c478bd9Sstevel@tonic-gate id->id_zoneid = lwp->li_info.pr_zoneid; 536*7c478bd9Sstevel@tonic-gate id->id_nproc++; 537*7c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_REPRESENT) { 538*7c478bd9Sstevel@tonic-gate id->id_size = lwp->li_info.pr_size; 539*7c478bd9Sstevel@tonic-gate id->id_rssize = lwp->li_info.pr_rssize; 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate id->id_pctcpu = FRC2PCT(lwp->li_info.pr_lwp.pr_pctcpu); 542*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_LWPS) 543*7c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_lwp.pr_time); 544*7c478bd9Sstevel@tonic-gate else 545*7c478bd9Sstevel@tonic-gate id->id_time = TIME2SEC(lwp->li_info.pr_time); 546*7c478bd9Sstevel@tonic-gate id->id_pctmem = FRC2PCT(lwp->li_info.pr_pctmem); 547*7c478bd9Sstevel@tonic-gate id->id_key = lwp->li_key; 548*7c478bd9Sstevel@tonic-gate total_cpu += id->id_pctcpu; 549*7c478bd9Sstevel@tonic-gate total_mem += id->id_pctmem; 550*7c478bd9Sstevel@tonic-gate list->l_count++; 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate static void 554*7c478bd9Sstevel@tonic-gate lwp_update(lwp_info_t *lwp, pid_t pid, id_t lwpid, struct prusage *usage) 555*7c478bd9Sstevel@tonic-gate { 556*7c478bd9Sstevel@tonic-gate float period; 557*7c478bd9Sstevel@tonic-gate 558*7c478bd9Sstevel@tonic-gate if (!lwpid_is_active(pid, lwpid)) { 559*7c478bd9Sstevel@tonic-gate /* 560*7c478bd9Sstevel@tonic-gate * If we are reading cpu times for the first time then 561*7c478bd9Sstevel@tonic-gate * calculate average cpu times based on whole process 562*7c478bd9Sstevel@tonic-gate * execution time. 563*7c478bd9Sstevel@tonic-gate */ 564*7c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t)); 565*7c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime); 566*7c478bd9Sstevel@tonic-gate period = period/(float)100; 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */ 569*7c478bd9Sstevel@tonic-gate period = 1; 570*7c478bd9Sstevel@tonic-gate lwp->li_usr = 0; 571*7c478bd9Sstevel@tonic-gate lwp->li_sys = 0; 572*7c478bd9Sstevel@tonic-gate lwp->li_slp = 0; 573*7c478bd9Sstevel@tonic-gate } else { 574*7c478bd9Sstevel@tonic-gate lwp->li_usr = TIME2NSEC(usage->pr_utime)/period; 575*7c478bd9Sstevel@tonic-gate lwp->li_sys = TIME2NSEC(usage->pr_stime)/period; 576*7c478bd9Sstevel@tonic-gate lwp->li_slp = TIME2NSEC(usage->pr_slptime)/period; 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate lwp->li_trp = TIME2NSEC(usage->pr_ttime)/period; 579*7c478bd9Sstevel@tonic-gate lwp->li_tfl = TIME2NSEC(usage->pr_tftime)/period; 580*7c478bd9Sstevel@tonic-gate lwp->li_dfl = TIME2NSEC(usage->pr_dftime)/period; 581*7c478bd9Sstevel@tonic-gate lwp->li_lck = TIME2NSEC(usage->pr_ltime)/period; 582*7c478bd9Sstevel@tonic-gate lwp->li_lat = TIME2NSEC(usage->pr_wtime)/period; 583*7c478bd9Sstevel@tonic-gate period = (period / NANOSEC)*(float)100; /* now in seconds */ 584*7c478bd9Sstevel@tonic-gate lwp->li_vcx = (ulong_t) 585*7c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_vctx/period)); 586*7c478bd9Sstevel@tonic-gate lwp->li_icx = (ulong_t) 587*7c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_ictx/period)); 588*7c478bd9Sstevel@tonic-gate lwp->li_scl = (ulong_t) 589*7c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sysc/period)); 590*7c478bd9Sstevel@tonic-gate lwp->li_sig = (ulong_t) 591*7c478bd9Sstevel@tonic-gate (opts.o_interval * (usage->pr_sigs/period)); 592*7c478bd9Sstevel@tonic-gate (void) lwpid_set_active(pid, lwpid); 593*7c478bd9Sstevel@tonic-gate } else { 594*7c478bd9Sstevel@tonic-gate /* 595*7c478bd9Sstevel@tonic-gate * If this is not a first time we are reading a process's 596*7c478bd9Sstevel@tonic-gate * CPU times then recalculate CPU times based on fresh data 597*7c478bd9Sstevel@tonic-gate * obtained from procfs and previous CPU time usage values. 598*7c478bd9Sstevel@tonic-gate */ 599*7c478bd9Sstevel@tonic-gate period = TIME2NSEC(usage->pr_rtime)- 600*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_rtime); 601*7c478bd9Sstevel@tonic-gate period = period/(float)100; 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate if (period == 0) { /* zombie */ 604*7c478bd9Sstevel@tonic-gate period = 1; 605*7c478bd9Sstevel@tonic-gate lwp->li_usr = 0; 606*7c478bd9Sstevel@tonic-gate lwp->li_sys = 0; 607*7c478bd9Sstevel@tonic-gate lwp->li_slp = 0; 608*7c478bd9Sstevel@tonic-gate } else { 609*7c478bd9Sstevel@tonic-gate lwp->li_usr = (TIME2NSEC(usage->pr_utime)- 610*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_utime))/period; 611*7c478bd9Sstevel@tonic-gate lwp->li_sys = (TIME2NSEC(usage->pr_stime) - 612*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_stime))/period; 613*7c478bd9Sstevel@tonic-gate lwp->li_slp = (TIME2NSEC(usage->pr_slptime) - 614*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_slptime))/period; 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate lwp->li_trp = (TIME2NSEC(usage->pr_ttime) - 617*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ttime))/period; 618*7c478bd9Sstevel@tonic-gate lwp->li_tfl = (TIME2NSEC(usage->pr_tftime) - 619*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_tftime))/period; 620*7c478bd9Sstevel@tonic-gate lwp->li_dfl = (TIME2NSEC(usage->pr_dftime) - 621*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_dftime))/period; 622*7c478bd9Sstevel@tonic-gate lwp->li_lck = (TIME2NSEC(usage->pr_ltime) - 623*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_ltime))/period; 624*7c478bd9Sstevel@tonic-gate lwp->li_lat = (TIME2NSEC(usage->pr_wtime) - 625*7c478bd9Sstevel@tonic-gate TIME2NSEC(lwp->li_usage.pr_wtime))/period; 626*7c478bd9Sstevel@tonic-gate lwp->li_vcx = usage->pr_vctx - lwp->li_usage.pr_vctx; 627*7c478bd9Sstevel@tonic-gate lwp->li_icx = usage->pr_ictx - lwp->li_usage.pr_ictx; 628*7c478bd9Sstevel@tonic-gate lwp->li_scl = usage->pr_sysc - lwp->li_usage.pr_sysc; 629*7c478bd9Sstevel@tonic-gate lwp->li_sig = usage->pr_sigs - lwp->li_usage.pr_sigs; 630*7c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_usage, usage, sizeof (prusage_t)); 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate static int 635*7c478bd9Sstevel@tonic-gate read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize) 636*7c478bd9Sstevel@tonic-gate { 637*7c478bd9Sstevel@tonic-gate char procfile[MAX_PROCFS_PATH]; 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate (void) snprintf(procfile, MAX_PROCFS_PATH, 640*7c478bd9Sstevel@tonic-gate "/proc/%s/%s", pidstr, file); 641*7c478bd9Sstevel@tonic-gate if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL) 642*7c478bd9Sstevel@tonic-gate return (1); 643*7c478bd9Sstevel@tonic-gate if (pread(fd_getfd(*fd), buf, bufsize, 0) != bufsize) { 644*7c478bd9Sstevel@tonic-gate fd_close(*fd); 645*7c478bd9Sstevel@tonic-gate return (1); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate return (0); 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate static void 651*7c478bd9Sstevel@tonic-gate add_proc(psinfo_t *psinfo) 652*7c478bd9Sstevel@tonic-gate { 653*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 654*7c478bd9Sstevel@tonic-gate id_t lwpid; 655*7c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid; 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate lwpid = psinfo->pr_lwp.pr_lwpid; 658*7c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 659*7c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid); 660*7c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE | LWP_REPRESENT; 661*7c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo, sizeof (psinfo_t)); 662*7c478bd9Sstevel@tonic-gate lwp->li_info.pr_lwp.pr_pctcpu = lwp->li_info.pr_pctcpu; 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate static void 666*7c478bd9Sstevel@tonic-gate add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags) 667*7c478bd9Sstevel@tonic-gate { 668*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 669*7c478bd9Sstevel@tonic-gate pid_t pid = psinfo->pr_pid; 670*7c478bd9Sstevel@tonic-gate id_t lwpid = lwpsinfo->pr_lwpid; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 673*7c478bd9Sstevel@tonic-gate lwp = list_add_lwp(&lwps, pid, lwpid); 674*7c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_REPRESENT; 675*7c478bd9Sstevel@tonic-gate lwp->li_flags |= LWP_ALIVE; 676*7c478bd9Sstevel@tonic-gate lwp->li_flags |= flags; 677*7c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info, psinfo, 678*7c478bd9Sstevel@tonic-gate sizeof (psinfo_t) - sizeof (lwpsinfo_t)); 679*7c478bd9Sstevel@tonic-gate (void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t)); 680*7c478bd9Sstevel@tonic-gate } 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate static void 683*7c478bd9Sstevel@tonic-gate prstat_scandir(DIR *procdir) 684*7c478bd9Sstevel@tonic-gate { 685*7c478bd9Sstevel@tonic-gate char *pidstr; 686*7c478bd9Sstevel@tonic-gate pid_t pid; 687*7c478bd9Sstevel@tonic-gate id_t lwpid; 688*7c478bd9Sstevel@tonic-gate size_t entsz; 689*7c478bd9Sstevel@tonic-gate long nlwps, nent, i; 690*7c478bd9Sstevel@tonic-gate char *buf, *ptr; 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate fds_t *fds; 693*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp; 694*7c478bd9Sstevel@tonic-gate dirent_t *direntp; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate prheader_t header; 697*7c478bd9Sstevel@tonic-gate psinfo_t psinfo; 698*7c478bd9Sstevel@tonic-gate prusage_t usage; 699*7c478bd9Sstevel@tonic-gate lwpsinfo_t *lwpsinfo; 700*7c478bd9Sstevel@tonic-gate prusage_t *lwpusage; 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate total_procs = 0; 703*7c478bd9Sstevel@tonic-gate total_lwps = 0; 704*7c478bd9Sstevel@tonic-gate total_cpu = 0; 705*7c478bd9Sstevel@tonic-gate total_mem = 0; 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate convert_zone(&zone_tbl); 708*7c478bd9Sstevel@tonic-gate for (rewinddir(procdir); (direntp = readdir(procdir)); ) { 709*7c478bd9Sstevel@tonic-gate pidstr = direntp->d_name; 710*7c478bd9Sstevel@tonic-gate if (pidstr[0] == '.') /* skip "." and ".." */ 711*7c478bd9Sstevel@tonic-gate continue; 712*7c478bd9Sstevel@tonic-gate pid = atoi(pidstr); 713*7c478bd9Sstevel@tonic-gate if (pid == 0 || pid == 2 || pid == 3) 714*7c478bd9Sstevel@tonic-gate continue; /* skip sched, pageout and fsflush */ 715*7c478bd9Sstevel@tonic-gate if (has_element(&pid_tbl, pid) == 0) 716*7c478bd9Sstevel@tonic-gate continue; /* check if we really want this pid */ 717*7c478bd9Sstevel@tonic-gate fds = fds_get(pid); /* get ptr to file descriptors */ 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_psinfo, pidstr, 720*7c478bd9Sstevel@tonic-gate "psinfo", &psinfo, sizeof (psinfo_t)) != 0) 721*7c478bd9Sstevel@tonic-gate continue; 722*7c478bd9Sstevel@tonic-gate if (!has_uid(&ruid_tbl, psinfo.pr_uid) || 723*7c478bd9Sstevel@tonic-gate !has_uid(&euid_tbl, psinfo.pr_euid) || 724*7c478bd9Sstevel@tonic-gate !has_element(&prj_tbl, psinfo.pr_projid) || 725*7c478bd9Sstevel@tonic-gate !has_element(&tsk_tbl, psinfo.pr_taskid) || 726*7c478bd9Sstevel@tonic-gate !has_zone(&zone_tbl, psinfo.pr_zoneid)) { 727*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 728*7c478bd9Sstevel@tonic-gate continue; 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate nlwps = psinfo.pr_nlwp + psinfo.pr_nzomb; 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate if (nlwps > 1 && (opts.o_outpmode & (OPT_LWPS | OPT_PSETS))) { 733*7c478bd9Sstevel@tonic-gate int rep_lwp = 0; 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lpsinfo, pidstr, "lpsinfo", 736*7c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) { 737*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 738*7c478bd9Sstevel@tonic-gate continue; 739*7c478bd9Sstevel@tonic-gate } 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate nent = header.pr_nent; 742*7c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent; 743*7c478bd9Sstevel@tonic-gate ptr = buf = Malloc(entsz); 744*7c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lpsinfo), buf, 745*7c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) { 746*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 747*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 748*7c478bd9Sstevel@tonic-gate free(buf); 749*7c478bd9Sstevel@tonic-gate continue; 750*7c478bd9Sstevel@tonic-gate } 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate nlwps = 0; 753*7c478bd9Sstevel@tonic-gate for (i = 0; i < nent; i++, ptr += header.pr_entsize) { 754*7c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/ 755*7c478bd9Sstevel@tonic-gate lwpsinfo = (lwpsinfo_t *)ptr; 756*7c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl, 757*7c478bd9Sstevel@tonic-gate lwpsinfo->pr_onpro) || 758*7c478bd9Sstevel@tonic-gate !has_element(&set_tbl, 759*7c478bd9Sstevel@tonic-gate lwpsinfo->pr_bindpset)) 760*7c478bd9Sstevel@tonic-gate continue; 761*7c478bd9Sstevel@tonic-gate nlwps++; 762*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & (OPT_PSETS | OPT_LWPS)) 763*7c478bd9Sstevel@tonic-gate == OPT_PSETS) { 764*7c478bd9Sstevel@tonic-gate /* 765*7c478bd9Sstevel@tonic-gate * If one of process's LWPs is bound 766*7c478bd9Sstevel@tonic-gate * to a given processor set, report the 767*7c478bd9Sstevel@tonic-gate * whole process. We may be doing this 768*7c478bd9Sstevel@tonic-gate * a few times but we'll get an accurate 769*7c478bd9Sstevel@tonic-gate * lwp count in return. 770*7c478bd9Sstevel@tonic-gate */ 771*7c478bd9Sstevel@tonic-gate add_proc(&psinfo); 772*7c478bd9Sstevel@tonic-gate } else { 773*7c478bd9Sstevel@tonic-gate if (rep_lwp == 0) { 774*7c478bd9Sstevel@tonic-gate rep_lwp = 1; 775*7c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo, 776*7c478bd9Sstevel@tonic-gate LWP_REPRESENT); 777*7c478bd9Sstevel@tonic-gate } else { 778*7c478bd9Sstevel@tonic-gate add_lwp(&psinfo, lwpsinfo, 0); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate free(buf); 783*7c478bd9Sstevel@tonic-gate if (nlwps == 0) { 784*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 785*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 786*7c478bd9Sstevel@tonic-gate continue; 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate } else { 789*7c478bd9Sstevel@tonic-gate if (!has_element(&cpu_tbl, psinfo.pr_lwp.pr_onpro) || 790*7c478bd9Sstevel@tonic-gate !has_element(&set_tbl, psinfo.pr_lwp.pr_bindpset)) { 791*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 792*7c478bd9Sstevel@tonic-gate continue; 793*7c478bd9Sstevel@tonic-gate } 794*7c478bd9Sstevel@tonic-gate add_proc(&psinfo); 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_MSACCT)) { 797*7c478bd9Sstevel@tonic-gate total_procs++; 798*7c478bd9Sstevel@tonic-gate total_lwps += nlwps; 799*7c478bd9Sstevel@tonic-gate continue; 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate /* 802*7c478bd9Sstevel@tonic-gate * Get more information about processes from /proc/pid/usage. 803*7c478bd9Sstevel@tonic-gate * If process has more than one lwp, then we may have to 804*7c478bd9Sstevel@tonic-gate * also look at the /proc/pid/lusage file. 805*7c478bd9Sstevel@tonic-gate */ 806*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_LWPS) && (nlwps > 1)) { 807*7c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_lusage, pidstr, "lusage", 808*7c478bd9Sstevel@tonic-gate &header, sizeof (prheader_t)) != 0) { 809*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 810*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 811*7c478bd9Sstevel@tonic-gate continue; 812*7c478bd9Sstevel@tonic-gate } 813*7c478bd9Sstevel@tonic-gate nent = header.pr_nent; 814*7c478bd9Sstevel@tonic-gate entsz = header.pr_entsize * nent; 815*7c478bd9Sstevel@tonic-gate buf = Malloc(entsz); 816*7c478bd9Sstevel@tonic-gate if (pread(fd_getfd(fds->fds_lusage), buf, 817*7c478bd9Sstevel@tonic-gate entsz, sizeof (struct prheader)) != entsz) { 818*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lusage); 819*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 820*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 821*7c478bd9Sstevel@tonic-gate free(buf); 822*7c478bd9Sstevel@tonic-gate continue; 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate for (i = 1, ptr = buf + header.pr_entsize; i < nent; 825*7c478bd9Sstevel@tonic-gate i++, ptr += header.pr_entsize) { 826*7c478bd9Sstevel@tonic-gate /*LINTED ALIGNMENT*/ 827*7c478bd9Sstevel@tonic-gate lwpusage = (prusage_t *)ptr; 828*7c478bd9Sstevel@tonic-gate lwpid = lwpusage->pr_lwpid; 829*7c478bd9Sstevel@tonic-gate /* 830*7c478bd9Sstevel@tonic-gate * New LWPs created after we read lpsinfo 831*7c478bd9Sstevel@tonic-gate * will be ignored. Don't want to do 832*7c478bd9Sstevel@tonic-gate * everything all over again. 833*7c478bd9Sstevel@tonic-gate */ 834*7c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 835*7c478bd9Sstevel@tonic-gate continue; 836*7c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, lwpusage); 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate free(buf); 839*7c478bd9Sstevel@tonic-gate } else { 840*7c478bd9Sstevel@tonic-gate if (read_procfile(&fds->fds_usage, pidstr, "usage", 841*7c478bd9Sstevel@tonic-gate &usage, sizeof (prusage_t)) != 0) { 842*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_lpsinfo); 843*7c478bd9Sstevel@tonic-gate fd_close(fds->fds_psinfo); 844*7c478bd9Sstevel@tonic-gate continue; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate lwpid = psinfo.pr_lwp.pr_lwpid; 847*7c478bd9Sstevel@tonic-gate if ((lwp = lwpid_get(pid, lwpid)) == NULL) 848*7c478bd9Sstevel@tonic-gate continue; 849*7c478bd9Sstevel@tonic-gate lwp_update(lwp, pid, lwpid, &usage); 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate total_procs++; 852*7c478bd9Sstevel@tonic-gate total_lwps += nlwps; 853*7c478bd9Sstevel@tonic-gate } 854*7c478bd9Sstevel@tonic-gate fd_update(); 855*7c478bd9Sstevel@tonic-gate } 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate /* 858*7c478bd9Sstevel@tonic-gate * This procedure removes all dead lwps from the linked list of all lwps. 859*7c478bd9Sstevel@tonic-gate * It also creates linked list of ids if necessary. 860*7c478bd9Sstevel@tonic-gate */ 861*7c478bd9Sstevel@tonic-gate static void 862*7c478bd9Sstevel@tonic-gate list_refresh(list_t *list) 863*7c478bd9Sstevel@tonic-gate { 864*7c478bd9Sstevel@tonic-gate lwp_info_t *lwp, *lwp_next; 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate if (!(list->l_type & LT_LWPS)) 867*7c478bd9Sstevel@tonic-gate return; 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate for (lwp = list->l_head; lwp != NULL; ) { 870*7c478bd9Sstevel@tonic-gate if (lwp->li_flags & LWP_ALIVE) { 871*7c478bd9Sstevel@tonic-gate /* 872*7c478bd9Sstevel@tonic-gate * Process all live LWPs. 873*7c478bd9Sstevel@tonic-gate * When we're done, mark them as dead. 874*7c478bd9Sstevel@tonic-gate * They will be marked "alive" on the next 875*7c478bd9Sstevel@tonic-gate * /proc scan if they still exist. 876*7c478bd9Sstevel@tonic-gate */ 877*7c478bd9Sstevel@tonic-gate lwp->li_key = list_getkeyval(list, lwp); 878*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 879*7c478bd9Sstevel@tonic-gate list_update(&users, lwp); 880*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS) 881*7c478bd9Sstevel@tonic-gate list_update(&tasks, lwp); 882*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS) 883*7c478bd9Sstevel@tonic-gate list_update(&projects, lwp); 884*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES) 885*7c478bd9Sstevel@tonic-gate list_update(&zones, lwp); 886*7c478bd9Sstevel@tonic-gate lwp->li_flags &= ~LWP_ALIVE; 887*7c478bd9Sstevel@tonic-gate lwp = lwp->li_next; 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate } else { 890*7c478bd9Sstevel@tonic-gate lwp_next = lwp->li_next; 891*7c478bd9Sstevel@tonic-gate list_remove_lwp(&lwps, lwp); 892*7c478bd9Sstevel@tonic-gate lwp = lwp_next; 893*7c478bd9Sstevel@tonic-gate } 894*7c478bd9Sstevel@tonic-gate } 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate static void 898*7c478bd9Sstevel@tonic-gate curses_on() 899*7c478bd9Sstevel@tonic-gate { 900*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) { 901*7c478bd9Sstevel@tonic-gate (void) initscr(); 902*7c478bd9Sstevel@tonic-gate (void) nonl(); 903*7c478bd9Sstevel@tonic-gate (void) putp(t_smcup); 904*7c478bd9Sstevel@tonic-gate is_curses_on = TRUE; 905*7c478bd9Sstevel@tonic-gate } 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate static void 909*7c478bd9Sstevel@tonic-gate curses_off() 910*7c478bd9Sstevel@tonic-gate { 911*7c478bd9Sstevel@tonic-gate if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) { 912*7c478bd9Sstevel@tonic-gate (void) putp(t_rmcup); 913*7c478bd9Sstevel@tonic-gate (void) endwin(); 914*7c478bd9Sstevel@tonic-gate is_curses_on = FALSE; 915*7c478bd9Sstevel@tonic-gate } 916*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate 919*7c478bd9Sstevel@tonic-gate static int 920*7c478bd9Sstevel@tonic-gate nlines() 921*7c478bd9Sstevel@tonic-gate { 922*7c478bd9Sstevel@tonic-gate struct winsize ws; 923*7c478bd9Sstevel@tonic-gate char *envp; 924*7c478bd9Sstevel@tonic-gate int n; 925*7c478bd9Sstevel@tonic-gate if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) { 926*7c478bd9Sstevel@tonic-gate if (ws.ws_row > 0) 927*7c478bd9Sstevel@tonic-gate return (ws.ws_row); 928*7c478bd9Sstevel@tonic-gate } 929*7c478bd9Sstevel@tonic-gate if (envp = getenv("LINES")) { 930*7c478bd9Sstevel@tonic-gate if ((n = Atoi(envp)) > 0) { 931*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 932*7c478bd9Sstevel@tonic-gate return (n); 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate } 935*7c478bd9Sstevel@tonic-gate return (-1); 936*7c478bd9Sstevel@tonic-gate } 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate static void 939*7c478bd9Sstevel@tonic-gate setmovecur() 940*7c478bd9Sstevel@tonic-gate { 941*7c478bd9Sstevel@tonic-gate int i, n; 942*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_FULLSCREEN) && 943*7c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_USEHOME)) { 944*7c478bd9Sstevel@tonic-gate movecur = t_home; 945*7c478bd9Sstevel@tonic-gate return; 946*7c478bd9Sstevel@tonic-gate } 947*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) { 948*7c478bd9Sstevel@tonic-gate n = opts.o_ntop + opts.o_nbottom + 2; 949*7c478bd9Sstevel@tonic-gate } else { 950*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 951*7c478bd9Sstevel@tonic-gate n = opts.o_nbottom + 1; 952*7c478bd9Sstevel@tonic-gate else 953*7c478bd9Sstevel@tonic-gate n = opts.o_ntop + 1; 954*7c478bd9Sstevel@tonic-gate } 955*7c478bd9Sstevel@tonic-gate if (movecur != NULL && movecur != empty_string && movecur != t_home) 956*7c478bd9Sstevel@tonic-gate free(movecur); 957*7c478bd9Sstevel@tonic-gate movecur = Zalloc(strlen(t_up) * (n + 5)); 958*7c478bd9Sstevel@tonic-gate for (i = 0; i <= n; i++) 959*7c478bd9Sstevel@tonic-gate (void) strcat(movecur, t_up); 960*7c478bd9Sstevel@tonic-gate } 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate static int 963*7c478bd9Sstevel@tonic-gate setsize() 964*7c478bd9Sstevel@tonic-gate { 965*7c478bd9Sstevel@tonic-gate static int oldn = 0; 966*7c478bd9Sstevel@tonic-gate int n; 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) { 969*7c478bd9Sstevel@tonic-gate n = nlines(); 970*7c478bd9Sstevel@tonic-gate if (n == oldn) 971*7c478bd9Sstevel@tonic-gate return (0); 972*7c478bd9Sstevel@tonic-gate oldn = n; 973*7c478bd9Sstevel@tonic-gate if (n == -1) { 974*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 975*7c478bd9Sstevel@tonic-gate setmovecur(); /* set default window size */ 976*7c478bd9Sstevel@tonic-gate return (1); 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate n = n - 3; /* minus header, total and cursor lines */ 979*7c478bd9Sstevel@tonic-gate if (n < 1) 980*7c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n")); 981*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_SPLIT) { 982*7c478bd9Sstevel@tonic-gate if (n < 8) { 983*7c478bd9Sstevel@tonic-gate Die(gettext("window is too small (try -n)\n")); 984*7c478bd9Sstevel@tonic-gate } else { 985*7c478bd9Sstevel@tonic-gate opts.o_ntop = (n / 4) * 3; 986*7c478bd9Sstevel@tonic-gate opts.o_nbottom = n - 1 - opts.o_ntop; 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate } else { 989*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) 990*7c478bd9Sstevel@tonic-gate opts.o_nbottom = n; 991*7c478bd9Sstevel@tonic-gate else 992*7c478bd9Sstevel@tonic-gate opts.o_ntop = n; 993*7c478bd9Sstevel@tonic-gate } 994*7c478bd9Sstevel@tonic-gate } 995*7c478bd9Sstevel@tonic-gate setmovecur(); 996*7c478bd9Sstevel@tonic-gate return (1); 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate static void 1000*7c478bd9Sstevel@tonic-gate ldtermcap() 1001*7c478bd9Sstevel@tonic-gate { 1002*7c478bd9Sstevel@tonic-gate int err; 1003*7c478bd9Sstevel@tonic-gate if (setupterm(NULL, STDIN_FILENO, &err) == ERR) { 1004*7c478bd9Sstevel@tonic-gate switch (err) { 1005*7c478bd9Sstevel@tonic-gate case 0: 1006*7c478bd9Sstevel@tonic-gate Warn(gettext("failed to load terminal info, " 1007*7c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 1008*7c478bd9Sstevel@tonic-gate break; 1009*7c478bd9Sstevel@tonic-gate case -1: 1010*7c478bd9Sstevel@tonic-gate Warn(gettext("terminfo database not found, " 1011*7c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 1012*7c478bd9Sstevel@tonic-gate break; 1013*7c478bd9Sstevel@tonic-gate default: 1014*7c478bd9Sstevel@tonic-gate Warn(gettext("failed to initialize terminal, " 1015*7c478bd9Sstevel@tonic-gate "defaulting to -c option\n")); 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 1018*7c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string; 1019*7c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string; 1020*7c478bd9Sstevel@tonic-gate return; 1021*7c478bd9Sstevel@tonic-gate } 1022*7c478bd9Sstevel@tonic-gate t_ulon = tigetstr("smul"); 1023*7c478bd9Sstevel@tonic-gate t_uloff = tigetstr("rmul"); 1024*7c478bd9Sstevel@tonic-gate t_up = tigetstr("cuu1"); 1025*7c478bd9Sstevel@tonic-gate t_eol = tigetstr("el"); 1026*7c478bd9Sstevel@tonic-gate t_smcup = tigetstr("smcup"); 1027*7c478bd9Sstevel@tonic-gate t_rmcup = tigetstr("rmcup"); 1028*7c478bd9Sstevel@tonic-gate t_home = tigetstr("home"); 1029*7c478bd9Sstevel@tonic-gate if ((t_up == (char *)-1) || (t_eol == (char *)-1) || 1030*7c478bd9Sstevel@tonic-gate (t_smcup == (char *)-1) || (t_rmcup == (char *)-1)) { 1031*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 1032*7c478bd9Sstevel@tonic-gate t_up = t_eol = t_smcup = t_rmcup = movecur = empty_string; 1033*7c478bd9Sstevel@tonic-gate return; 1034*7c478bd9Sstevel@tonic-gate } 1035*7c478bd9Sstevel@tonic-gate if (t_up == NULL || t_eol == NULL) { 1036*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 1037*7c478bd9Sstevel@tonic-gate t_eol = t_up = movecur = empty_string; 1038*7c478bd9Sstevel@tonic-gate return; 1039*7c478bd9Sstevel@tonic-gate } 1040*7c478bd9Sstevel@tonic-gate if (t_ulon == (char *)-1 || t_uloff == (char *)-1 || 1041*7c478bd9Sstevel@tonic-gate t_ulon == NULL || t_uloff == NULL) { 1042*7c478bd9Sstevel@tonic-gate t_ulon = t_uloff = empty_string; /* can live without it */ 1043*7c478bd9Sstevel@tonic-gate } 1044*7c478bd9Sstevel@tonic-gate if (t_smcup == NULL || t_rmcup == NULL) 1045*7c478bd9Sstevel@tonic-gate t_smcup = t_rmcup = empty_string; 1046*7c478bd9Sstevel@tonic-gate if (t_home == (char *)-1 || t_home == NULL) { 1047*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_USEHOME; 1048*7c478bd9Sstevel@tonic-gate t_home = empty_string; 1049*7c478bd9Sstevel@tonic-gate } 1050*7c478bd9Sstevel@tonic-gate } 1051*7c478bd9Sstevel@tonic-gate 1052*7c478bd9Sstevel@tonic-gate static void 1053*7c478bd9Sstevel@tonic-gate sig_handler(int sig) 1054*7c478bd9Sstevel@tonic-gate { 1055*7c478bd9Sstevel@tonic-gate switch (sig) { 1056*7c478bd9Sstevel@tonic-gate case SIGTSTP: sigtstp = 1; 1057*7c478bd9Sstevel@tonic-gate break; 1058*7c478bd9Sstevel@tonic-gate case SIGWINCH: sigwinch = 1; 1059*7c478bd9Sstevel@tonic-gate break; 1060*7c478bd9Sstevel@tonic-gate case SIGINT: 1061*7c478bd9Sstevel@tonic-gate case SIGTERM: sigterm = 1; 1062*7c478bd9Sstevel@tonic-gate break; 1063*7c478bd9Sstevel@tonic-gate } 1064*7c478bd9Sstevel@tonic-gate } 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate static void 1067*7c478bd9Sstevel@tonic-gate set_signals() 1068*7c478bd9Sstevel@tonic-gate { 1069*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler); 1070*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sig_handler); 1071*7c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, sig_handler); 1072*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) 1073*7c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler); 1074*7c478bd9Sstevel@tonic-gate } 1075*7c478bd9Sstevel@tonic-gate 1076*7c478bd9Sstevel@tonic-gate static void 1077*7c478bd9Sstevel@tonic-gate fill_table(table_t *table, char *arg) 1078*7c478bd9Sstevel@tonic-gate { 1079*7c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 1080*7c478bd9Sstevel@tonic-gate long l = Atoi(p); 1081*7c478bd9Sstevel@tonic-gate 1082*7c478bd9Sstevel@tonic-gate add_element(table, l); 1083*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) { 1084*7c478bd9Sstevel@tonic-gate l = Atoi(p); 1085*7c478bd9Sstevel@tonic-gate add_element(table, l); 1086*7c478bd9Sstevel@tonic-gate } 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate 1089*7c478bd9Sstevel@tonic-gate static void 1090*7c478bd9Sstevel@tonic-gate fill_prj_table(char *arg) 1091*7c478bd9Sstevel@tonic-gate { 1092*7c478bd9Sstevel@tonic-gate projid_t projid; 1093*7c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 1094*7c478bd9Sstevel@tonic-gate 1095*7c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1) 1096*7c478bd9Sstevel@tonic-gate projid = Atoi(p); 1097*7c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid); 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) { 1100*7c478bd9Sstevel@tonic-gate if ((projid = getprojidbyname(p)) == -1) 1101*7c478bd9Sstevel@tonic-gate projid = Atoi(p); 1102*7c478bd9Sstevel@tonic-gate add_element(&prj_tbl, (long)projid); 1103*7c478bd9Sstevel@tonic-gate } 1104*7c478bd9Sstevel@tonic-gate } 1105*7c478bd9Sstevel@tonic-gate 1106*7c478bd9Sstevel@tonic-gate static void 1107*7c478bd9Sstevel@tonic-gate fill_set_table(char *arg) 1108*7c478bd9Sstevel@tonic-gate { 1109*7c478bd9Sstevel@tonic-gate char *p = strtok(arg, ", "); 1110*7c478bd9Sstevel@tonic-gate psetid_t id; 1111*7c478bd9Sstevel@tonic-gate 1112*7c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0) 1113*7c478bd9Sstevel@tonic-gate id = PS_NONE; 1114*7c478bd9Sstevel@tonic-gate add_element(&set_tbl, id); 1115*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) { 1116*7c478bd9Sstevel@tonic-gate if ((id = Atoi(p)) == 0) 1117*7c478bd9Sstevel@tonic-gate id = PS_NONE; 1118*7c478bd9Sstevel@tonic-gate if (!has_element(&set_tbl, id)) 1119*7c478bd9Sstevel@tonic-gate add_element(&set_tbl, id); 1120*7c478bd9Sstevel@tonic-gate } 1121*7c478bd9Sstevel@tonic-gate } 1122*7c478bd9Sstevel@tonic-gate 1123*7c478bd9Sstevel@tonic-gate static void 1124*7c478bd9Sstevel@tonic-gate Exit() 1125*7c478bd9Sstevel@tonic-gate { 1126*7c478bd9Sstevel@tonic-gate curses_off(); 1127*7c478bd9Sstevel@tonic-gate list_clear(&lwps); 1128*7c478bd9Sstevel@tonic-gate list_clear(&users); 1129*7c478bd9Sstevel@tonic-gate list_clear(&tasks); 1130*7c478bd9Sstevel@tonic-gate list_clear(&projects); 1131*7c478bd9Sstevel@tonic-gate list_clear(&zones); 1132*7c478bd9Sstevel@tonic-gate fd_exit(); 1133*7c478bd9Sstevel@tonic-gate } 1134*7c478bd9Sstevel@tonic-gate 1135*7c478bd9Sstevel@tonic-gate int 1136*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 1137*7c478bd9Sstevel@tonic-gate { 1138*7c478bd9Sstevel@tonic-gate DIR *procdir; 1139*7c478bd9Sstevel@tonic-gate char *p; 1140*7c478bd9Sstevel@tonic-gate char *sortk = "cpu"; /* default sort key */ 1141*7c478bd9Sstevel@tonic-gate int opt; 1142*7c478bd9Sstevel@tonic-gate int timeout; 1143*7c478bd9Sstevel@tonic-gate struct pollfd pollset; 1144*7c478bd9Sstevel@tonic-gate char key; 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1147*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1148*7c478bd9Sstevel@tonic-gate Progname(argv[0]); 1149*7c478bd9Sstevel@tonic-gate lwpid_init(); 1150*7c478bd9Sstevel@tonic-gate fd_init(Setrlimit()); 1151*7c478bd9Sstevel@tonic-gate 1152*7c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, "vcmaRLtu:U:n:p:C:P:s:S:j:k:TJz:Z")) 1153*7c478bd9Sstevel@tonic-gate != (int)EOF) { 1154*7c478bd9Sstevel@tonic-gate switch (opt) { 1155*7c478bd9Sstevel@tonic-gate case 'R': 1156*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_REALTIME; 1157*7c478bd9Sstevel@tonic-gate break; 1158*7c478bd9Sstevel@tonic-gate case 'c': 1159*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; 1160*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 1161*7c478bd9Sstevel@tonic-gate break; 1162*7c478bd9Sstevel@tonic-gate case 'm': 1163*7c478bd9Sstevel@tonic-gate case 'v': 1164*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO; 1165*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_MSACCT; 1166*7c478bd9Sstevel@tonic-gate break; 1167*7c478bd9Sstevel@tonic-gate case 't': 1168*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_PSINFO; 1169*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_USERS; 1170*7c478bd9Sstevel@tonic-gate break; 1171*7c478bd9Sstevel@tonic-gate case 'a': 1172*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_USERS; 1173*7c478bd9Sstevel@tonic-gate break; 1174*7c478bd9Sstevel@tonic-gate case 'T': 1175*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_TASKS; 1176*7c478bd9Sstevel@tonic-gate break; 1177*7c478bd9Sstevel@tonic-gate case 'J': 1178*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_PROJECTS; 1179*7c478bd9Sstevel@tonic-gate break; 1180*7c478bd9Sstevel@tonic-gate case 'n': 1181*7c478bd9Sstevel@tonic-gate p = strtok(optarg, ","); 1182*7c478bd9Sstevel@tonic-gate opts.o_ntop = Atoi(p); 1183*7c478bd9Sstevel@tonic-gate if (p = strtok(NULL, ",")) 1184*7c478bd9Sstevel@tonic-gate opts.o_nbottom = Atoi(p); 1185*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 1186*7c478bd9Sstevel@tonic-gate break; 1187*7c478bd9Sstevel@tonic-gate case 's': 1188*7c478bd9Sstevel@tonic-gate opts.o_sortorder = -1; 1189*7c478bd9Sstevel@tonic-gate sortk = optarg; 1190*7c478bd9Sstevel@tonic-gate break; 1191*7c478bd9Sstevel@tonic-gate case 'S': 1192*7c478bd9Sstevel@tonic-gate opts.o_sortorder = 1; 1193*7c478bd9Sstevel@tonic-gate sortk = optarg; 1194*7c478bd9Sstevel@tonic-gate break; 1195*7c478bd9Sstevel@tonic-gate case 'u': 1196*7c478bd9Sstevel@tonic-gate p = strtok(optarg, ", "); 1197*7c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p); 1198*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 1199*7c478bd9Sstevel@tonic-gate add_uid(&euid_tbl, p); 1200*7c478bd9Sstevel@tonic-gate break; 1201*7c478bd9Sstevel@tonic-gate case 'U': 1202*7c478bd9Sstevel@tonic-gate p = strtok(optarg, ", "); 1203*7c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p); 1204*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 1205*7c478bd9Sstevel@tonic-gate add_uid(&ruid_tbl, p); 1206*7c478bd9Sstevel@tonic-gate break; 1207*7c478bd9Sstevel@tonic-gate case 'p': 1208*7c478bd9Sstevel@tonic-gate fill_table(&pid_tbl, optarg); 1209*7c478bd9Sstevel@tonic-gate break; 1210*7c478bd9Sstevel@tonic-gate case 'C': 1211*7c478bd9Sstevel@tonic-gate fill_set_table(optarg); 1212*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_PSETS; 1213*7c478bd9Sstevel@tonic-gate break; 1214*7c478bd9Sstevel@tonic-gate case 'P': 1215*7c478bd9Sstevel@tonic-gate fill_table(&cpu_tbl, optarg); 1216*7c478bd9Sstevel@tonic-gate break; 1217*7c478bd9Sstevel@tonic-gate case 'k': 1218*7c478bd9Sstevel@tonic-gate fill_table(&tsk_tbl, optarg); 1219*7c478bd9Sstevel@tonic-gate break; 1220*7c478bd9Sstevel@tonic-gate case 'j': 1221*7c478bd9Sstevel@tonic-gate fill_prj_table(optarg); 1222*7c478bd9Sstevel@tonic-gate break; 1223*7c478bd9Sstevel@tonic-gate case 'L': 1224*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_LWPS; 1225*7c478bd9Sstevel@tonic-gate break; 1226*7c478bd9Sstevel@tonic-gate case 'z': 1227*7c478bd9Sstevel@tonic-gate p = strtok(optarg, ", "); 1228*7c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p); 1229*7c478bd9Sstevel@tonic-gate while (p = strtok(NULL, ", ")) 1230*7c478bd9Sstevel@tonic-gate add_zone(&zone_tbl, p); 1231*7c478bd9Sstevel@tonic-gate break; 1232*7c478bd9Sstevel@tonic-gate case 'Z': 1233*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_SPLIT | OPT_ZONES; 1234*7c478bd9Sstevel@tonic-gate break; 1235*7c478bd9Sstevel@tonic-gate default: 1236*7c478bd9Sstevel@tonic-gate Usage(); 1237*7c478bd9Sstevel@tonic-gate } 1238*7c478bd9Sstevel@tonic-gate } 1239*7c478bd9Sstevel@tonic-gate 1240*7c478bd9Sstevel@tonic-gate (void) atexit(Exit); 1241*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) && 1242*7c478bd9Sstevel@tonic-gate !(opts.o_outpmode & OPT_SPLIT)) 1243*7c478bd9Sstevel@tonic-gate opts.o_nbottom = opts.o_ntop; 1244*7c478bd9Sstevel@tonic-gate if (opts.o_ntop == 0 || opts.o_nbottom == 0) 1245*7c478bd9Sstevel@tonic-gate Die(gettext("invalid argument for -n\n")); 1246*7c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) && 1247*7c478bd9Sstevel@tonic-gate ((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT)))) 1248*7c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with -v or -m\n")); 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode && OPT_USERS) && 1251*7c478bd9Sstevel@tonic-gate !((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT)))) 1252*7c478bd9Sstevel@tonic-gate Die(gettext("-t option cannot be used with " 1253*7c478bd9Sstevel@tonic-gate "-a, -J, -T or -Z\n")); 1254*7c478bd9Sstevel@tonic-gate 1255*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_USERS) && 1256*7c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_TASKS | OPT_PROJECTS | OPT_ZONES))) 1257*7c478bd9Sstevel@tonic-gate Die(gettext("-a option cannot be used with " 1258*7c478bd9Sstevel@tonic-gate "-t, -J, -T or -Z\n")); 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate if (((opts.o_outpmode & OPT_TASKS) && 1261*7c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_PROJECTS|OPT_ZONES))) || 1262*7c478bd9Sstevel@tonic-gate ((opts.o_outpmode & OPT_PROJECTS) && 1263*7c478bd9Sstevel@tonic-gate (opts.o_outpmode & (OPT_TASKS|OPT_ZONES)))) { 1264*7c478bd9Sstevel@tonic-gate Die(gettext("-J, -T and -Z options are mutually exclusive\n")); 1265*7c478bd9Sstevel@tonic-gate } 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate if (argc > optind) 1268*7c478bd9Sstevel@tonic-gate opts.o_interval = Atoi(argv[optind++]); 1269*7c478bd9Sstevel@tonic-gate if (argc > optind) 1270*7c478bd9Sstevel@tonic-gate opts.o_count = Atoi(argv[optind++]); 1271*7c478bd9Sstevel@tonic-gate if (opts.o_count == 0) 1272*7c478bd9Sstevel@tonic-gate Die(gettext("invalid counter value\n")); 1273*7c478bd9Sstevel@tonic-gate if (argc > optind) 1274*7c478bd9Sstevel@tonic-gate Usage(); 1275*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_REALTIME) 1276*7c478bd9Sstevel@tonic-gate Priocntl("RT"); 1277*7c478bd9Sstevel@tonic-gate if (isatty(STDOUT_FILENO) == 1 && isatty(STDIN_FILENO)) 1278*7c478bd9Sstevel@tonic-gate opts.o_outpmode |= OPT_TTY; /* interactive */ 1279*7c478bd9Sstevel@tonic-gate if (!(opts.o_outpmode & OPT_TTY)) { 1280*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_TERMCAP; /* no termcap for pipes */ 1281*7c478bd9Sstevel@tonic-gate opts.o_outpmode &= ~OPT_FULLSCREEN; 1282*7c478bd9Sstevel@tonic-gate } 1283*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 1284*7c478bd9Sstevel@tonic-gate ldtermcap(); /* can turn OPT_TERMCAP off */ 1285*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 1286*7c478bd9Sstevel@tonic-gate (void) setsize(); 1287*7c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop); 1288*7c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom); 1289*7c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom); 1290*7c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom); 1291*7c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom); 1292*7c478bd9Sstevel@tonic-gate list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS); 1293*7c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &users, LT_USERS); 1294*7c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS); 1295*7c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS); 1296*7c478bd9Sstevel@tonic-gate list_setkeyfunc(NULL, &opts, &zones, LT_ZONES); 1297*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TERMCAP) 1298*7c478bd9Sstevel@tonic-gate curses_on(); 1299*7c478bd9Sstevel@tonic-gate if ((procdir = opendir("/proc")) == NULL) 1300*7c478bd9Sstevel@tonic-gate Die(gettext("cannot open /proc directory\n")); 1301*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) { 1302*7c478bd9Sstevel@tonic-gate (void) printf(gettext("Please wait...\r")); 1303*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1304*7c478bd9Sstevel@tonic-gate } 1305*7c478bd9Sstevel@tonic-gate set_signals(); 1306*7c478bd9Sstevel@tonic-gate pollset.fd = STDIN_FILENO; 1307*7c478bd9Sstevel@tonic-gate pollset.events = POLLIN; 1308*7c478bd9Sstevel@tonic-gate timeout = opts.o_interval * MILLISEC; 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate /* 1311*7c478bd9Sstevel@tonic-gate * main program loop 1312*7c478bd9Sstevel@tonic-gate */ 1313*7c478bd9Sstevel@tonic-gate do { 1314*7c478bd9Sstevel@tonic-gate if (sigterm == 1) 1315*7c478bd9Sstevel@tonic-gate break; 1316*7c478bd9Sstevel@tonic-gate if (sigtstp == 1) { 1317*7c478bd9Sstevel@tonic-gate curses_off(); 1318*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, SIG_DFL); 1319*7c478bd9Sstevel@tonic-gate (void) kill(0, SIGTSTP); 1320*7c478bd9Sstevel@tonic-gate /* 1321*7c478bd9Sstevel@tonic-gate * prstat stops here until it receives SIGCONT signal. 1322*7c478bd9Sstevel@tonic-gate */ 1323*7c478bd9Sstevel@tonic-gate sigtstp = 0; 1324*7c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, sig_handler); 1325*7c478bd9Sstevel@tonic-gate curses_on(); 1326*7c478bd9Sstevel@tonic-gate print_movecur = FALSE; 1327*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_FULLSCREEN) 1328*7c478bd9Sstevel@tonic-gate sigwinch = 1; 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate if (sigwinch == 1) { 1331*7c478bd9Sstevel@tonic-gate if (setsize() == 1) { 1332*7c478bd9Sstevel@tonic-gate list_free(&lwps); 1333*7c478bd9Sstevel@tonic-gate list_free(&users); 1334*7c478bd9Sstevel@tonic-gate list_free(&tasks); 1335*7c478bd9Sstevel@tonic-gate list_free(&projects); 1336*7c478bd9Sstevel@tonic-gate list_free(&zones); 1337*7c478bd9Sstevel@tonic-gate list_alloc(&lwps, opts.o_ntop); 1338*7c478bd9Sstevel@tonic-gate list_alloc(&users, opts.o_nbottom); 1339*7c478bd9Sstevel@tonic-gate list_alloc(&tasks, opts.o_nbottom); 1340*7c478bd9Sstevel@tonic-gate list_alloc(&projects, opts.o_nbottom); 1341*7c478bd9Sstevel@tonic-gate list_alloc(&zones, opts.o_nbottom); 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate sigwinch = 0; 1344*7c478bd9Sstevel@tonic-gate (void) signal(SIGWINCH, sig_handler); 1345*7c478bd9Sstevel@tonic-gate } 1346*7c478bd9Sstevel@tonic-gate prstat_scandir(procdir); 1347*7c478bd9Sstevel@tonic-gate list_refresh(&lwps); 1348*7c478bd9Sstevel@tonic-gate if (print_movecur) 1349*7c478bd9Sstevel@tonic-gate (void) putp(movecur); 1350*7c478bd9Sstevel@tonic-gate print_movecur = TRUE; 1351*7c478bd9Sstevel@tonic-gate if ((opts.o_outpmode & OPT_PSINFO) || 1352*7c478bd9Sstevel@tonic-gate (opts.o_outpmode & OPT_MSACCT)) { 1353*7c478bd9Sstevel@tonic-gate list_sort(&lwps); 1354*7c478bd9Sstevel@tonic-gate list_print(&lwps); 1355*7c478bd9Sstevel@tonic-gate } 1356*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_USERS) { 1357*7c478bd9Sstevel@tonic-gate list_sort(&users); 1358*7c478bd9Sstevel@tonic-gate list_print(&users); 1359*7c478bd9Sstevel@tonic-gate list_clear(&users); 1360*7c478bd9Sstevel@tonic-gate } 1361*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TASKS) { 1362*7c478bd9Sstevel@tonic-gate list_sort(&tasks); 1363*7c478bd9Sstevel@tonic-gate list_print(&tasks); 1364*7c478bd9Sstevel@tonic-gate list_clear(&tasks); 1365*7c478bd9Sstevel@tonic-gate } 1366*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_PROJECTS) { 1367*7c478bd9Sstevel@tonic-gate list_sort(&projects); 1368*7c478bd9Sstevel@tonic-gate list_print(&projects); 1369*7c478bd9Sstevel@tonic-gate list_clear(&projects); 1370*7c478bd9Sstevel@tonic-gate } 1371*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_ZONES) { 1372*7c478bd9Sstevel@tonic-gate list_sort(&zones); 1373*7c478bd9Sstevel@tonic-gate list_print(&zones); 1374*7c478bd9Sstevel@tonic-gate list_clear(&zones); 1375*7c478bd9Sstevel@tonic-gate } 1376*7c478bd9Sstevel@tonic-gate if (opts.o_count == 1) 1377*7c478bd9Sstevel@tonic-gate break; 1378*7c478bd9Sstevel@tonic-gate /* 1379*7c478bd9Sstevel@tonic-gate * If poll() returns -1 and sets errno to EINTR here because 1380*7c478bd9Sstevel@tonic-gate * the process received a signal, it is Ok to abort this 1381*7c478bd9Sstevel@tonic-gate * timeout and loop around because we check the signals at the 1382*7c478bd9Sstevel@tonic-gate * top of the loop. 1383*7c478bd9Sstevel@tonic-gate */ 1384*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) { 1385*7c478bd9Sstevel@tonic-gate if (poll(&pollset, (nfds_t)1, timeout) > 0) { 1386*7c478bd9Sstevel@tonic-gate if (read(STDIN_FILENO, &key, 1) == 1) { 1387*7c478bd9Sstevel@tonic-gate if (tolower(key) == 'q') 1388*7c478bd9Sstevel@tonic-gate break; 1389*7c478bd9Sstevel@tonic-gate } 1390*7c478bd9Sstevel@tonic-gate } 1391*7c478bd9Sstevel@tonic-gate } else { 1392*7c478bd9Sstevel@tonic-gate (void) sleep(opts.o_interval); 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate } while (opts.o_count == (-1) || --opts.o_count); 1395*7c478bd9Sstevel@tonic-gate 1396*7c478bd9Sstevel@tonic-gate if (opts.o_outpmode & OPT_TTY) 1397*7c478bd9Sstevel@tonic-gate (void) putchar('\r'); 1398*7c478bd9Sstevel@tonic-gate return (0); 1399*7c478bd9Sstevel@tonic-gate } 1400