xref: /minix3/external/bsd/top/dist/machine/m_svr4.c (revision b89261ba018da33f0bd8cd05f5a1fe9e7a9c837b)
1*b89261baSDavid van Moolenbroek /*
2*b89261baSDavid van Moolenbroek  * Copyright (c) 1984 through 2008, William LeFebvre
3*b89261baSDavid van Moolenbroek  * All rights reserved.
4*b89261baSDavid van Moolenbroek  *
5*b89261baSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b89261baSDavid van Moolenbroek  * modification, are permitted provided that the following conditions are met:
7*b89261baSDavid van Moolenbroek  *
8*b89261baSDavid van Moolenbroek  *     * Redistributions of source code must retain the above copyright
9*b89261baSDavid van Moolenbroek  * notice, this list of conditions and the following disclaimer.
10*b89261baSDavid van Moolenbroek  *
11*b89261baSDavid van Moolenbroek  *     * Redistributions in binary form must reproduce the above
12*b89261baSDavid van Moolenbroek  * copyright notice, this list of conditions and the following disclaimer
13*b89261baSDavid van Moolenbroek  * in the documentation and/or other materials provided with the
14*b89261baSDavid van Moolenbroek  * distribution.
15*b89261baSDavid van Moolenbroek  *
16*b89261baSDavid van Moolenbroek  *     * Neither the name of William LeFebvre nor the names of other
17*b89261baSDavid van Moolenbroek  * contributors may be used to endorse or promote products derived from
18*b89261baSDavid van Moolenbroek  * this software without specific prior written permission.
19*b89261baSDavid van Moolenbroek  *
20*b89261baSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*b89261baSDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*b89261baSDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*b89261baSDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*b89261baSDavid van Moolenbroek  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*b89261baSDavid van Moolenbroek  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*b89261baSDavid van Moolenbroek  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*b89261baSDavid van Moolenbroek  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*b89261baSDavid van Moolenbroek  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*b89261baSDavid van Moolenbroek  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*b89261baSDavid van Moolenbroek  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*b89261baSDavid van Moolenbroek  */
32*b89261baSDavid van Moolenbroek 
33*b89261baSDavid van Moolenbroek /*
34*b89261baSDavid van Moolenbroek  * top - a top users display for Unix
35*b89261baSDavid van Moolenbroek  *
36*b89261baSDavid van Moolenbroek  * SYNOPSIS:  Intel based System V Release 4
37*b89261baSDavid van Moolenbroek  *
38*b89261baSDavid van Moolenbroek  * DESCRIPTION:
39*b89261baSDavid van Moolenbroek  *	System V release 4.0.x for i486
40*b89261baSDavid van Moolenbroek  *	System V release 4     for Okidata M88100
41*b89261baSDavid van Moolenbroek  *	System V release 4     for NCR 3000 series OS Rel 1.00 to 2.02
42*b89261baSDavid van Moolenbroek  *	System V release 4     for NCR 3000 series OS Rel 02.03.00 and above
43*b89261baSDavid van Moolenbroek  *	and probably other svr4 ports
44*b89261baSDavid van Moolenbroek  *
45*b89261baSDavid van Moolenbroek  * LIBS:  -lelf
46*b89261baSDavid van Moolenbroek  *
47*b89261baSDavid van Moolenbroek  * AUTHORS:  Andrew Herbert     <andrew@werple.apana.org.au>
48*b89261baSDavid van Moolenbroek  *           Robert Boucher     <boucher@sofkin.ca>
49*b89261baSDavid van Moolenbroek  * Ported to System 3000 Release 2.03 by:
50*b89261baSDavid van Moolenbroek  * 	     Jeff Janvrin       <jeff.janvrinColumbiaSC.NCR.COM>
51*b89261baSDavid van Moolenbroek  */
52*b89261baSDavid van Moolenbroek 
53*b89261baSDavid van Moolenbroek #include "top.h"
54*b89261baSDavid van Moolenbroek #include "machine.h"
55*b89261baSDavid van Moolenbroek #include "utils.h"
56*b89261baSDavid van Moolenbroek #include <stdio.h>
57*b89261baSDavid van Moolenbroek #include <fcntl.h>
58*b89261baSDavid van Moolenbroek #include <unistd.h>
59*b89261baSDavid van Moolenbroek #include <stdlib.h>
60*b89261baSDavid van Moolenbroek #include <errno.h>
61*b89261baSDavid van Moolenbroek #include <dirent.h>
62*b89261baSDavid van Moolenbroek #include <nlist.h>
63*b89261baSDavid van Moolenbroek #include <string.h>
64*b89261baSDavid van Moolenbroek #if TIME_WITH_SYS_TIME
65*b89261baSDavid van Moolenbroek # include <sys/time.h>
66*b89261baSDavid van Moolenbroek # include <time.h>
67*b89261baSDavid van Moolenbroek #else
68*b89261baSDavid van Moolenbroek # if HAVE_SYS_TIME_H
69*b89261baSDavid van Moolenbroek #  include <sys/time.h>
70*b89261baSDavid van Moolenbroek # else
71*b89261baSDavid van Moolenbroek #  include <time.h>
72*b89261baSDavid van Moolenbroek # endif
73*b89261baSDavid van Moolenbroek #endif
74*b89261baSDavid van Moolenbroek #include <sys/types.h>
75*b89261baSDavid van Moolenbroek #include <sys/stat.h>
76*b89261baSDavid van Moolenbroek #include <sys/param.h>
77*b89261baSDavid van Moolenbroek #include <sys/procfs.h>
78*b89261baSDavid van Moolenbroek #include <sys/sysinfo.h>
79*b89261baSDavid van Moolenbroek #include <sys/sysmacros.h>
80*b89261baSDavid van Moolenbroek #include <sys/vmmeter.h>
81*b89261baSDavid van Moolenbroek #include <vm/anon.h>
82*b89261baSDavid van Moolenbroek #include <sys/priocntl.h>
83*b89261baSDavid van Moolenbroek #include <sys/rtpriocntl.h>
84*b89261baSDavid van Moolenbroek #include <sys/tspriocntl.h>
85*b89261baSDavid van Moolenbroek #include <sys/procset.h>
86*b89261baSDavid van Moolenbroek #include <sys/var.h>
87*b89261baSDavid van Moolenbroek 
88*b89261baSDavid van Moolenbroek #define UNIX "/stand/unix"
89*b89261baSDavid van Moolenbroek #define KMEM "/dev/kmem"
90*b89261baSDavid van Moolenbroek #define PROCFS "/proc"
91*b89261baSDavid van Moolenbroek #define CPUSTATES	5
92*b89261baSDavid van Moolenbroek 
93*b89261baSDavid van Moolenbroek #ifndef PRIO_MAX
94*b89261baSDavid van Moolenbroek #define PRIO_MAX	20
95*b89261baSDavid van Moolenbroek #endif
96*b89261baSDavid van Moolenbroek #ifndef PRIO_MIN
97*b89261baSDavid van Moolenbroek #define PRIO_MIN	-20
98*b89261baSDavid van Moolenbroek #endif
99*b89261baSDavid van Moolenbroek 
100*b89261baSDavid van Moolenbroek #ifndef FSCALE
101*b89261baSDavid van Moolenbroek #define FSHIFT  8		/* bits to right of fixed binary point */
102*b89261baSDavid van Moolenbroek #define FSCALE  (1<<FSHIFT)
103*b89261baSDavid van Moolenbroek #endif
104*b89261baSDavid van Moolenbroek 
105*b89261baSDavid van Moolenbroek #define loaddouble(x) ((double)(x) / FSCALE)
106*b89261baSDavid van Moolenbroek #define percent_cpu(x) ((double)(x)->pr_cpu / FSCALE)
107*b89261baSDavid van Moolenbroek #define weighted_cpu(pct, pp) ( ((pp)->pr_time.tv_sec) == 0 ? 0.0 : \
108*b89261baSDavid van Moolenbroek         ((pp)->pr_cpu) / ((pp)->pr_time.tv_sec) )
109*b89261baSDavid van Moolenbroek #define pagetok(size) ctob(size) >> LOG1024
110*b89261baSDavid van Moolenbroek 
111*b89261baSDavid van Moolenbroek /* definitions for the index in the nlist array */
112*b89261baSDavid van Moolenbroek #define X_AVENRUN	0
113*b89261baSDavid van Moolenbroek #define X_MPID		1
114*b89261baSDavid van Moolenbroek #define X_V		2
115*b89261baSDavid van Moolenbroek #define X_NPROC		3
116*b89261baSDavid van Moolenbroek #define X_ANONINFO	4
117*b89261baSDavid van Moolenbroek #define X_TOTAL		5
118*b89261baSDavid van Moolenbroek #define X_SYSINFO	6
119*b89261baSDavid van Moolenbroek 
120*b89261baSDavid van Moolenbroek static struct nlist nlst[] =
121*b89261baSDavid van Moolenbroek {
122*b89261baSDavid van Moolenbroek {"avenrun"},			/* 0 */
123*b89261baSDavid van Moolenbroek {"mpid"},			/* 1 */
124*b89261baSDavid van Moolenbroek {"v"},			/* 2 */
125*b89261baSDavid van Moolenbroek {"nproc"},			/* 3 */
126*b89261baSDavid van Moolenbroek {"anoninfo"},			/* 4 */
127*b89261baSDavid van Moolenbroek {"total"},			/* 5 */
128*b89261baSDavid van Moolenbroek {"sysinfo"},			/* 6 */
129*b89261baSDavid van Moolenbroek {NULL}
130*b89261baSDavid van Moolenbroek };
131*b89261baSDavid van Moolenbroek 
132*b89261baSDavid van Moolenbroek static unsigned long avenrun_offset;
133*b89261baSDavid van Moolenbroek static unsigned long mpid_offset;
134*b89261baSDavid van Moolenbroek static unsigned long nproc_offset;
135*b89261baSDavid van Moolenbroek static unsigned long anoninfo_offset;
136*b89261baSDavid van Moolenbroek static unsigned long total_offset;
137*b89261baSDavid van Moolenbroek static unsigned long sysinfo_offset;
138*b89261baSDavid van Moolenbroek 
139*b89261baSDavid van Moolenbroek /* get_process_info passes back a handle.  This is what it looks like: */
140*b89261baSDavid van Moolenbroek 
141*b89261baSDavid van Moolenbroek struct handle
142*b89261baSDavid van Moolenbroek   {
143*b89261baSDavid van Moolenbroek     struct prpsinfo **next_proc;/* points to next valid proc pointer */
144*b89261baSDavid van Moolenbroek     int remaining;		/* number of pointers remaining */
145*b89261baSDavid van Moolenbroek   };
146*b89261baSDavid van Moolenbroek 
147*b89261baSDavid van Moolenbroek /*
148*b89261baSDavid van Moolenbroek  *  These definitions control the format of the per-process area
149*b89261baSDavid van Moolenbroek  */
150*b89261baSDavid van Moolenbroek 
151*b89261baSDavid van Moolenbroek static char header[] =
152*b89261baSDavid van Moolenbroek "  PID X        PRI NICE  SIZE   RES STATE   TIME   WCPU    CPU COMMAND";
153*b89261baSDavid van Moolenbroek /* 0123456   -- field to fill in starts at header+6 */
154*b89261baSDavid van Moolenbroek #define UNAME_START 6
155*b89261baSDavid van Moolenbroek #define Proc_format \
156*b89261baSDavid van Moolenbroek 	"%5d %-8.8s %3d %4d %5s %5s %-5s %6s %3d.0%% %5.2f%% %.16s"
157*b89261baSDavid van Moolenbroek 
158*b89261baSDavid van Moolenbroek char *state_abbrev[] =
159*b89261baSDavid van Moolenbroek {"", "sleep", "run", "zombie", "stop", "start", "cpu", "swap"};
160*b89261baSDavid van Moolenbroek 
161*b89261baSDavid van Moolenbroek int process_states[8];
162*b89261baSDavid van Moolenbroek char *procstatenames[] =
163*b89261baSDavid van Moolenbroek {
164*b89261baSDavid van Moolenbroek   "", " sleeping, ", " running, ", " zombie, ", " stopped, ",
165*b89261baSDavid van Moolenbroek   " starting, ", " on cpu, ", " swapped, ",
166*b89261baSDavid van Moolenbroek   NULL
167*b89261baSDavid van Moolenbroek };
168*b89261baSDavid van Moolenbroek 
169*b89261baSDavid van Moolenbroek int cpu_states[CPUSTATES];
170*b89261baSDavid van Moolenbroek char *cpustatenames[] =
171*b89261baSDavid van Moolenbroek {"idle", "user", "kernel", "wait", "swap", NULL};
172*b89261baSDavid van Moolenbroek 
173*b89261baSDavid van Moolenbroek /* these are for detailing the memory statistics */
174*b89261baSDavid van Moolenbroek 
175*b89261baSDavid van Moolenbroek long memory_stats[5];
176*b89261baSDavid van Moolenbroek char *memorynames[] =
177*b89261baSDavid van Moolenbroek {"K real, ", "K active, ", "K free, ", "K swap, ", "K free swap", NULL};
178*b89261baSDavid van Moolenbroek 
179*b89261baSDavid van Moolenbroek /* forward reference for qsort comparison function */
180*b89261baSDavid van Moolenbroek int proc_compare();
181*b89261baSDavid van Moolenbroek 
182*b89261baSDavid van Moolenbroek static int kmem = -1;
183*b89261baSDavid van Moolenbroek static int nproc;
184*b89261baSDavid van Moolenbroek static int bytes;
185*b89261baSDavid van Moolenbroek static int use_stats = 0;
186*b89261baSDavid van Moolenbroek static struct prpsinfo *pbase;
187*b89261baSDavid van Moolenbroek static struct prpsinfo **pref;
188*b89261baSDavid van Moolenbroek static DIR *proc_dir;
189*b89261baSDavid van Moolenbroek 
190*b89261baSDavid van Moolenbroek /* useful externals */
191*b89261baSDavid van Moolenbroek extern int errno;
192*b89261baSDavid van Moolenbroek extern char *sys_errlist[];
193*b89261baSDavid van Moolenbroek extern char *myname;
194*b89261baSDavid van Moolenbroek extern int check_nlist ();
195*b89261baSDavid van Moolenbroek extern int getkval ();
196*b89261baSDavid van Moolenbroek extern void perror ();
197*b89261baSDavid van Moolenbroek extern void getptable ();
198*b89261baSDavid van Moolenbroek extern void quit ();
199*b89261baSDavid van Moolenbroek extern int nlist ();
200*b89261baSDavid van Moolenbroek 
201*b89261baSDavid van Moolenbroek int
machine_init(struct statics * statics)202*b89261baSDavid van Moolenbroek machine_init (struct statics *statics)
203*b89261baSDavid van Moolenbroek   {
204*b89261baSDavid van Moolenbroek     static struct var v;
205*b89261baSDavid van Moolenbroek 
206*b89261baSDavid van Moolenbroek     /* fill in the statics information */
207*b89261baSDavid van Moolenbroek     statics->procstate_names = procstatenames;
208*b89261baSDavid van Moolenbroek     statics->cpustate_names = cpustatenames;
209*b89261baSDavid van Moolenbroek     statics->memory_names = memorynames;
210*b89261baSDavid van Moolenbroek 
211*b89261baSDavid van Moolenbroek     /* get the list of symbols we want to access in the kernel */
212*b89261baSDavid van Moolenbroek     if (nlist (UNIX, nlst))
213*b89261baSDavid van Moolenbroek       {
214*b89261baSDavid van Moolenbroek 	(void) fprintf (stderr, "Unable to nlist %s\n", UNIX);
215*b89261baSDavid van Moolenbroek 	return (-1);
216*b89261baSDavid van Moolenbroek       }
217*b89261baSDavid van Moolenbroek 
218*b89261baSDavid van Moolenbroek     /* make sure they were all found */
219*b89261baSDavid van Moolenbroek     if (check_nlist (nlst) > 0)
220*b89261baSDavid van Moolenbroek       return (-1);
221*b89261baSDavid van Moolenbroek 
222*b89261baSDavid van Moolenbroek     /* open kernel memory */
223*b89261baSDavid van Moolenbroek     if ((kmem = open (KMEM, O_RDONLY)) == -1)
224*b89261baSDavid van Moolenbroek       {
225*b89261baSDavid van Moolenbroek 	perror (KMEM);
226*b89261baSDavid van Moolenbroek 	return (-1);
227*b89261baSDavid van Moolenbroek       }
228*b89261baSDavid van Moolenbroek 
229*b89261baSDavid van Moolenbroek     /* get the symbol values out of kmem */
230*b89261baSDavid van Moolenbroek     /* NPROC Tuning parameter for max number of processes */
231*b89261baSDavid van Moolenbroek     (void) getkval (nlst[X_V].n_value, &v, sizeof (struct var), nlst[X_V].n_name);
232*b89261baSDavid van Moolenbroek     nproc = v.v_proc;
233*b89261baSDavid van Moolenbroek 
234*b89261baSDavid van Moolenbroek     /* stash away certain offsets for later use */
235*b89261baSDavid van Moolenbroek     mpid_offset = nlst[X_MPID].n_value;
236*b89261baSDavid van Moolenbroek     nproc_offset = nlst[X_NPROC].n_value;
237*b89261baSDavid van Moolenbroek     avenrun_offset = nlst[X_AVENRUN].n_value;
238*b89261baSDavid van Moolenbroek     anoninfo_offset = nlst[X_ANONINFO].n_value;
239*b89261baSDavid van Moolenbroek     total_offset = nlst[X_TOTAL].n_value;
240*b89261baSDavid van Moolenbroek /* JJ this may need to be changed */
241*b89261baSDavid van Moolenbroek     sysinfo_offset = nlst[X_SYSINFO].n_value;
242*b89261baSDavid van Moolenbroek 
243*b89261baSDavid van Moolenbroek     /* allocate space for proc structure array and array of pointers */
244*b89261baSDavid van Moolenbroek     bytes = nproc * sizeof (struct prpsinfo);
245*b89261baSDavid van Moolenbroek     pbase = (struct prpsinfo *) malloc (bytes);
246*b89261baSDavid van Moolenbroek     pref = (struct prpsinfo **) malloc (nproc * sizeof (struct prpsinfo *));
247*b89261baSDavid van Moolenbroek 
248*b89261baSDavid van Moolenbroek     /* Just in case ... */
249*b89261baSDavid van Moolenbroek     if (pbase == (struct prpsinfo *) NULL || pref == (struct prpsinfo **) NULL)
250*b89261baSDavid van Moolenbroek       {
251*b89261baSDavid van Moolenbroek 	(void) fprintf (stderr, "%s: can't allocate sufficient memory\n", myname);
252*b89261baSDavid van Moolenbroek 	return (-1);
253*b89261baSDavid van Moolenbroek       }
254*b89261baSDavid van Moolenbroek 
255*b89261baSDavid van Moolenbroek     if (!(proc_dir = opendir (PROCFS)))
256*b89261baSDavid van Moolenbroek       {
257*b89261baSDavid van Moolenbroek 	(void) fprintf (stderr, "Unable to open %s\n", PROCFS);
258*b89261baSDavid van Moolenbroek 	return (-1);
259*b89261baSDavid van Moolenbroek       }
260*b89261baSDavid van Moolenbroek 
261*b89261baSDavid van Moolenbroek     if (chdir (PROCFS))
262*b89261baSDavid van Moolenbroek       {				/* handy for later on when we're reading it */
263*b89261baSDavid van Moolenbroek 	(void) fprintf (stderr, "Unable to chdir to %s\n", PROCFS);
264*b89261baSDavid van Moolenbroek 	return (-1);
265*b89261baSDavid van Moolenbroek       }
266*b89261baSDavid van Moolenbroek 
267*b89261baSDavid van Moolenbroek     /* all done! */
268*b89261baSDavid van Moolenbroek     return (0);
269*b89261baSDavid van Moolenbroek   }
270*b89261baSDavid van Moolenbroek 
271*b89261baSDavid van Moolenbroek char *
format_header(char * uname_field)272*b89261baSDavid van Moolenbroek format_header (char *uname_field)
273*b89261baSDavid van Moolenbroek {
274*b89261baSDavid van Moolenbroek   register char *ptr;
275*b89261baSDavid van Moolenbroek 
276*b89261baSDavid van Moolenbroek   ptr = header + UNAME_START;
277*b89261baSDavid van Moolenbroek   while (*uname_field != '\0')
278*b89261baSDavid van Moolenbroek     *ptr++ = *uname_field++;
279*b89261baSDavid van Moolenbroek 
280*b89261baSDavid van Moolenbroek   return (header);
281*b89261baSDavid van Moolenbroek }
282*b89261baSDavid van Moolenbroek 
283*b89261baSDavid van Moolenbroek void
get_system_info(struct system_info * si)284*b89261baSDavid van Moolenbroek get_system_info (struct system_info *si)
285*b89261baSDavid van Moolenbroek {
286*b89261baSDavid van Moolenbroek   long avenrun[3];
287*b89261baSDavid van Moolenbroek   struct sysinfo sysinfo;
288*b89261baSDavid van Moolenbroek   static struct sysinfo *mpinfo = NULL;	/* array, per-processor sysinfo structures. */
289*b89261baSDavid van Moolenbroek   struct vmtotal total;
290*b89261baSDavid van Moolenbroek   struct anoninfo anoninfo;
291*b89261baSDavid van Moolenbroek   static long cp_old[CPUSTATES];
292*b89261baSDavid van Moolenbroek   static long cp_diff[CPUSTATES];	/* for cpu state percentages */
293*b89261baSDavid van Moolenbroek   static int num_cpus;
294*b89261baSDavid van Moolenbroek   static int fd_cpu = 0;
295*b89261baSDavid van Moolenbroek   register int i;
296*b89261baSDavid van Moolenbroek 
297*b89261baSDavid van Moolenbroek   if ( use_stats == 1) {
298*b89261baSDavid van Moolenbroek     if ( fd_cpu == 0 ) {
299*b89261baSDavid van Moolenbroek       if ((fd_cpu = open("/stats/cpuinfo", O_RDONLY)) == -1) {
300*b89261baSDavid van Moolenbroek         (void) fprintf (stderr, "%s: Open of /stats/cpuinfo failed\n", myname);
301*b89261baSDavid van Moolenbroek 	quit(2);
302*b89261baSDavid van Moolenbroek       }
303*b89261baSDavid van Moolenbroek       if (read(fd_cpu, &num_cpus, sizeof(int)) != sizeof(int)) {
304*b89261baSDavid van Moolenbroek         (void) fprintf (stderr, "%s: Read of /stats/cpuinfo failed\n", myname);
305*b89261baSDavid van Moolenbroek 	quit(2);
306*b89261baSDavid van Moolenbroek       }
307*b89261baSDavid van Moolenbroek       close(fd_cpu);
308*b89261baSDavid van Moolenbroek     }
309*b89261baSDavid van Moolenbroek     if (mpinfo == NULL) {
310*b89261baSDavid van Moolenbroek       mpinfo = (struct sysinfo *)calloc(num_cpus, sizeof(mpinfo[0]));
311*b89261baSDavid van Moolenbroek       if (mpinfo == NULL) {
312*b89261baSDavid van Moolenbroek         (void) fprintf (stderr, "%s: can't allocate space for per-processor sysinfos\n", myname);
313*b89261baSDavid van Moolenbroek         quit(12);
314*b89261baSDavid van Moolenbroek       }
315*b89261baSDavid van Moolenbroek     }
316*b89261baSDavid van Moolenbroek     /* Read the per cpu sysinfo structures into mpinfo struct. */
317*b89261baSDavid van Moolenbroek     read_sysinfos(num_cpus, mpinfo);
318*b89261baSDavid van Moolenbroek     /* Add up all of the percpu sysinfos to get global sysinfo */
319*b89261baSDavid van Moolenbroek     sysinfo_data(num_cpus, &sysinfo, mpinfo);
320*b89261baSDavid van Moolenbroek   } else {
321*b89261baSDavid van Moolenbroek     (void) getkval (sysinfo_offset, &sysinfo, sizeof (struct sysinfo), "sysinfo");
322*b89261baSDavid van Moolenbroek   }
323*b89261baSDavid van Moolenbroek 
324*b89261baSDavid van Moolenbroek   /* convert cp_time counts to percentages */
325*b89261baSDavid van Moolenbroek   (void) percentages (CPUSTATES, cpu_states, sysinfo.cpu, cp_old, cp_diff);
326*b89261baSDavid van Moolenbroek 
327*b89261baSDavid van Moolenbroek   /* get mpid -- process id of last process */
328*b89261baSDavid van Moolenbroek   (void) getkval (mpid_offset, &(si->last_pid), sizeof (si->last_pid),
329*b89261baSDavid van Moolenbroek 		  "mpid");
330*b89261baSDavid van Moolenbroek 
331*b89261baSDavid van Moolenbroek   /* get load average array */
332*b89261baSDavid van Moolenbroek   (void) getkval (avenrun_offset, (int *) avenrun, sizeof (avenrun), "avenrun");
333*b89261baSDavid van Moolenbroek 
334*b89261baSDavid van Moolenbroek   /* convert load averages to doubles */
335*b89261baSDavid van Moolenbroek   for (i = 0; i < 3; i++)
336*b89261baSDavid van Moolenbroek     si->load_avg[i] = loaddouble (avenrun[i]);
337*b89261baSDavid van Moolenbroek 
338*b89261baSDavid van Moolenbroek   /* get total -- systemwide main memory usage structure */
339*b89261baSDavid van Moolenbroek   (void) getkval (total_offset, (int *) (&total), sizeof (total), "total");
340*b89261baSDavid van Moolenbroek   /* convert memory stats to Kbytes */
341*b89261baSDavid van Moolenbroek   memory_stats[0] = pagetok (total.t_rm);
342*b89261baSDavid van Moolenbroek   memory_stats[1] = pagetok (total.t_arm);
343*b89261baSDavid van Moolenbroek   memory_stats[2] = pagetok (total.t_free);
344*b89261baSDavid van Moolenbroek   (void) getkval (anoninfo_offset, (int *) (&anoninfo), sizeof (anoninfo),
345*b89261baSDavid van Moolenbroek 		  "anoninfo");
346*b89261baSDavid van Moolenbroek   memory_stats[3] = pagetok (anoninfo.ani_max - anoninfo.ani_free);
347*b89261baSDavid van Moolenbroek   memory_stats[4] = pagetok (anoninfo.ani_max - anoninfo.ani_resv);
348*b89261baSDavid van Moolenbroek 
349*b89261baSDavid van Moolenbroek   /* set arrays and strings */
350*b89261baSDavid van Moolenbroek   si->cpustates = cpu_states;
351*b89261baSDavid van Moolenbroek   si->memory = memory_stats;
352*b89261baSDavid van Moolenbroek }
353*b89261baSDavid van Moolenbroek 
354*b89261baSDavid van Moolenbroek static struct handle handle;
355*b89261baSDavid van Moolenbroek 
356*b89261baSDavid van Moolenbroek caddr_t
get_process_info(struct system_info * si,struct process_select * sel,int x)357*b89261baSDavid van Moolenbroek get_process_info (
358*b89261baSDavid van Moolenbroek 		   struct system_info *si,
359*b89261baSDavid van Moolenbroek 		   struct process_select *sel,
360*b89261baSDavid van Moolenbroek 		   int x)
361*b89261baSDavid van Moolenbroek {
362*b89261baSDavid van Moolenbroek   register int i;
363*b89261baSDavid van Moolenbroek   register int total_procs;
364*b89261baSDavid van Moolenbroek   register int active_procs;
365*b89261baSDavid van Moolenbroek   register struct prpsinfo **prefp;
366*b89261baSDavid van Moolenbroek   register struct prpsinfo *pp;
367*b89261baSDavid van Moolenbroek 
368*b89261baSDavid van Moolenbroek   /* these are copied out of sel for speed */
369*b89261baSDavid van Moolenbroek   int show_idle;
370*b89261baSDavid van Moolenbroek   int show_system;
371*b89261baSDavid van Moolenbroek   int show_uid;
372*b89261baSDavid van Moolenbroek 
373*b89261baSDavid van Moolenbroek   /* Get current number of processes */
374*b89261baSDavid van Moolenbroek   (void) getkval (nproc_offset, (int *) (&nproc), sizeof (nproc), "nproc");
375*b89261baSDavid van Moolenbroek 
376*b89261baSDavid van Moolenbroek   /* read all the proc structures */
377*b89261baSDavid van Moolenbroek   getptable (pbase);
378*b89261baSDavid van Moolenbroek 
379*b89261baSDavid van Moolenbroek   /* get a pointer to the states summary array */
380*b89261baSDavid van Moolenbroek   si->procstates = process_states;
381*b89261baSDavid van Moolenbroek 
382*b89261baSDavid van Moolenbroek   /* set up flags which define what we are going to select */
383*b89261baSDavid van Moolenbroek   show_idle = sel->idle;
384*b89261baSDavid van Moolenbroek   show_system = sel->system;
385*b89261baSDavid van Moolenbroek   show_uid = sel->uid != -1;
386*b89261baSDavid van Moolenbroek 
387*b89261baSDavid van Moolenbroek   /* count up process states and get pointers to interesting procs */
388*b89261baSDavid van Moolenbroek   total_procs = 0;
389*b89261baSDavid van Moolenbroek   active_procs = 0;
390*b89261baSDavid van Moolenbroek   (void) memset (process_states, 0, sizeof (process_states));
391*b89261baSDavid van Moolenbroek   prefp = pref;
392*b89261baSDavid van Moolenbroek 
393*b89261baSDavid van Moolenbroek   for (pp = pbase, i = 0; i < nproc; pp++, i++)
394*b89261baSDavid van Moolenbroek     {
395*b89261baSDavid van Moolenbroek       /*
396*b89261baSDavid van Moolenbroek 	 *  Place pointers to each valid proc structure in pref[].
397*b89261baSDavid van Moolenbroek 	 *  Process slots that are actually in use have a non-zero
398*b89261baSDavid van Moolenbroek 	 *  status field.  Processes with SSYS set are system
399*b89261baSDavid van Moolenbroek 	 *  processes---these get ignored unless show_sysprocs is set.
400*b89261baSDavid van Moolenbroek 	 */
401*b89261baSDavid van Moolenbroek       if (pp->pr_state != 0 &&
402*b89261baSDavid van Moolenbroek 	  (show_system || ((pp->pr_flag & SSYS) == 0)))
403*b89261baSDavid van Moolenbroek 	{
404*b89261baSDavid van Moolenbroek 	  total_procs++;
405*b89261baSDavid van Moolenbroek 	  process_states[pp->pr_state]++;
406*b89261baSDavid van Moolenbroek 	  if ((!pp->pr_zomb) &&
407*b89261baSDavid van Moolenbroek 	      (show_idle || (pp->pr_state == SRUN) || (pp->pr_state == SONPROC)) &&
408*b89261baSDavid van Moolenbroek 	      (!show_uid || pp->pr_uid == (uid_t) sel->uid))
409*b89261baSDavid van Moolenbroek 	    {
410*b89261baSDavid van Moolenbroek 	      *prefp++ = pp;
411*b89261baSDavid van Moolenbroek 	      active_procs++;
412*b89261baSDavid van Moolenbroek 	    }
413*b89261baSDavid van Moolenbroek 	}
414*b89261baSDavid van Moolenbroek     }
415*b89261baSDavid van Moolenbroek 
416*b89261baSDavid van Moolenbroek   /* if requested, sort the "interesting" processes */
417*b89261baSDavid van Moolenbroek   qsort ((char *) pref, active_procs, sizeof (struct prpsinfo *), proc_compare);
418*b89261baSDavid van Moolenbroek 
419*b89261baSDavid van Moolenbroek   /* remember active and total counts */
420*b89261baSDavid van Moolenbroek   si->p_total = total_procs;
421*b89261baSDavid van Moolenbroek   si->p_active = active_procs;
422*b89261baSDavid van Moolenbroek 
423*b89261baSDavid van Moolenbroek   /* pass back a handle */
424*b89261baSDavid van Moolenbroek   handle.next_proc = pref;
425*b89261baSDavid van Moolenbroek   handle.remaining = active_procs;
426*b89261baSDavid van Moolenbroek   return ((caddr_t) & handle);
427*b89261baSDavid van Moolenbroek }
428*b89261baSDavid van Moolenbroek 
429*b89261baSDavid van Moolenbroek char fmt[MAX_COLS];			/* static area where result is built */
430*b89261baSDavid van Moolenbroek 
431*b89261baSDavid van Moolenbroek char *
format_next_process(caddr_t handle,char * (* get_userid)())432*b89261baSDavid van Moolenbroek format_next_process (
433*b89261baSDavid van Moolenbroek 		      caddr_t handle,
434*b89261baSDavid van Moolenbroek 		      char *(*get_userid) ())
435*b89261baSDavid van Moolenbroek {
436*b89261baSDavid van Moolenbroek   register struct prpsinfo *pp;
437*b89261baSDavid van Moolenbroek   struct handle *hp;
438*b89261baSDavid van Moolenbroek   register long cputime;
439*b89261baSDavid van Moolenbroek   register double pctcpu;
440*b89261baSDavid van Moolenbroek 
441*b89261baSDavid van Moolenbroek   /* find and remember the next proc structure */
442*b89261baSDavid van Moolenbroek   hp = (struct handle *) handle;
443*b89261baSDavid van Moolenbroek   pp = *(hp->next_proc++);
444*b89261baSDavid van Moolenbroek   hp->remaining--;
445*b89261baSDavid van Moolenbroek 
446*b89261baSDavid van Moolenbroek   /* get the cpu usage and calculate the cpu percentages */
447*b89261baSDavid van Moolenbroek   cputime = pp->pr_time.tv_sec;
448*b89261baSDavid van Moolenbroek   pctcpu = percent_cpu (pp);
449*b89261baSDavid van Moolenbroek 
450*b89261baSDavid van Moolenbroek   /* format this entry */
451*b89261baSDavid van Moolenbroek   (void) sprintf (fmt,
452*b89261baSDavid van Moolenbroek 		  Proc_format,
453*b89261baSDavid van Moolenbroek 		  pp->pr_pid,
454*b89261baSDavid van Moolenbroek 		  (*get_userid) (pp->pr_uid),
455*b89261baSDavid van Moolenbroek 		  pp->pr_pri - PZERO,
456*b89261baSDavid van Moolenbroek 		  pp->pr_nice - NZERO,
457*b89261baSDavid van Moolenbroek 		  format_k(pagetok (pp->pr_size)),
458*b89261baSDavid van Moolenbroek 		  format_k(pagetok (pp->pr_rssize)),
459*b89261baSDavid van Moolenbroek 		  state_abbrev[pp->pr_state],
460*b89261baSDavid van Moolenbroek 		  format_time(cputime),
461*b89261baSDavid van Moolenbroek 		  (pp->pr_cpu & 0377),
462*b89261baSDavid van Moolenbroek 		  100.0 * pctcpu,
463*b89261baSDavid van Moolenbroek 		  printable(pp->pr_fname));
464*b89261baSDavid van Moolenbroek 
465*b89261baSDavid van Moolenbroek   /* return the result */
466*b89261baSDavid van Moolenbroek   return (fmt);
467*b89261baSDavid van Moolenbroek }
468*b89261baSDavid van Moolenbroek 
469*b89261baSDavid van Moolenbroek /*
470*b89261baSDavid van Moolenbroek  * check_nlist(nlst) - checks the nlist to see if any symbols were not
471*b89261baSDavid van Moolenbroek  *		found.  For every symbol that was not found, a one-line
472*b89261baSDavid van Moolenbroek  *		message is printed to stderr.  The routine returns the
473*b89261baSDavid van Moolenbroek  *		number of symbols NOT found.
474*b89261baSDavid van Moolenbroek  */
475*b89261baSDavid van Moolenbroek int
check_nlist(register struct nlist * nlst)476*b89261baSDavid van Moolenbroek check_nlist (register struct nlist *nlst)
477*b89261baSDavid van Moolenbroek {
478*b89261baSDavid van Moolenbroek   register int i;
479*b89261baSDavid van Moolenbroek   struct stat stat_buf;
480*b89261baSDavid van Moolenbroek 
481*b89261baSDavid van Moolenbroek   /* check to see if we got ALL the symbols we requested */
482*b89261baSDavid van Moolenbroek   /* this will write one line to stderr for every symbol not found */
483*b89261baSDavid van Moolenbroek 
484*b89261baSDavid van Moolenbroek   i = 0;
485*b89261baSDavid van Moolenbroek   while (nlst->n_name != NULL)
486*b89261baSDavid van Moolenbroek     {
487*b89261baSDavid van Moolenbroek       if (nlst->n_type == 0)
488*b89261baSDavid van Moolenbroek 	{
489*b89261baSDavid van Moolenbroek 	  if (strcmp("sysinfo", nlst->n_name) == 0)
490*b89261baSDavid van Moolenbroek 	    {
491*b89261baSDavid van Moolenbroek 		/* check to see if /stats file system exists. If so, 	*/
492*b89261baSDavid van Moolenbroek 		/* ignore error. 					*/
493*b89261baSDavid van Moolenbroek 		if ( !((stat("/stats/sysinfo", &stat_buf) == 0) &&
494*b89261baSDavid van Moolenbroek 		  (stat_buf.st_mode & S_IFREG)) )
495*b89261baSDavid van Moolenbroek 		  {
496*b89261baSDavid van Moolenbroek 		    (void) fprintf (stderr, "kernel: no symbol named `%s'\n", nlst->n_name);
497*b89261baSDavid van Moolenbroek 		    i = 1;
498*b89261baSDavid van Moolenbroek 		  } else {
499*b89261baSDavid van Moolenbroek 		    use_stats = 1;
500*b89261baSDavid van Moolenbroek 		  }
501*b89261baSDavid van Moolenbroek 	    } else {
502*b89261baSDavid van Moolenbroek 
503*b89261baSDavid van Moolenbroek 	      /* this one wasn't found */
504*b89261baSDavid van Moolenbroek 	      (void) fprintf (stderr, "kernel: no symbol named `%s'\n", nlst->n_name);
505*b89261baSDavid van Moolenbroek 	      i = 1;
506*b89261baSDavid van Moolenbroek 	    }
507*b89261baSDavid van Moolenbroek 	}
508*b89261baSDavid van Moolenbroek       nlst++;
509*b89261baSDavid van Moolenbroek     }
510*b89261baSDavid van Moolenbroek   return (i);
511*b89261baSDavid van Moolenbroek }
512*b89261baSDavid van Moolenbroek 
513*b89261baSDavid van Moolenbroek 
514*b89261baSDavid van Moolenbroek /*
515*b89261baSDavid van Moolenbroek  *  getkval(offset, ptr, size, refstr) - get a value out of the kernel.
516*b89261baSDavid van Moolenbroek  *	"offset" is the byte offset into the kernel for the desired value,
517*b89261baSDavid van Moolenbroek  *  	"ptr" points to a buffer into which the value is retrieved,
518*b89261baSDavid van Moolenbroek  *  	"size" is the size of the buffer (and the object to retrieve),
519*b89261baSDavid van Moolenbroek  *  	"refstr" is a reference string used when printing error meessages,
520*b89261baSDavid van Moolenbroek  *	    if "refstr" starts with a '!', then a failure on read will not
521*b89261baSDavid van Moolenbroek  *  	    be fatal (this may seem like a silly way to do things, but I
522*b89261baSDavid van Moolenbroek  *  	    really didn't want the overhead of another argument).
523*b89261baSDavid van Moolenbroek  *
524*b89261baSDavid van Moolenbroek  */
525*b89261baSDavid van Moolenbroek int
getkval(unsigned long offset,int * ptr,int size,char * refstr)526*b89261baSDavid van Moolenbroek getkval (
527*b89261baSDavid van Moolenbroek 	  unsigned long offset,
528*b89261baSDavid van Moolenbroek 	  int *ptr,
529*b89261baSDavid van Moolenbroek 	  int size,
530*b89261baSDavid van Moolenbroek 	  char *refstr)
531*b89261baSDavid van Moolenbroek {
532*b89261baSDavid van Moolenbroek #ifdef MIPS
533*b89261baSDavid van Moolenbroek   if (lseek (kmem, (long) (offset & 0x7fffffff), 0) == -1)
534*b89261baSDavid van Moolenbroek #else
535*b89261baSDavid van Moolenbroek   if (lseek (kmem, (long) offset, 0) == -1)
536*b89261baSDavid van Moolenbroek #endif
537*b89261baSDavid van Moolenbroek     {
538*b89261baSDavid van Moolenbroek       if (*refstr == '!')
539*b89261baSDavid van Moolenbroek 	refstr++;
540*b89261baSDavid van Moolenbroek       (void) fprintf (stderr, "%s: lseek to %s: %s\n",
541*b89261baSDavid van Moolenbroek 		      myname, refstr, sys_errlist[errno]);
542*b89261baSDavid van Moolenbroek       quit (22);
543*b89261baSDavid van Moolenbroek     }
544*b89261baSDavid van Moolenbroek   if (read (kmem, (char *) ptr, size) == -1)
545*b89261baSDavid van Moolenbroek     if (*refstr == '!')
546*b89261baSDavid van Moolenbroek       /* we lost the race with the kernel, process isn't in memory */
547*b89261baSDavid van Moolenbroek       return (0);
548*b89261baSDavid van Moolenbroek     else
549*b89261baSDavid van Moolenbroek       {
550*b89261baSDavid van Moolenbroek 	(void) fprintf (stderr, "%s: reading %s: %s\n",
551*b89261baSDavid van Moolenbroek 			myname, refstr, sys_errlist[errno]);
552*b89261baSDavid van Moolenbroek 	quit (23);
553*b89261baSDavid van Moolenbroek       }
554*b89261baSDavid van Moolenbroek   return (1);
555*b89261baSDavid van Moolenbroek }
556*b89261baSDavid van Moolenbroek 
557*b89261baSDavid van Moolenbroek /* comparison routine for qsort */
558*b89261baSDavid van Moolenbroek 
559*b89261baSDavid van Moolenbroek /*
560*b89261baSDavid van Moolenbroek  *  proc_compare - comparison function for "qsort"
561*b89261baSDavid van Moolenbroek  *	Compares the resource consumption of two processes using five
562*b89261baSDavid van Moolenbroek  *  	distinct keys.  The keys (in descending order of importance) are:
563*b89261baSDavid van Moolenbroek  *  	percent cpu, cpu ticks, state, resident set size, total virtual
564*b89261baSDavid van Moolenbroek  *  	memory usage.  The process states are ordered as follows (from least
565*b89261baSDavid van Moolenbroek  *  	to most important):  WAIT, zombie, sleep, stop, start, run.  The
566*b89261baSDavid van Moolenbroek  *  	array declaration below maps a process state index into a number
567*b89261baSDavid van Moolenbroek  *  	that reflects this ordering.
568*b89261baSDavid van Moolenbroek  */
569*b89261baSDavid van Moolenbroek 
570*b89261baSDavid van Moolenbroek 
571*b89261baSDavid van Moolenbroek unsigned char sorted_state[] =
572*b89261baSDavid van Moolenbroek {
573*b89261baSDavid van Moolenbroek   0,				/* not used		*/
574*b89261baSDavid van Moolenbroek   3,				/* sleep		*/
575*b89261baSDavid van Moolenbroek   6,				/* run			*/
576*b89261baSDavid van Moolenbroek   2,				/* zombie		*/
577*b89261baSDavid van Moolenbroek   4,				/* stop			*/
578*b89261baSDavid van Moolenbroek   5,				/* start		*/
579*b89261baSDavid van Moolenbroek   7,				/* run on a processor   */
580*b89261baSDavid van Moolenbroek   1				/* being swapped (WAIT)	*/
581*b89261baSDavid van Moolenbroek };
582*b89261baSDavid van Moolenbroek 
583*b89261baSDavid van Moolenbroek int
proc_compare(struct prpsinfo ** pp1,struct prpsinfo ** pp2)584*b89261baSDavid van Moolenbroek proc_compare (
585*b89261baSDavid van Moolenbroek 	       struct prpsinfo **pp1,
586*b89261baSDavid van Moolenbroek 	       struct prpsinfo **pp2)
587*b89261baSDavid van Moolenbroek {
588*b89261baSDavid van Moolenbroek     register struct prpsinfo *p1;
589*b89261baSDavid van Moolenbroek     register struct prpsinfo *p2;
590*b89261baSDavid van Moolenbroek     register long result;
591*b89261baSDavid van Moolenbroek 
592*b89261baSDavid van Moolenbroek     /* remove one level of indirection */
593*b89261baSDavid van Moolenbroek     p1 = *pp1;
594*b89261baSDavid van Moolenbroek     p2 = *pp2;
595*b89261baSDavid van Moolenbroek 
596*b89261baSDavid van Moolenbroek     /* compare percent cpu (pctcpu) */
597*b89261baSDavid van Moolenbroek     if ((result = (long) (p2->pr_cpu - p1->pr_cpu)) == 0)
598*b89261baSDavid van Moolenbroek       {
599*b89261baSDavid van Moolenbroek 	/* use cpticks to break the tie */
600*b89261baSDavid van Moolenbroek 	if ((result = p2->pr_time.tv_sec - p1->pr_time.tv_sec) == 0)
601*b89261baSDavid van Moolenbroek 	  {
602*b89261baSDavid van Moolenbroek 	    /* use process state to break the tie */
603*b89261baSDavid van Moolenbroek 	    if ((result = (long) (sorted_state[p2->pr_state] -
604*b89261baSDavid van Moolenbroek 				  sorted_state[p1->pr_state])) == 0)
605*b89261baSDavid van Moolenbroek 	      {
606*b89261baSDavid van Moolenbroek 		/* use priority to break the tie */
607*b89261baSDavid van Moolenbroek 		if ((result = p2->pr_oldpri - p1->pr_oldpri) == 0)
608*b89261baSDavid van Moolenbroek 		  {
609*b89261baSDavid van Moolenbroek 		    /* use resident set size (rssize) to break the tie */
610*b89261baSDavid van Moolenbroek 		    if ((result = p2->pr_rssize - p1->pr_rssize) == 0)
611*b89261baSDavid van Moolenbroek 		      {
612*b89261baSDavid van Moolenbroek 			/* use total memory to break the tie */
613*b89261baSDavid van Moolenbroek 			result = (p2->pr_size - p1->pr_size);
614*b89261baSDavid van Moolenbroek 		      }
615*b89261baSDavid van Moolenbroek 		  }
616*b89261baSDavid van Moolenbroek 	      }
617*b89261baSDavid van Moolenbroek 	  }
618*b89261baSDavid van Moolenbroek       }
619*b89261baSDavid van Moolenbroek     return (result);
620*b89261baSDavid van Moolenbroek   }
621*b89261baSDavid van Moolenbroek 
622*b89261baSDavid van Moolenbroek /*
623*b89261baSDavid van Moolenbroek get process table
624*b89261baSDavid van Moolenbroek */
625*b89261baSDavid van Moolenbroek void
getptable(struct prpsinfo * baseptr)626*b89261baSDavid van Moolenbroek getptable (struct prpsinfo *baseptr)
627*b89261baSDavid van Moolenbroek {
628*b89261baSDavid van Moolenbroek   struct prpsinfo *currproc;	/* pointer to current proc structure	*/
629*b89261baSDavid van Moolenbroek   int numprocs = 0;
630*b89261baSDavid van Moolenbroek   struct dirent *direntp;
631*b89261baSDavid van Moolenbroek 
632*b89261baSDavid van Moolenbroek   for (rewinddir (proc_dir); direntp = readdir (proc_dir);)
633*b89261baSDavid van Moolenbroek     {
634*b89261baSDavid van Moolenbroek       int fd;
635*b89261baSDavid van Moolenbroek 
636*b89261baSDavid van Moolenbroek       if ((fd = open (direntp->d_name, O_RDONLY)) < 0)
637*b89261baSDavid van Moolenbroek 	continue;
638*b89261baSDavid van Moolenbroek 
639*b89261baSDavid van Moolenbroek       currproc = &baseptr[numprocs];
640*b89261baSDavid van Moolenbroek       if (ioctl (fd, PIOCPSINFO, currproc) < 0)
641*b89261baSDavid van Moolenbroek 	{
642*b89261baSDavid van Moolenbroek 	  (void) close (fd);
643*b89261baSDavid van Moolenbroek 	  continue;
644*b89261baSDavid van Moolenbroek 	}
645*b89261baSDavid van Moolenbroek 
646*b89261baSDavid van Moolenbroek       numprocs++;
647*b89261baSDavid van Moolenbroek       (void) close (fd);
648*b89261baSDavid van Moolenbroek     }
649*b89261baSDavid van Moolenbroek 
650*b89261baSDavid van Moolenbroek   if (nproc != numprocs)
651*b89261baSDavid van Moolenbroek     nproc = numprocs;
652*b89261baSDavid van Moolenbroek }
653*b89261baSDavid van Moolenbroek 
654*b89261baSDavid van Moolenbroek /* return the owner of the specified process, for use in commands.c as we're
655*b89261baSDavid van Moolenbroek    running setuid root */
656*b89261baSDavid van Moolenbroek int
proc_owner(int pid)657*b89261baSDavid van Moolenbroek proc_owner (int pid)
658*b89261baSDavid van Moolenbroek {
659*b89261baSDavid van Moolenbroek   register struct prpsinfo *p;
660*b89261baSDavid van Moolenbroek   int i;
661*b89261baSDavid van Moolenbroek   for (i = 0, p = pbase; i < nproc; i++, p++)
662*b89261baSDavid van Moolenbroek     if (p->pr_pid == (pid_t)pid)
663*b89261baSDavid van Moolenbroek       return (p->pr_uid);
664*b89261baSDavid van Moolenbroek 
665*b89261baSDavid van Moolenbroek   return (-1);
666*b89261baSDavid van Moolenbroek }
667*b89261baSDavid van Moolenbroek 
668*b89261baSDavid van Moolenbroek #ifndef HAVE_SETPRIORITY
669*b89261baSDavid van Moolenbroek int
setpriority(int dummy,int who,int niceval)670*b89261baSDavid van Moolenbroek setpriority (int dummy, int who, int niceval)
671*b89261baSDavid van Moolenbroek {
672*b89261baSDavid van Moolenbroek   int scale;
673*b89261baSDavid van Moolenbroek   int prio;
674*b89261baSDavid van Moolenbroek   pcinfo_t pcinfo;
675*b89261baSDavid van Moolenbroek   pcparms_t pcparms;
676*b89261baSDavid van Moolenbroek   tsparms_t *tsparms;
677*b89261baSDavid van Moolenbroek 
678*b89261baSDavid van Moolenbroek   strcpy (pcinfo.pc_clname, "TS");
679*b89261baSDavid van Moolenbroek   if (priocntl (0, 0, PC_GETCID, (caddr_t) & pcinfo) == -1)
680*b89261baSDavid van Moolenbroek     return (-1);
681*b89261baSDavid van Moolenbroek 
682*b89261baSDavid van Moolenbroek   prio = niceval;
683*b89261baSDavid van Moolenbroek   if (prio > PRIO_MAX)
684*b89261baSDavid van Moolenbroek     prio = PRIO_MAX;
685*b89261baSDavid van Moolenbroek   else if (prio < PRIO_MIN)
686*b89261baSDavid van Moolenbroek     prio = PRIO_MIN;
687*b89261baSDavid van Moolenbroek 
688*b89261baSDavid van Moolenbroek   tsparms = (tsparms_t *) pcparms.pc_clparms;
689*b89261baSDavid van Moolenbroek   scale = ((tsinfo_t *) pcinfo.pc_clinfo)->ts_maxupri;
690*b89261baSDavid van Moolenbroek   tsparms->ts_uprilim = tsparms->ts_upri = -(scale * prio) / 20;
691*b89261baSDavid van Moolenbroek   pcparms.pc_cid = pcinfo.pc_cid;
692*b89261baSDavid van Moolenbroek 
693*b89261baSDavid van Moolenbroek   if (priocntl (P_PID, who, PC_SETPARMS, (caddr_t) & pcparms) == -1)
694*b89261baSDavid van Moolenbroek     return (-1);
695*b89261baSDavid van Moolenbroek 
696*b89261baSDavid van Moolenbroek   return (0);
697*b89261baSDavid van Moolenbroek }
698*b89261baSDavid van Moolenbroek #endif
699*b89261baSDavid van Moolenbroek 
700*b89261baSDavid van Moolenbroek /****************************************************************
701*b89261baSDavid van Moolenbroek  * read_sysinfos() -						*
702*b89261baSDavid van Moolenbroek  *	Read all of the CPU specific sysinfo sturctures in from	*
703*b89261baSDavid van Moolenbroek  *	the /stats file system.					*
704*b89261baSDavid van Moolenbroek  ****************************************************************/
read_sysinfos(num_cpus,buf)705*b89261baSDavid van Moolenbroek read_sysinfos(num_cpus, buf)
706*b89261baSDavid van Moolenbroek 	int num_cpus;
707*b89261baSDavid van Moolenbroek 	struct sysinfo	*buf;
708*b89261baSDavid van Moolenbroek {
709*b89261baSDavid van Moolenbroek 
710*b89261baSDavid van Moolenbroek 	static int	fd1=0;	/* file descriptor for /stats/sysinfo */
711*b89261baSDavid van Moolenbroek 	int		read_sz;
712*b89261baSDavid van Moolenbroek 
713*b89261baSDavid van Moolenbroek 	/* Open /stats/sysinfo one time only and leave it open */
714*b89261baSDavid van Moolenbroek 	if (fd1==0) {
715*b89261baSDavid van Moolenbroek 		if ((fd1 = open("/stats/sysinfo", O_RDONLY)) == -1)
716*b89261baSDavid van Moolenbroek 			(void) fprintf (stderr, "%s: Open of /stats/sysinfo failed\n", myname);
717*b89261baSDavid van Moolenbroek 	}
718*b89261baSDavid van Moolenbroek 	/* reset the read pointer to the beginning of the file */
719*b89261baSDavid van Moolenbroek 	if (lseek(fd1, 0L, SEEK_SET) == -1)
720*b89261baSDavid van Moolenbroek 		(void) fprintf (stderr, "%s: lseek to beginning of /stats/sysinfo failed\n", myname);
721*b89261baSDavid van Moolenbroek 	read_sz = num_cpus * sizeof(buf[0]);
722*b89261baSDavid van Moolenbroek 	if (read(fd1, buf, read_sz) != read_sz)
723*b89261baSDavid van Moolenbroek 		(void) fprintf (stderr, "%s: Read of /stats/sysinfo failed\n", myname);
724*b89261baSDavid van Moolenbroek }
725*b89261baSDavid van Moolenbroek 
726*b89261baSDavid van Moolenbroek /****************************************************************
727*b89261baSDavid van Moolenbroek  * sysinfo_data() -						*
728*b89261baSDavid van Moolenbroek  *	Add up all of the CPU specific sysinfo sturctures to	*
729*b89261baSDavid van Moolenbroek  *	make the GLOBAL sysinfo.				*
730*b89261baSDavid van Moolenbroek  ****************************************************************/
sysinfo_data(num_cpus,global_si,percpu_si)731*b89261baSDavid van Moolenbroek sysinfo_data(num_cpus, global_si, percpu_si)
732*b89261baSDavid van Moolenbroek 	int num_cpus;
733*b89261baSDavid van Moolenbroek 	struct sysinfo	*global_si;
734*b89261baSDavid van Moolenbroek 	struct sysinfo	*percpu_si;
735*b89261baSDavid van Moolenbroek {
736*b89261baSDavid van Moolenbroek 	struct sysinfo	*percpu_p;
737*b89261baSDavid van Moolenbroek 	int		cpu, i, *global, *src;
738*b89261baSDavid van Moolenbroek 
739*b89261baSDavid van Moolenbroek 	/* null out the global statistics from last sample */
740*b89261baSDavid van Moolenbroek 	memset(global_si, 0, sizeof(struct sysinfo));
741*b89261baSDavid van Moolenbroek 
742*b89261baSDavid van Moolenbroek 	percpu_p = (struct sysinfo *)percpu_si;
743*b89261baSDavid van Moolenbroek 	for(cpu = 0; cpu < num_cpus; cpu++) {
744*b89261baSDavid van Moolenbroek 		global = (int *)global_si;
745*b89261baSDavid van Moolenbroek 		src = (int *)percpu_p;
746*b89261baSDavid van Moolenbroek 
747*b89261baSDavid van Moolenbroek 		/* assume sysinfo ends on an int boundary */
748*b89261baSDavid van Moolenbroek 		/* Currently, all of the struct sysinfo members are the same
749*b89261baSDavid van Moolenbroek 		 * size as an int. If that changes, we may not be able to
750*b89261baSDavid van Moolenbroek 		 * do this. But this should be safe.
751*b89261baSDavid van Moolenbroek 		 */
752*b89261baSDavid van Moolenbroek 		for(i=0; i<sizeof(struct sysinfo)/sizeof(int); i++) {
753*b89261baSDavid van Moolenbroek 			*global++ += *src++;
754*b89261baSDavid van Moolenbroek 		}
755*b89261baSDavid van Moolenbroek 		percpu_p++;
756*b89261baSDavid van Moolenbroek 	}
757*b89261baSDavid van Moolenbroek }
758