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: For FreeBSD 5.x, 6.x, 7.x, 8.x
37*b89261baSDavid van Moolenbroek *
38*b89261baSDavid van Moolenbroek * DESCRIPTION:
39*b89261baSDavid van Moolenbroek * Originally written for BSD4.4 system by Christos Zoulas.
40*b89261baSDavid van Moolenbroek * Ported to FreeBSD 2.x by Steven Wallace && Wolfram Schneider
41*b89261baSDavid van Moolenbroek * Order support hacked in from top-3.5beta6/machine/m_aix41.c
42*b89261baSDavid van Moolenbroek * by Monte Mitzelfelt
43*b89261baSDavid van Moolenbroek * Ported to FreeBSD 5.x and higher by William LeFebvre
44*b89261baSDavid van Moolenbroek *
45*b89261baSDavid van Moolenbroek * AUTHOR: Christos Zoulas <christos@ee.cornell.edu>
46*b89261baSDavid van Moolenbroek * Steven Wallace <swallace@freebsd.org>
47*b89261baSDavid van Moolenbroek * Wolfram Schneider <wosch@FreeBSD.org>
48*b89261baSDavid van Moolenbroek */
49*b89261baSDavid van Moolenbroek
50*b89261baSDavid van Moolenbroek
51*b89261baSDavid van Moolenbroek #include <sys/time.h>
52*b89261baSDavid van Moolenbroek #include <sys/types.h>
53*b89261baSDavid van Moolenbroek #include <sys/signal.h>
54*b89261baSDavid van Moolenbroek #include <sys/param.h>
55*b89261baSDavid van Moolenbroek
56*b89261baSDavid van Moolenbroek #include "config.h"
57*b89261baSDavid van Moolenbroek #include <stdio.h>
58*b89261baSDavid van Moolenbroek #include <string.h>
59*b89261baSDavid van Moolenbroek #include <nlist.h>
60*b89261baSDavid van Moolenbroek #include <math.h>
61*b89261baSDavid van Moolenbroek #include <kvm.h>
62*b89261baSDavid van Moolenbroek #include <pwd.h>
63*b89261baSDavid van Moolenbroek #include <sys/errno.h>
64*b89261baSDavid van Moolenbroek #include <sys/sysctl.h>
65*b89261baSDavid van Moolenbroek #include <sys/dkstat.h>
66*b89261baSDavid van Moolenbroek #include <sys/file.h>
67*b89261baSDavid van Moolenbroek #include <sys/time.h>
68*b89261baSDavid van Moolenbroek #include <sys/proc.h>
69*b89261baSDavid van Moolenbroek #include <sys/user.h>
70*b89261baSDavid van Moolenbroek #include <sys/vmmeter.h>
71*b89261baSDavid van Moolenbroek #include <sys/resource.h>
72*b89261baSDavid van Moolenbroek #include <sys/rtprio.h>
73*b89261baSDavid van Moolenbroek #ifdef HAVE_UNISTD_H
74*b89261baSDavid van Moolenbroek #include <unistd.h>
75*b89261baSDavid van Moolenbroek #endif
76*b89261baSDavid van Moolenbroek
77*b89261baSDavid van Moolenbroek /* Swap */
78*b89261baSDavid van Moolenbroek #include <stdlib.h>
79*b89261baSDavid van Moolenbroek #include <sys/conf.h>
80*b89261baSDavid van Moolenbroek
81*b89261baSDavid van Moolenbroek #include <osreldate.h> /* for changes in kernel structures */
82*b89261baSDavid van Moolenbroek
83*b89261baSDavid van Moolenbroek #include "top.h"
84*b89261baSDavid van Moolenbroek #include "machine.h"
85*b89261baSDavid van Moolenbroek #include "utils.h"
86*b89261baSDavid van Moolenbroek #include "username.h"
87*b89261baSDavid van Moolenbroek #include "hash.h"
88*b89261baSDavid van Moolenbroek #include "display.h"
89*b89261baSDavid van Moolenbroek
90*b89261baSDavid van Moolenbroek extern char* printable __P((char *));
91*b89261baSDavid van Moolenbroek int swapmode __P((int *retavail, int *retfree));
92*b89261baSDavid van Moolenbroek static int smpmode;
93*b89261baSDavid van Moolenbroek static int namelength;
94*b89261baSDavid van Moolenbroek
95*b89261baSDavid van Moolenbroek /*
96*b89261baSDavid van Moolenbroek * Versions prior to 5.x do not track threads in kinfo_proc, so we
97*b89261baSDavid van Moolenbroek * simply do not display any information about them.
98*b89261baSDavid van Moolenbroek * Versions 5.x, 6.x, and 7.x track threads but the data reported
99*b89261baSDavid van Moolenbroek * as runtime for each thread is actually per-process and is just
100*b89261baSDavid van Moolenbroek * duplicated across all threads. It would be very wrong to show
101*b89261baSDavid van Moolenbroek * this data individually for each thread. Therefore we will show
102*b89261baSDavid van Moolenbroek * a THR column (number of threads) but not provide any sort of
103*b89261baSDavid van Moolenbroek * per-thread display. We distinguish between these three ways of
104*b89261baSDavid van Moolenbroek * handling threads as follows: HAS_THREADS indicates that the
105*b89261baSDavid van Moolenbroek * system has and tracks kernel threads (a THR column will appear
106*b89261baSDavid van Moolenbroek * in the display). HAS_SHOWTHREADS indicates that the system
107*b89261baSDavid van Moolenbroek * reports correct per-thread information and we will provide a
108*b89261baSDavid van Moolenbroek * per-thread display (the 'H' and 't' command) upon request.
109*b89261baSDavid van Moolenbroek * HAS_SHOWTHREADS implies HAS_THREADS.
110*b89261baSDavid van Moolenbroek */
111*b89261baSDavid van Moolenbroek
112*b89261baSDavid van Moolenbroek /* HAS_THREADS for anything 5.x and up */
113*b89261baSDavid van Moolenbroek #if OSMAJOR >= 5
114*b89261baSDavid van Moolenbroek #define HAS_THREADS
115*b89261baSDavid van Moolenbroek #endif
116*b89261baSDavid van Moolenbroek
117*b89261baSDavid van Moolenbroek /* HAS_SHOWTHREADS for anything 8.x and up */
118*b89261baSDavid van Moolenbroek #if OSMAJOR >=8
119*b89261baSDavid van Moolenbroek #define HAS_SHOWTHREADS
120*b89261baSDavid van Moolenbroek #endif
121*b89261baSDavid van Moolenbroek
122*b89261baSDavid van Moolenbroek /* get_process_info passes back a handle. This is what it looks like: */
123*b89261baSDavid van Moolenbroek
124*b89261baSDavid van Moolenbroek struct handle
125*b89261baSDavid van Moolenbroek {
126*b89261baSDavid van Moolenbroek struct kinfo_proc **next_proc; /* points to next valid proc pointer */
127*b89261baSDavid van Moolenbroek int remaining; /* number of pointers remaining */
128*b89261baSDavid van Moolenbroek };
129*b89261baSDavid van Moolenbroek
130*b89261baSDavid van Moolenbroek /* declarations for load_avg */
131*b89261baSDavid van Moolenbroek #include "loadavg.h"
132*b89261baSDavid van Moolenbroek
133*b89261baSDavid van Moolenbroek /*
134*b89261baSDavid van Moolenbroek * Macros to access process information:
135*b89261baSDavid van Moolenbroek * In versions 4.x and earlier the kinfo_proc structure was a collection of
136*b89261baSDavid van Moolenbroek * substructures (kp_proc and kp_eproc). Starting with 5.0 kinfo_proc was
137*b89261baSDavid van Moolenbroek * redesigned and "flattene" so that most of the information was available
138*b89261baSDavid van Moolenbroek * in a single structure. We use macros to access the various types of
139*b89261baSDavid van Moolenbroek * information and define these macros according to the OS revision. The
140*b89261baSDavid van Moolenbroek * names PP, EP, and VP are due to the fact that information was originally
141*b89261baSDavid van Moolenbroek * contained in the different substructures. We retain these names in the
142*b89261baSDavid van Moolenbroek * code for backward compatibility. These macros use ANSI concatenation.
143*b89261baSDavid van Moolenbroek * PP: proc
144*b89261baSDavid van Moolenbroek * EP: extented proc
145*b89261baSDavid van Moolenbroek * VP: vm (virtual memory information)
146*b89261baSDavid van Moolenbroek * PRUID: Real uid
147*b89261baSDavid van Moolenbroek * RP: rusage
148*b89261baSDavid van Moolenbroek * PPCPU: where we store calculated cpu% data
149*b89261baSDavid van Moolenbroek * SPPTR: where we store pointer to extra calculated data
150*b89261baSDavid van Moolenbroek * SP: access to the extra calculated data pointed to by SPPTR
151*b89261baSDavid van Moolenbroek */
152*b89261baSDavid van Moolenbroek #if OSMAJOR <= 4
153*b89261baSDavid van Moolenbroek #define PP(pp, field) ((pp)->kp_proc . p_##field)
154*b89261baSDavid van Moolenbroek #define EP(pp, field) ((pp)->kp_eproc . e_##field)
155*b89261baSDavid van Moolenbroek #define VP(pp, field) ((pp)->kp_eproc.e_vm . vm_##field)
156*b89261baSDavid van Moolenbroek #define PRUID(pp) ((pp)->kp_eproc.e_pcred.p_ruid)
157*b89261baSDavid van Moolenbroek #else
158*b89261baSDavid van Moolenbroek #define PP(pp, field) ((pp)->ki_##field)
159*b89261baSDavid van Moolenbroek #define EP(pp, field) ((pp)->ki_##field)
160*b89261baSDavid van Moolenbroek #define VP(pp, field) ((pp)->ki_##field)
161*b89261baSDavid van Moolenbroek #define PRUID(pp) ((pp)->ki_ruid)
162*b89261baSDavid van Moolenbroek #define RP(pp, field) ((pp)->ki_rusage.ru_##field)
163*b89261baSDavid van Moolenbroek #define PPCPU(pp) ((pp)->ki_sparelongs[0])
164*b89261baSDavid van Moolenbroek #define SPPTR(pp) ((pp)->ki_spareptrs[0])
165*b89261baSDavid van Moolenbroek #define SP(pp, field) (((struct save_proc *)((pp)->ki_spareptrs[0]))->sp_##field)
166*b89261baSDavid van Moolenbroek #endif
167*b89261baSDavid van Moolenbroek
168*b89261baSDavid van Moolenbroek /* what we consider to be process size: */
169*b89261baSDavid van Moolenbroek #if OSMAJOR <= 4
170*b89261baSDavid van Moolenbroek #define PROCSIZE(pp) (VP((pp), map.size) / 1024)
171*b89261baSDavid van Moolenbroek #else
172*b89261baSDavid van Moolenbroek #define PROCSIZE(pp) (((pp)->ki_size) / 1024)
173*b89261baSDavid van Moolenbroek #endif
174*b89261baSDavid van Moolenbroek
175*b89261baSDavid van Moolenbroek /* calculate a per-second rate using milliseconds */
176*b89261baSDavid van Moolenbroek #define per_second(n, msec) (((n) * 1000) / (msec))
177*b89261baSDavid van Moolenbroek
178*b89261baSDavid van Moolenbroek /* process state names for the "STATE" column of the display */
179*b89261baSDavid van Moolenbroek /* the extra nulls in the string "run" are for adding a slash and
180*b89261baSDavid van Moolenbroek the processor number when needed */
181*b89261baSDavid van Moolenbroek
182*b89261baSDavid van Moolenbroek char *state_abbrev[] =
183*b89261baSDavid van Moolenbroek {
184*b89261baSDavid van Moolenbroek "?", "START", "RUN", "SLEEP", "STOP", "ZOMB", "WAIT", "LOCK"
185*b89261baSDavid van Moolenbroek };
186*b89261baSDavid van Moolenbroek #define NUM_STATES 8
187*b89261baSDavid van Moolenbroek
188*b89261baSDavid van Moolenbroek /* kernel access */
189*b89261baSDavid van Moolenbroek static kvm_t *kd;
190*b89261baSDavid van Moolenbroek
191*b89261baSDavid van Moolenbroek /* these are for dealing with sysctl-based data */
192*b89261baSDavid van Moolenbroek #define MAXMIBLEN 8
193*b89261baSDavid van Moolenbroek struct sysctl_mib {
194*b89261baSDavid van Moolenbroek char *name;
195*b89261baSDavid van Moolenbroek int mib[MAXMIBLEN];
196*b89261baSDavid van Moolenbroek size_t miblen;
197*b89261baSDavid van Moolenbroek };
198*b89261baSDavid van Moolenbroek static struct sysctl_mib mibs[] = {
199*b89261baSDavid van Moolenbroek { "vm.stats.sys.v_swtch" },
200*b89261baSDavid van Moolenbroek #define V_SWTCH 0
201*b89261baSDavid van Moolenbroek { "vm.stats.sys.v_trap" },
202*b89261baSDavid van Moolenbroek #define V_TRAP 1
203*b89261baSDavid van Moolenbroek { "vm.stats.sys.v_intr" },
204*b89261baSDavid van Moolenbroek #define V_INTR 2
205*b89261baSDavid van Moolenbroek { "vm.stats.sys.v_soft" },
206*b89261baSDavid van Moolenbroek #define V_SOFT 3
207*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_forks" },
208*b89261baSDavid van Moolenbroek #define V_FORKS 4
209*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_vforks" },
210*b89261baSDavid van Moolenbroek #define V_VFORKS 5
211*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_rforks" },
212*b89261baSDavid van Moolenbroek #define V_RFORKS 6
213*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_vm_faults" },
214*b89261baSDavid van Moolenbroek #define V_VM_FAULTS 7
215*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_swapin" },
216*b89261baSDavid van Moolenbroek #define V_SWAPIN 8
217*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_swapout" },
218*b89261baSDavid van Moolenbroek #define V_SWAPOUT 9
219*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_tfree" },
220*b89261baSDavid van Moolenbroek #define V_TFREE 10
221*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_vnodein" },
222*b89261baSDavid van Moolenbroek #define V_VNODEIN 11
223*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_vnodeout" },
224*b89261baSDavid van Moolenbroek #define V_VNODEOUT 12
225*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_active_count" },
226*b89261baSDavid van Moolenbroek #define V_ACTIVE_COUNT 13
227*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_inactive_count" },
228*b89261baSDavid van Moolenbroek #define V_INACTIVE_COUNT 14
229*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_wire_count" },
230*b89261baSDavid van Moolenbroek #define V_WIRE_COUNT 15
231*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_cache_count" },
232*b89261baSDavid van Moolenbroek #define V_CACHE_COUNT 16
233*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_free_count" },
234*b89261baSDavid van Moolenbroek #define V_FREE_COUNT 17
235*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_swappgsin" },
236*b89261baSDavid van Moolenbroek #define V_SWAPPGSIN 18
237*b89261baSDavid van Moolenbroek { "vm.stats.vm.v_swappgsout" },
238*b89261baSDavid van Moolenbroek #define V_SWAPPGSOUT 19
239*b89261baSDavid van Moolenbroek { "vfs.bufspace" },
240*b89261baSDavid van Moolenbroek #define VFS_BUFSPACE 20
241*b89261baSDavid van Moolenbroek { "kern.cp_time" },
242*b89261baSDavid van Moolenbroek #define K_CP_TIME 21
243*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
244*b89261baSDavid van Moolenbroek { "kern.proc.all" },
245*b89261baSDavid van Moolenbroek #else
246*b89261baSDavid van Moolenbroek { "kern.proc.proc" },
247*b89261baSDavid van Moolenbroek #endif
248*b89261baSDavid van Moolenbroek #define K_PROC 22
249*b89261baSDavid van Moolenbroek { NULL }
250*b89261baSDavid van Moolenbroek };
251*b89261baSDavid van Moolenbroek
252*b89261baSDavid van Moolenbroek
253*b89261baSDavid van Moolenbroek /* these are for calculating cpu state percentages */
254*b89261baSDavid van Moolenbroek
255*b89261baSDavid van Moolenbroek static long cp_time[CPUSTATES];
256*b89261baSDavid van Moolenbroek static long cp_old[CPUSTATES];
257*b89261baSDavid van Moolenbroek static long cp_diff[CPUSTATES];
258*b89261baSDavid van Moolenbroek
259*b89261baSDavid van Moolenbroek /* these are for detailing the process states */
260*b89261baSDavid van Moolenbroek
261*b89261baSDavid van Moolenbroek int process_states[8];
262*b89261baSDavid van Moolenbroek char *procstatenames[] = {
263*b89261baSDavid van Moolenbroek "", " starting, ", " running, ", " sleeping, ", " stopped, ", " zombie, ",
264*b89261baSDavid van Moolenbroek " waiting, ", " locked, ",
265*b89261baSDavid van Moolenbroek NULL
266*b89261baSDavid van Moolenbroek };
267*b89261baSDavid van Moolenbroek
268*b89261baSDavid van Moolenbroek /* these are for detailing the cpu states */
269*b89261baSDavid van Moolenbroek
270*b89261baSDavid van Moolenbroek int cpu_states[CPUSTATES];
271*b89261baSDavid van Moolenbroek char *cpustatenames[] = {
272*b89261baSDavid van Moolenbroek "user", "nice", "system", "interrupt", "idle", NULL
273*b89261baSDavid van Moolenbroek };
274*b89261baSDavid van Moolenbroek
275*b89261baSDavid van Moolenbroek /* these are for detailing the kernel information */
276*b89261baSDavid van Moolenbroek
277*b89261baSDavid van Moolenbroek int kernel_stats[9];
278*b89261baSDavid van Moolenbroek char *kernelnames[] = {
279*b89261baSDavid van Moolenbroek " ctxsw, ", " trap, ", " intr, ", " soft, ", " fork, ",
280*b89261baSDavid van Moolenbroek " flt, ", " pgin, ", " pgout, ", " fr",
281*b89261baSDavid van Moolenbroek NULL
282*b89261baSDavid van Moolenbroek };
283*b89261baSDavid van Moolenbroek
284*b89261baSDavid van Moolenbroek /* these are for detailing the memory statistics */
285*b89261baSDavid van Moolenbroek
286*b89261baSDavid van Moolenbroek long memory_stats[7];
287*b89261baSDavid van Moolenbroek char *memorynames[] = {
288*b89261baSDavid van Moolenbroek "K Active, ", "K Inact, ", "K Wired, ", "K Cache, ", "K Buf, ", "K Free",
289*b89261baSDavid van Moolenbroek NULL
290*b89261baSDavid van Moolenbroek };
291*b89261baSDavid van Moolenbroek
292*b89261baSDavid van Moolenbroek long swap_stats[7];
293*b89261baSDavid van Moolenbroek char *swapnames[] = {
294*b89261baSDavid van Moolenbroek /* 0 1 2 3 4 5 */
295*b89261baSDavid van Moolenbroek "K Total, ", "K Used, ", "K Free, ", "% Inuse, ", "K In, ", "K Out",
296*b89261baSDavid van Moolenbroek NULL
297*b89261baSDavid van Moolenbroek };
298*b89261baSDavid van Moolenbroek
299*b89261baSDavid van Moolenbroek
300*b89261baSDavid van Moolenbroek /*
301*b89261baSDavid van Moolenbroek * pbase points to the array that holds the kinfo_proc structures. pref
302*b89261baSDavid van Moolenbroek * (pronounced p-ref) points to an array of kinfo_proc pointers and is where
303*b89261baSDavid van Moolenbroek * we build up a list of processes we wish to display. Both pbase and pref are
304*b89261baSDavid van Moolenbroek * potentially resized on every call to get_process_info. psize is the number
305*b89261baSDavid van Moolenbroek * of procs for which we currently have space allocated. pref_len is the number
306*b89261baSDavid van Moolenbroek * of valid pointers in pref (this is used by proc_owner). We start psize off
307*b89261baSDavid van Moolenbroek * at -1 to ensure that space gets allocated on the first call to
308*b89261baSDavid van Moolenbroek * get_process_info.
309*b89261baSDavid van Moolenbroek */
310*b89261baSDavid van Moolenbroek
311*b89261baSDavid van Moolenbroek static int psize = -1;
312*b89261baSDavid van Moolenbroek static int pref_len;
313*b89261baSDavid van Moolenbroek static struct kinfo_proc *pbase = NULL;
314*b89261baSDavid van Moolenbroek static struct kinfo_proc **pref = NULL;
315*b89261baSDavid van Moolenbroek
316*b89261baSDavid van Moolenbroek /* this structure retains information from the proc array between samples */
317*b89261baSDavid van Moolenbroek struct save_proc {
318*b89261baSDavid van Moolenbroek pid_t sp_pid;
319*b89261baSDavid van Moolenbroek u_int64_t sp_runtime;
320*b89261baSDavid van Moolenbroek long sp_vcsw;
321*b89261baSDavid van Moolenbroek long sp_ivcsw;
322*b89261baSDavid van Moolenbroek long sp_inblock;
323*b89261baSDavid van Moolenbroek long sp_oublock;
324*b89261baSDavid van Moolenbroek long sp_majflt;
325*b89261baSDavid van Moolenbroek long sp_totalio;
326*b89261baSDavid van Moolenbroek long sp_old_nvcsw;
327*b89261baSDavid van Moolenbroek long sp_old_nivcsw;
328*b89261baSDavid van Moolenbroek long sp_old_inblock;
329*b89261baSDavid van Moolenbroek long sp_old_oublock;
330*b89261baSDavid van Moolenbroek long sp_old_majflt;
331*b89261baSDavid van Moolenbroek };
332*b89261baSDavid van Moolenbroek hash_table *procs;
333*b89261baSDavid van Moolenbroek
334*b89261baSDavid van Moolenbroek struct proc_field {
335*b89261baSDavid van Moolenbroek char *name;
336*b89261baSDavid van Moolenbroek int width;
337*b89261baSDavid van Moolenbroek int rjust;
338*b89261baSDavid van Moolenbroek int min_screenwidth;
339*b89261baSDavid van Moolenbroek int (*format)(char *, int, struct kinfo_proc *);
340*b89261baSDavid van Moolenbroek };
341*b89261baSDavid van Moolenbroek
342*b89261baSDavid van Moolenbroek /* these are for getting the memory statistics */
343*b89261baSDavid van Moolenbroek
344*b89261baSDavid van Moolenbroek static int pagesize; /* kept from getpagesize */
345*b89261baSDavid van Moolenbroek static int pageshift; /* log base 2 of the pagesize */
346*b89261baSDavid van Moolenbroek
347*b89261baSDavid van Moolenbroek /* define pagetok in terms of pageshift */
348*b89261baSDavid van Moolenbroek
349*b89261baSDavid van Moolenbroek #define pagetok(size) ((size) << pageshift)
350*b89261baSDavid van Moolenbroek
351*b89261baSDavid van Moolenbroek /* things that we track between updates */
352*b89261baSDavid van Moolenbroek static u_int ctxsws = 0;
353*b89261baSDavid van Moolenbroek static u_int traps = 0;
354*b89261baSDavid van Moolenbroek static u_int intrs = 0;
355*b89261baSDavid van Moolenbroek static u_int softs = 0;
356*b89261baSDavid van Moolenbroek static u_int64_t forks = 0;
357*b89261baSDavid van Moolenbroek static u_int pfaults;
358*b89261baSDavid van Moolenbroek static u_int pagein;
359*b89261baSDavid van Moolenbroek static u_int pageout;
360*b89261baSDavid van Moolenbroek static u_int tfreed;
361*b89261baSDavid van Moolenbroek static int swappgsin = -1;
362*b89261baSDavid van Moolenbroek static int swappgsout = -1;
363*b89261baSDavid van Moolenbroek extern struct timeval timeout;
364*b89261baSDavid van Moolenbroek static struct timeval lasttime = { 0, 0 };
365*b89261baSDavid van Moolenbroek static long elapsed_time;
366*b89261baSDavid van Moolenbroek static long elapsed_msecs;
367*b89261baSDavid van Moolenbroek
368*b89261baSDavid van Moolenbroek /* things that we track during an update */
369*b89261baSDavid van Moolenbroek static long total_io;
370*b89261baSDavid van Moolenbroek static int show_fullcmd;
371*b89261baSDavid van Moolenbroek static struct handle handle;
372*b89261baSDavid van Moolenbroek static int username_length;
373*b89261baSDavid van Moolenbroek static int show_usernames;
374*b89261baSDavid van Moolenbroek static int display_mode;
375*b89261baSDavid van Moolenbroek static int *display_fields;
376*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
377*b89261baSDavid van Moolenbroek static int show_threads = 0;
378*b89261baSDavid van Moolenbroek #endif
379*b89261baSDavid van Moolenbroek
380*b89261baSDavid van Moolenbroek
381*b89261baSDavid van Moolenbroek /* sorting orders. first is default */
382*b89261baSDavid van Moolenbroek char *ordernames[] = {
383*b89261baSDavid van Moolenbroek "cpu", "size", "res", "time", "pri", "io", "pid", NULL
384*b89261baSDavid van Moolenbroek };
385*b89261baSDavid van Moolenbroek
386*b89261baSDavid van Moolenbroek /* compare routines */
387*b89261baSDavid van Moolenbroek int proc_compare(), compare_size(), compare_res(), compare_time(),
388*b89261baSDavid van Moolenbroek compare_prio(), compare_io(), compare_pid();
389*b89261baSDavid van Moolenbroek
390*b89261baSDavid van Moolenbroek int (*proc_compares[])() = {
391*b89261baSDavid van Moolenbroek proc_compare,
392*b89261baSDavid van Moolenbroek compare_size,
393*b89261baSDavid van Moolenbroek compare_res,
394*b89261baSDavid van Moolenbroek compare_time,
395*b89261baSDavid van Moolenbroek compare_prio,
396*b89261baSDavid van Moolenbroek compare_io,
397*b89261baSDavid van Moolenbroek compare_pid,
398*b89261baSDavid van Moolenbroek NULL
399*b89261baSDavid van Moolenbroek };
400*b89261baSDavid van Moolenbroek
401*b89261baSDavid van Moolenbroek /* swap related calculations */
402*b89261baSDavid van Moolenbroek
403*b89261baSDavid van Moolenbroek static int mib_swapinfo[16];
404*b89261baSDavid van Moolenbroek static int *mib_swapinfo_idx;
405*b89261baSDavid van Moolenbroek static int mib_swapinfo_size = 0;
406*b89261baSDavid van Moolenbroek
407*b89261baSDavid van Moolenbroek void
swap_init()408*b89261baSDavid van Moolenbroek swap_init()
409*b89261baSDavid van Moolenbroek
410*b89261baSDavid van Moolenbroek {
411*b89261baSDavid van Moolenbroek size_t m;
412*b89261baSDavid van Moolenbroek
413*b89261baSDavid van Moolenbroek m = sizeof(mib_swapinfo) / sizeof(mib_swapinfo[0]);
414*b89261baSDavid van Moolenbroek if (sysctlnametomib("vm.swap_info", mib_swapinfo, &m) != -1)
415*b89261baSDavid van Moolenbroek {
416*b89261baSDavid van Moolenbroek mib_swapinfo_size = m + 1;
417*b89261baSDavid van Moolenbroek mib_swapinfo_idx = &(mib_swapinfo[m]);
418*b89261baSDavid van Moolenbroek }
419*b89261baSDavid van Moolenbroek }
420*b89261baSDavid van Moolenbroek
421*b89261baSDavid van Moolenbroek int
swap_getdata(long long * retavail,long long * retfree)422*b89261baSDavid van Moolenbroek swap_getdata(long long *retavail, long long *retfree)
423*b89261baSDavid van Moolenbroek
424*b89261baSDavid van Moolenbroek {
425*b89261baSDavid van Moolenbroek int n;
426*b89261baSDavid van Moolenbroek size_t size;
427*b89261baSDavid van Moolenbroek long long total = 0;
428*b89261baSDavid van Moolenbroek long long used = 0;
429*b89261baSDavid van Moolenbroek struct xswdev xsw;
430*b89261baSDavid van Moolenbroek
431*b89261baSDavid van Moolenbroek n = 0;
432*b89261baSDavid van Moolenbroek if (mib_swapinfo_size > 0)
433*b89261baSDavid van Moolenbroek {
434*b89261baSDavid van Moolenbroek *mib_swapinfo_idx = 0;
435*b89261baSDavid van Moolenbroek while (size = sizeof(xsw),
436*b89261baSDavid van Moolenbroek sysctl(mib_swapinfo, mib_swapinfo_size, &xsw, &size, NULL, 0) != -1)
437*b89261baSDavid van Moolenbroek {
438*b89261baSDavid van Moolenbroek dprintf("swap_getdata: swaparea %d: nblks %d, used %d\n",
439*b89261baSDavid van Moolenbroek n, xsw.xsw_nblks, xsw.xsw_used);
440*b89261baSDavid van Moolenbroek total += (long long)xsw.xsw_nblks;
441*b89261baSDavid van Moolenbroek used += (long long)xsw.xsw_used;
442*b89261baSDavid van Moolenbroek *mib_swapinfo_idx = ++n;
443*b89261baSDavid van Moolenbroek }
444*b89261baSDavid van Moolenbroek
445*b89261baSDavid van Moolenbroek *retavail = pagetok(total);
446*b89261baSDavid van Moolenbroek *retfree = pagetok(total) - pagetok(used);
447*b89261baSDavid van Moolenbroek
448*b89261baSDavid van Moolenbroek if (total > 0)
449*b89261baSDavid van Moolenbroek {
450*b89261baSDavid van Moolenbroek n = (int)((double)used * 100.0 / (double)total);
451*b89261baSDavid van Moolenbroek }
452*b89261baSDavid van Moolenbroek else
453*b89261baSDavid van Moolenbroek {
454*b89261baSDavid van Moolenbroek n = 0;
455*b89261baSDavid van Moolenbroek }
456*b89261baSDavid van Moolenbroek }
457*b89261baSDavid van Moolenbroek else
458*b89261baSDavid van Moolenbroek {
459*b89261baSDavid van Moolenbroek *retavail = 0;
460*b89261baSDavid van Moolenbroek *retfree = 0;
461*b89261baSDavid van Moolenbroek }
462*b89261baSDavid van Moolenbroek
463*b89261baSDavid van Moolenbroek dprintf("swap_getdata: avail %lld, free %lld, %d%%\n",
464*b89261baSDavid van Moolenbroek *retavail, *retfree, n);
465*b89261baSDavid van Moolenbroek return(n);
466*b89261baSDavid van Moolenbroek }
467*b89261baSDavid van Moolenbroek
468*b89261baSDavid van Moolenbroek /*
469*b89261baSDavid van Moolenbroek * getkval(offset, ptr, size) - get a value out of the kernel.
470*b89261baSDavid van Moolenbroek * "offset" is the byte offset into the kernel for the desired value,
471*b89261baSDavid van Moolenbroek * "ptr" points to a buffer into which the value is retrieved,
472*b89261baSDavid van Moolenbroek * "size" is the size of the buffer (and the object to retrieve).
473*b89261baSDavid van Moolenbroek * Return 0 on success, -1 on any kind of failure.
474*b89261baSDavid van Moolenbroek */
475*b89261baSDavid van Moolenbroek
476*b89261baSDavid van Moolenbroek static int
getkval(unsigned long offset,int * ptr,int size)477*b89261baSDavid van Moolenbroek getkval(unsigned long offset, int *ptr, int size)
478*b89261baSDavid van Moolenbroek
479*b89261baSDavid van Moolenbroek {
480*b89261baSDavid van Moolenbroek if (kd != NULL)
481*b89261baSDavid van Moolenbroek {
482*b89261baSDavid van Moolenbroek if (kvm_read(kd, offset, (char *) ptr, size) == size)
483*b89261baSDavid van Moolenbroek {
484*b89261baSDavid van Moolenbroek return(0);
485*b89261baSDavid van Moolenbroek }
486*b89261baSDavid van Moolenbroek }
487*b89261baSDavid van Moolenbroek return(-1);
488*b89261baSDavid van Moolenbroek }
489*b89261baSDavid van Moolenbroek
490*b89261baSDavid van Moolenbroek int
get_sysctl_mibs()491*b89261baSDavid van Moolenbroek get_sysctl_mibs()
492*b89261baSDavid van Moolenbroek
493*b89261baSDavid van Moolenbroek {
494*b89261baSDavid van Moolenbroek struct sysctl_mib *mp;
495*b89261baSDavid van Moolenbroek size_t len;
496*b89261baSDavid van Moolenbroek
497*b89261baSDavid van Moolenbroek mp = mibs;
498*b89261baSDavid van Moolenbroek while (mp->name != NULL)
499*b89261baSDavid van Moolenbroek {
500*b89261baSDavid van Moolenbroek len = MAXMIBLEN;
501*b89261baSDavid van Moolenbroek if (sysctlnametomib(mp->name, mp->mib, &len) == -1)
502*b89261baSDavid van Moolenbroek {
503*b89261baSDavid van Moolenbroek message_error(" sysctlnametomib: %s", strerror(errno));
504*b89261baSDavid van Moolenbroek return -1;
505*b89261baSDavid van Moolenbroek }
506*b89261baSDavid van Moolenbroek mp->miblen = len;
507*b89261baSDavid van Moolenbroek mp++;
508*b89261baSDavid van Moolenbroek }
509*b89261baSDavid van Moolenbroek return 0;
510*b89261baSDavid van Moolenbroek }
511*b89261baSDavid van Moolenbroek
512*b89261baSDavid van Moolenbroek int
get_sysctl(int idx,void * v,size_t l)513*b89261baSDavid van Moolenbroek get_sysctl(int idx, void *v, size_t l)
514*b89261baSDavid van Moolenbroek
515*b89261baSDavid van Moolenbroek {
516*b89261baSDavid van Moolenbroek struct sysctl_mib *m;
517*b89261baSDavid van Moolenbroek size_t len;
518*b89261baSDavid van Moolenbroek
519*b89261baSDavid van Moolenbroek m = &(mibs[idx]);
520*b89261baSDavid van Moolenbroek len = l;
521*b89261baSDavid van Moolenbroek if (sysctl(m->mib, m->miblen, v, &len, NULL, 0) == -1)
522*b89261baSDavid van Moolenbroek {
523*b89261baSDavid van Moolenbroek message_error(" sysctl: %s", strerror(errno));
524*b89261baSDavid van Moolenbroek return -1;
525*b89261baSDavid van Moolenbroek }
526*b89261baSDavid van Moolenbroek return len;
527*b89261baSDavid van Moolenbroek }
528*b89261baSDavid van Moolenbroek
529*b89261baSDavid van Moolenbroek size_t
get_sysctlsize(int idx)530*b89261baSDavid van Moolenbroek get_sysctlsize(int idx)
531*b89261baSDavid van Moolenbroek
532*b89261baSDavid van Moolenbroek {
533*b89261baSDavid van Moolenbroek size_t len;
534*b89261baSDavid van Moolenbroek struct sysctl_mib *m;
535*b89261baSDavid van Moolenbroek
536*b89261baSDavid van Moolenbroek m = &(mibs[idx]);
537*b89261baSDavid van Moolenbroek if (sysctl(m->mib, m->miblen, NULL, &len, NULL, 0) == -1)
538*b89261baSDavid van Moolenbroek {
539*b89261baSDavid van Moolenbroek message_error(" sysctl (size): %s", strerror(errno));
540*b89261baSDavid van Moolenbroek len = 0;
541*b89261baSDavid van Moolenbroek }
542*b89261baSDavid van Moolenbroek return len;
543*b89261baSDavid van Moolenbroek }
544*b89261baSDavid van Moolenbroek
545*b89261baSDavid van Moolenbroek int
fmt_pid(char * buf,int sz,struct kinfo_proc * pp)546*b89261baSDavid van Moolenbroek fmt_pid(char *buf, int sz, struct kinfo_proc *pp)
547*b89261baSDavid van Moolenbroek
548*b89261baSDavid van Moolenbroek {
549*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6d", PP(pp, pid));
550*b89261baSDavid van Moolenbroek }
551*b89261baSDavid van Moolenbroek
552*b89261baSDavid van Moolenbroek int
fmt_username(char * buf,int sz,struct kinfo_proc * pp)553*b89261baSDavid van Moolenbroek fmt_username(char *buf, int sz, struct kinfo_proc *pp)
554*b89261baSDavid van Moolenbroek
555*b89261baSDavid van Moolenbroek {
556*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%-*.*s",
557*b89261baSDavid van Moolenbroek username_length, username_length, username(PRUID(pp)));
558*b89261baSDavid van Moolenbroek }
559*b89261baSDavid van Moolenbroek
560*b89261baSDavid van Moolenbroek int
fmt_uid(char * buf,int sz,struct kinfo_proc * pp)561*b89261baSDavid van Moolenbroek fmt_uid(char *buf, int sz, struct kinfo_proc *pp)
562*b89261baSDavid van Moolenbroek
563*b89261baSDavid van Moolenbroek {
564*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6d", PRUID(pp));
565*b89261baSDavid van Moolenbroek }
566*b89261baSDavid van Moolenbroek
567*b89261baSDavid van Moolenbroek int
fmt_thr(char * buf,int sz,struct kinfo_proc * pp)568*b89261baSDavid van Moolenbroek fmt_thr(char *buf, int sz, struct kinfo_proc *pp)
569*b89261baSDavid van Moolenbroek
570*b89261baSDavid van Moolenbroek {
571*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%3d", PP(pp, numthreads));
572*b89261baSDavid van Moolenbroek }
573*b89261baSDavid van Moolenbroek
574*b89261baSDavid van Moolenbroek int
fmt_pri(char * buf,int sz,struct kinfo_proc * pp)575*b89261baSDavid van Moolenbroek fmt_pri(char *buf, int sz, struct kinfo_proc *pp)
576*b89261baSDavid van Moolenbroek
577*b89261baSDavid van Moolenbroek {
578*b89261baSDavid van Moolenbroek #if OSMAJOR <= 4
579*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%3d", PP(pp, priority));
580*b89261baSDavid van Moolenbroek #else
581*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%3d", PP(pp, pri.pri_level));
582*b89261baSDavid van Moolenbroek #endif
583*b89261baSDavid van Moolenbroek }
584*b89261baSDavid van Moolenbroek
585*b89261baSDavid van Moolenbroek int
fmt_nice(char * buf,int sz,struct kinfo_proc * pp)586*b89261baSDavid van Moolenbroek fmt_nice(char *buf, int sz, struct kinfo_proc *pp)
587*b89261baSDavid van Moolenbroek
588*b89261baSDavid van Moolenbroek {
589*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%4d", PP(pp, nice) - NZERO);
590*b89261baSDavid van Moolenbroek }
591*b89261baSDavid van Moolenbroek
592*b89261baSDavid van Moolenbroek int
fmt_size(char * buf,int sz,struct kinfo_proc * pp)593*b89261baSDavid van Moolenbroek fmt_size(char *buf, int sz, struct kinfo_proc *pp)
594*b89261baSDavid van Moolenbroek
595*b89261baSDavid van Moolenbroek {
596*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%5s", format_k(PROCSIZE(pp)));
597*b89261baSDavid van Moolenbroek }
598*b89261baSDavid van Moolenbroek
599*b89261baSDavid van Moolenbroek int
fmt_res(char * buf,int sz,struct kinfo_proc * pp)600*b89261baSDavid van Moolenbroek fmt_res(char *buf, int sz, struct kinfo_proc *pp)
601*b89261baSDavid van Moolenbroek
602*b89261baSDavid van Moolenbroek {
603*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%5s", format_k(pagetok(VP(pp, rssize))));
604*b89261baSDavid van Moolenbroek }
605*b89261baSDavid van Moolenbroek
606*b89261baSDavid van Moolenbroek int
fmt_state(char * buf,int sz,struct kinfo_proc * pp)607*b89261baSDavid van Moolenbroek fmt_state(char *buf, int sz, struct kinfo_proc *pp)
608*b89261baSDavid van Moolenbroek
609*b89261baSDavid van Moolenbroek {
610*b89261baSDavid van Moolenbroek int state;
611*b89261baSDavid van Moolenbroek char status[16];
612*b89261baSDavid van Moolenbroek
613*b89261baSDavid van Moolenbroek state = PP(pp, stat);
614*b89261baSDavid van Moolenbroek switch(state)
615*b89261baSDavid van Moolenbroek {
616*b89261baSDavid van Moolenbroek case SRUN:
617*b89261baSDavid van Moolenbroek if (smpmode && PP(pp, oncpu) != 0xff)
618*b89261baSDavid van Moolenbroek sprintf(status, "CPU%d", PP(pp, oncpu));
619*b89261baSDavid van Moolenbroek else
620*b89261baSDavid van Moolenbroek strcpy(status, "RUN");
621*b89261baSDavid van Moolenbroek break;
622*b89261baSDavid van Moolenbroek
623*b89261baSDavid van Moolenbroek case SSLEEP:
624*b89261baSDavid van Moolenbroek if (EP(pp, wmesg) != NULL) {
625*b89261baSDavid van Moolenbroek sprintf(status, "%.6s", EP(pp, wmesg));
626*b89261baSDavid van Moolenbroek break;
627*b89261baSDavid van Moolenbroek }
628*b89261baSDavid van Moolenbroek /* fall through */
629*b89261baSDavid van Moolenbroek default:
630*b89261baSDavid van Moolenbroek if (state >= 0 && state < NUM_STATES)
631*b89261baSDavid van Moolenbroek sprintf(status, "%.6s", state_abbrev[(unsigned char) state]);
632*b89261baSDavid van Moolenbroek else
633*b89261baSDavid van Moolenbroek sprintf(status, "?%-5d", state);
634*b89261baSDavid van Moolenbroek break;
635*b89261baSDavid van Moolenbroek }
636*b89261baSDavid van Moolenbroek
637*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%-6.6s", status);
638*b89261baSDavid van Moolenbroek }
639*b89261baSDavid van Moolenbroek
640*b89261baSDavid van Moolenbroek int
fmt_flags(char * buf,int sz,struct kinfo_proc * pp)641*b89261baSDavid van Moolenbroek fmt_flags(char *buf, int sz, struct kinfo_proc *pp)
642*b89261baSDavid van Moolenbroek
643*b89261baSDavid van Moolenbroek {
644*b89261baSDavid van Moolenbroek long flag;
645*b89261baSDavid van Moolenbroek char chrs[12];
646*b89261baSDavid van Moolenbroek char *p;
647*b89261baSDavid van Moolenbroek
648*b89261baSDavid van Moolenbroek flag = PP(pp, flag);
649*b89261baSDavid van Moolenbroek p = chrs;
650*b89261baSDavid van Moolenbroek if (PP(pp, nice) < NZERO)
651*b89261baSDavid van Moolenbroek *p++ = '<';
652*b89261baSDavid van Moolenbroek else if (PP(pp, nice) > NZERO)
653*b89261baSDavid van Moolenbroek *p++ = 'N';
654*b89261baSDavid van Moolenbroek if (flag & P_TRACED)
655*b89261baSDavid van Moolenbroek *p++ = 'X';
656*b89261baSDavid van Moolenbroek if (flag & P_WEXIT && PP(pp, stat) != SZOMB)
657*b89261baSDavid van Moolenbroek *p++ = 'E';
658*b89261baSDavid van Moolenbroek if (flag & P_PPWAIT)
659*b89261baSDavid van Moolenbroek *p++ = 'V';
660*b89261baSDavid van Moolenbroek if (flag & P_SYSTEM || PP(pp, lock) > 0)
661*b89261baSDavid van Moolenbroek *p++ = 'L';
662*b89261baSDavid van Moolenbroek if (PP(pp, kiflag) & KI_SLEADER)
663*b89261baSDavid van Moolenbroek *p++ = 's';
664*b89261baSDavid van Moolenbroek if (flag & P_CONTROLT)
665*b89261baSDavid van Moolenbroek *p++ = '+';
666*b89261baSDavid van Moolenbroek if (flag & P_JAILED)
667*b89261baSDavid van Moolenbroek *p++ = 'J';
668*b89261baSDavid van Moolenbroek *p = '\0';
669*b89261baSDavid van Moolenbroek
670*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%-3.3s", chrs);
671*b89261baSDavid van Moolenbroek }
672*b89261baSDavid van Moolenbroek
673*b89261baSDavid van Moolenbroek int
fmt_c(char * buf,int sz,struct kinfo_proc * pp)674*b89261baSDavid van Moolenbroek fmt_c(char *buf, int sz, struct kinfo_proc *pp)
675*b89261baSDavid van Moolenbroek
676*b89261baSDavid van Moolenbroek {
677*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%1x", PP(pp, lastcpu));
678*b89261baSDavid van Moolenbroek }
679*b89261baSDavid van Moolenbroek
680*b89261baSDavid van Moolenbroek int
fmt_time(char * buf,int sz,struct kinfo_proc * pp)681*b89261baSDavid van Moolenbroek fmt_time(char *buf, int sz, struct kinfo_proc *pp)
682*b89261baSDavid van Moolenbroek
683*b89261baSDavid van Moolenbroek {
684*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6s",
685*b89261baSDavid van Moolenbroek format_time((PP(pp, runtime) + 500000) / 1000000));
686*b89261baSDavid van Moolenbroek }
687*b89261baSDavid van Moolenbroek
688*b89261baSDavid van Moolenbroek int
fmt_cpu(char * buf,int sz,struct kinfo_proc * pp)689*b89261baSDavid van Moolenbroek fmt_cpu(char *buf, int sz, struct kinfo_proc *pp)
690*b89261baSDavid van Moolenbroek
691*b89261baSDavid van Moolenbroek {
692*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%5.2f%%", (double)PPCPU(pp) / 100.0);
693*b89261baSDavid van Moolenbroek }
694*b89261baSDavid van Moolenbroek
695*b89261baSDavid van Moolenbroek int
fmt_command(char * buf,int sz,struct kinfo_proc * pp)696*b89261baSDavid van Moolenbroek fmt_command(char *buf, int sz, struct kinfo_proc *pp)
697*b89261baSDavid van Moolenbroek
698*b89261baSDavid van Moolenbroek {
699*b89261baSDavid van Moolenbroek int inmem;
700*b89261baSDavid van Moolenbroek char cmd[MAX_COLS];
701*b89261baSDavid van Moolenbroek char *bufp;
702*b89261baSDavid van Moolenbroek struct pargs pargs;
703*b89261baSDavid van Moolenbroek int len;
704*b89261baSDavid van Moolenbroek
705*b89261baSDavid van Moolenbroek #if OSMAJOR <= 4
706*b89261baSDavid van Moolenbroek inmem = (PP(pp, flag) & P_INMEM);
707*b89261baSDavid van Moolenbroek #else
708*b89261baSDavid van Moolenbroek inmem = (PP(pp, sflag) & PS_INMEM);
709*b89261baSDavid van Moolenbroek #endif
710*b89261baSDavid van Moolenbroek
711*b89261baSDavid van Moolenbroek if (show_fullcmd && inmem)
712*b89261baSDavid van Moolenbroek {
713*b89261baSDavid van Moolenbroek /* get the pargs structure */
714*b89261baSDavid van Moolenbroek if (getkval((unsigned long)PP(pp, args), (int *)&pargs, sizeof(pargs)) != -1)
715*b89261baSDavid van Moolenbroek {
716*b89261baSDavid van Moolenbroek /* determine workable length */
717*b89261baSDavid van Moolenbroek if ((len = pargs.ar_length) >= MAX_COLS)
718*b89261baSDavid van Moolenbroek {
719*b89261baSDavid van Moolenbroek len = MAX_COLS - 1;
720*b89261baSDavid van Moolenbroek }
721*b89261baSDavid van Moolenbroek
722*b89261baSDavid van Moolenbroek /* get the string from that */
723*b89261baSDavid van Moolenbroek if (len > 0 && getkval((unsigned long)PP(pp, args) +
724*b89261baSDavid van Moolenbroek sizeof(pargs.ar_ref) +
725*b89261baSDavid van Moolenbroek sizeof(pargs.ar_length),
726*b89261baSDavid van Moolenbroek (int *)cmd, len) != -1)
727*b89261baSDavid van Moolenbroek {
728*b89261baSDavid van Moolenbroek /* successfull retrieval: now convert nulls in to spaces */
729*b89261baSDavid van Moolenbroek bufp = cmd;
730*b89261baSDavid van Moolenbroek while (len-- > 0)
731*b89261baSDavid van Moolenbroek {
732*b89261baSDavid van Moolenbroek if (*bufp == '\0')
733*b89261baSDavid van Moolenbroek {
734*b89261baSDavid van Moolenbroek *bufp = ' ';
735*b89261baSDavid van Moolenbroek }
736*b89261baSDavid van Moolenbroek bufp++;
737*b89261baSDavid van Moolenbroek }
738*b89261baSDavid van Moolenbroek
739*b89261baSDavid van Moolenbroek /* null terminate cmd */
740*b89261baSDavid van Moolenbroek *--bufp = '\0';
741*b89261baSDavid van Moolenbroek
742*b89261baSDavid van Moolenbroek /* format cmd as our answer */
743*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%s", cmd);
744*b89261baSDavid van Moolenbroek }
745*b89261baSDavid van Moolenbroek }
746*b89261baSDavid van Moolenbroek }
747*b89261baSDavid van Moolenbroek
748*b89261baSDavid van Moolenbroek /* for anything else we just display comm */
749*b89261baSDavid van Moolenbroek return snprintf(buf, sz, inmem ? "%s" : "<%s>", printable(PP(pp, comm)));
750*b89261baSDavid van Moolenbroek }
751*b89261baSDavid van Moolenbroek
752*b89261baSDavid van Moolenbroek int
fmt_vcsw(char * buf,int sz,struct kinfo_proc * pp)753*b89261baSDavid van Moolenbroek fmt_vcsw(char *buf, int sz, struct kinfo_proc *pp)
754*b89261baSDavid van Moolenbroek
755*b89261baSDavid van Moolenbroek {
756*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, vcsw), elapsed_msecs));
757*b89261baSDavid van Moolenbroek }
758*b89261baSDavid van Moolenbroek
759*b89261baSDavid van Moolenbroek int
fmt_ivcsw(char * buf,int sz,struct kinfo_proc * pp)760*b89261baSDavid van Moolenbroek fmt_ivcsw(char *buf, int sz, struct kinfo_proc *pp)
761*b89261baSDavid van Moolenbroek
762*b89261baSDavid van Moolenbroek {
763*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, ivcsw), elapsed_msecs));
764*b89261baSDavid van Moolenbroek }
765*b89261baSDavid van Moolenbroek
766*b89261baSDavid van Moolenbroek int
fmt_read(char * buf,int sz,struct kinfo_proc * pp)767*b89261baSDavid van Moolenbroek fmt_read(char *buf, int sz, struct kinfo_proc *pp)
768*b89261baSDavid van Moolenbroek
769*b89261baSDavid van Moolenbroek {
770*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, inblock), elapsed_msecs));
771*b89261baSDavid van Moolenbroek }
772*b89261baSDavid van Moolenbroek
773*b89261baSDavid van Moolenbroek int
fmt_write(char * buf,int sz,struct kinfo_proc * pp)774*b89261baSDavid van Moolenbroek fmt_write(char *buf, int sz, struct kinfo_proc *pp)
775*b89261baSDavid van Moolenbroek
776*b89261baSDavid van Moolenbroek {
777*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, oublock), elapsed_msecs));
778*b89261baSDavid van Moolenbroek }
779*b89261baSDavid van Moolenbroek
780*b89261baSDavid van Moolenbroek int
fmt_fault(char * buf,int sz,struct kinfo_proc * pp)781*b89261baSDavid van Moolenbroek fmt_fault(char *buf, int sz, struct kinfo_proc *pp)
782*b89261baSDavid van Moolenbroek
783*b89261baSDavid van Moolenbroek {
784*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, majflt), elapsed_msecs));
785*b89261baSDavid van Moolenbroek }
786*b89261baSDavid van Moolenbroek
787*b89261baSDavid van Moolenbroek int
fmt_iototal(char * buf,int sz,struct kinfo_proc * pp)788*b89261baSDavid van Moolenbroek fmt_iototal(char *buf, int sz, struct kinfo_proc *pp)
789*b89261baSDavid van Moolenbroek
790*b89261baSDavid van Moolenbroek {
791*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6ld", per_second(SP(pp, totalio), elapsed_msecs));
792*b89261baSDavid van Moolenbroek }
793*b89261baSDavid van Moolenbroek
794*b89261baSDavid van Moolenbroek int
fmt_iopct(char * buf,int sz,struct kinfo_proc * pp)795*b89261baSDavid van Moolenbroek fmt_iopct(char *buf, int sz, struct kinfo_proc *pp)
796*b89261baSDavid van Moolenbroek
797*b89261baSDavid van Moolenbroek {
798*b89261baSDavid van Moolenbroek return snprintf(buf, sz, "%6.2f", (SP(pp, totalio) * 100.) / total_io);
799*b89261baSDavid van Moolenbroek }
800*b89261baSDavid van Moolenbroek
801*b89261baSDavid van Moolenbroek
802*b89261baSDavid van Moolenbroek struct proc_field proc_field[] = {
803*b89261baSDavid van Moolenbroek { "PID", 6, 1, 0, fmt_pid },
804*b89261baSDavid van Moolenbroek { "USERNAME", 8, 0, 0, fmt_username },
805*b89261baSDavid van Moolenbroek #define FIELD_USERNAME 1
806*b89261baSDavid van Moolenbroek { "UID", 6, 1, 0, fmt_uid },
807*b89261baSDavid van Moolenbroek #define FIELD_UID 2
808*b89261baSDavid van Moolenbroek { "THR", 3, 1, 0, fmt_thr },
809*b89261baSDavid van Moolenbroek { "PRI", 3, 1, 0, fmt_pri },
810*b89261baSDavid van Moolenbroek { "NICE", 4, 1, 0, fmt_nice },
811*b89261baSDavid van Moolenbroek { "SIZE", 5, 1, 0, fmt_size },
812*b89261baSDavid van Moolenbroek { "RES", 5, 1, 0, fmt_res },
813*b89261baSDavid van Moolenbroek { "STATE", 6, 0, 0, fmt_state },
814*b89261baSDavid van Moolenbroek { "FLG", 3, 0, 84, fmt_flags },
815*b89261baSDavid van Moolenbroek { "C", 1, 0, 0, fmt_c },
816*b89261baSDavid van Moolenbroek { "TIME", 6, 1, 0, fmt_time },
817*b89261baSDavid van Moolenbroek { "CPU", 6, 1, 0, fmt_cpu },
818*b89261baSDavid van Moolenbroek { "COMMAND", 7, 0, 0, fmt_command },
819*b89261baSDavid van Moolenbroek { "VCSW", 6, 1, 0, fmt_vcsw },
820*b89261baSDavid van Moolenbroek { "IVCSW", 6, 1, 0, fmt_ivcsw },
821*b89261baSDavid van Moolenbroek { "READ", 6, 1, 0, fmt_read },
822*b89261baSDavid van Moolenbroek { "WRITE", 6, 1, 0, fmt_write },
823*b89261baSDavid van Moolenbroek { "FAULT", 6, 1, 0, fmt_fault },
824*b89261baSDavid van Moolenbroek { "TOTAL", 6, 1, 0, fmt_iototal },
825*b89261baSDavid van Moolenbroek { "PERCENT", 7, 1, 0, fmt_iopct },
826*b89261baSDavid van Moolenbroek { NULL, 0, 0, 0, NULL }
827*b89261baSDavid van Moolenbroek };
828*b89261baSDavid van Moolenbroek #define MAX_FIELDS 24
829*b89261baSDavid van Moolenbroek
830*b89261baSDavid van Moolenbroek static int mode0_display[MAX_FIELDS];
831*b89261baSDavid van Moolenbroek static int mode0thr_display[MAX_FIELDS];
832*b89261baSDavid van Moolenbroek static int mode1_display[MAX_FIELDS];
833*b89261baSDavid van Moolenbroek
834*b89261baSDavid van Moolenbroek int
field_index(char * col)835*b89261baSDavid van Moolenbroek field_index(char *col)
836*b89261baSDavid van Moolenbroek
837*b89261baSDavid van Moolenbroek {
838*b89261baSDavid van Moolenbroek struct proc_field *fp;
839*b89261baSDavid van Moolenbroek int i = 0;
840*b89261baSDavid van Moolenbroek
841*b89261baSDavid van Moolenbroek fp = proc_field;
842*b89261baSDavid van Moolenbroek while (fp->name != NULL)
843*b89261baSDavid van Moolenbroek {
844*b89261baSDavid van Moolenbroek if (strcmp(col, fp->name) == 0)
845*b89261baSDavid van Moolenbroek {
846*b89261baSDavid van Moolenbroek return i;
847*b89261baSDavid van Moolenbroek }
848*b89261baSDavid van Moolenbroek fp++;
849*b89261baSDavid van Moolenbroek i++;
850*b89261baSDavid van Moolenbroek }
851*b89261baSDavid van Moolenbroek
852*b89261baSDavid van Moolenbroek return -1;
853*b89261baSDavid van Moolenbroek }
854*b89261baSDavid van Moolenbroek
855*b89261baSDavid van Moolenbroek void
field_subst(int * fp,int old,int new)856*b89261baSDavid van Moolenbroek field_subst(int *fp, int old, int new)
857*b89261baSDavid van Moolenbroek
858*b89261baSDavid van Moolenbroek {
859*b89261baSDavid van Moolenbroek while (*fp != -1)
860*b89261baSDavid van Moolenbroek {
861*b89261baSDavid van Moolenbroek if (*fp == old)
862*b89261baSDavid van Moolenbroek {
863*b89261baSDavid van Moolenbroek *fp = new;
864*b89261baSDavid van Moolenbroek }
865*b89261baSDavid van Moolenbroek fp++;
866*b89261baSDavid van Moolenbroek }
867*b89261baSDavid van Moolenbroek }
868*b89261baSDavid van Moolenbroek
869*b89261baSDavid van Moolenbroek int
machine_init(struct statics * statics)870*b89261baSDavid van Moolenbroek machine_init(struct statics *statics)
871*b89261baSDavid van Moolenbroek
872*b89261baSDavid van Moolenbroek {
873*b89261baSDavid van Moolenbroek int i = 0;
874*b89261baSDavid van Moolenbroek size_t len;
875*b89261baSDavid van Moolenbroek int *ip;
876*b89261baSDavid van Moolenbroek
877*b89261baSDavid van Moolenbroek struct timeval boottime;
878*b89261baSDavid van Moolenbroek
879*b89261baSDavid van Moolenbroek len = sizeof(smpmode);
880*b89261baSDavid van Moolenbroek if ((sysctlbyname("machdep.smp_active", &smpmode, &len, NULL, 0) < 0 &&
881*b89261baSDavid van Moolenbroek sysctlbyname("smp.smp_active", &smpmode, &len, NULL, 0) < 0) ||
882*b89261baSDavid van Moolenbroek len != sizeof(smpmode))
883*b89261baSDavid van Moolenbroek {
884*b89261baSDavid van Moolenbroek smpmode = 0;
885*b89261baSDavid van Moolenbroek }
886*b89261baSDavid van Moolenbroek smpmode = smpmode != 0;
887*b89261baSDavid van Moolenbroek
888*b89261baSDavid van Moolenbroek /* kvm_open the active kernel: its okay if this fails */
889*b89261baSDavid van Moolenbroek kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
890*b89261baSDavid van Moolenbroek
891*b89261baSDavid van Moolenbroek /* get boot time */
892*b89261baSDavid van Moolenbroek len = sizeof(boottime);
893*b89261baSDavid van Moolenbroek if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) == -1)
894*b89261baSDavid van Moolenbroek {
895*b89261baSDavid van Moolenbroek /* we have no boottime to report */
896*b89261baSDavid van Moolenbroek boottime.tv_sec = -1;
897*b89261baSDavid van Moolenbroek }
898*b89261baSDavid van Moolenbroek
899*b89261baSDavid van Moolenbroek pbase = NULL;
900*b89261baSDavid van Moolenbroek pref = NULL;
901*b89261baSDavid van Moolenbroek
902*b89261baSDavid van Moolenbroek /* get the page size with "getpagesize" and calculate pageshift from it */
903*b89261baSDavid van Moolenbroek i = pagesize = getpagesize();
904*b89261baSDavid van Moolenbroek pageshift = 0;
905*b89261baSDavid van Moolenbroek while (i > 1)
906*b89261baSDavid van Moolenbroek {
907*b89261baSDavid van Moolenbroek pageshift++;
908*b89261baSDavid van Moolenbroek i >>= 1;
909*b89261baSDavid van Moolenbroek }
910*b89261baSDavid van Moolenbroek
911*b89261baSDavid van Moolenbroek /* translate sysctl paths to mibs for faster access */
912*b89261baSDavid van Moolenbroek get_sysctl_mibs();
913*b89261baSDavid van Moolenbroek
914*b89261baSDavid van Moolenbroek /* initialize swap stuff */
915*b89261baSDavid van Moolenbroek swap_init();
916*b89261baSDavid van Moolenbroek
917*b89261baSDavid van Moolenbroek /* create the hash table that remembers proc data */
918*b89261baSDavid van Moolenbroek procs = hash_create(2039);
919*b89261baSDavid van Moolenbroek
920*b89261baSDavid van Moolenbroek /* we only need the amount of log(2)1024 for our conversion */
921*b89261baSDavid van Moolenbroek pageshift -= LOG1024;
922*b89261baSDavid van Moolenbroek
923*b89261baSDavid van Moolenbroek /* fill in the statics information */
924*b89261baSDavid van Moolenbroek statics->procstate_names = procstatenames;
925*b89261baSDavid van Moolenbroek statics->cpustate_names = cpustatenames;
926*b89261baSDavid van Moolenbroek statics->memory_names = memorynames;
927*b89261baSDavid van Moolenbroek statics->kernel_names = kernelnames;
928*b89261baSDavid van Moolenbroek statics->boottime = boottime.tv_sec;
929*b89261baSDavid van Moolenbroek statics->swap_names = swapnames;
930*b89261baSDavid van Moolenbroek statics->order_names = ordernames;
931*b89261baSDavid van Moolenbroek statics->flags.warmup = 1;
932*b89261baSDavid van Moolenbroek statics->modemax = 2;
933*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
934*b89261baSDavid van Moolenbroek statics->flags.threads = 1;
935*b89261baSDavid van Moolenbroek #endif
936*b89261baSDavid van Moolenbroek
937*b89261baSDavid van Moolenbroek /* we need kvm descriptor in order to show full commands */
938*b89261baSDavid van Moolenbroek statics->flags.fullcmds = kd != NULL;
939*b89261baSDavid van Moolenbroek
940*b89261baSDavid van Moolenbroek /* set up the display indices for mode0 */
941*b89261baSDavid van Moolenbroek ip = mode0_display;
942*b89261baSDavid van Moolenbroek *ip++ = field_index("PID");
943*b89261baSDavid van Moolenbroek *ip++ = field_index("USERNAME");
944*b89261baSDavid van Moolenbroek #ifdef HAS_THREADS
945*b89261baSDavid van Moolenbroek *ip++ = field_index("THR");
946*b89261baSDavid van Moolenbroek #endif
947*b89261baSDavid van Moolenbroek *ip++ = field_index("PRI");
948*b89261baSDavid van Moolenbroek *ip++ = field_index("NICE");
949*b89261baSDavid van Moolenbroek *ip++ = field_index("SIZE");
950*b89261baSDavid van Moolenbroek *ip++ = field_index("RES");
951*b89261baSDavid van Moolenbroek *ip++ = field_index("STATE");
952*b89261baSDavid van Moolenbroek *ip++ = field_index("FLG");
953*b89261baSDavid van Moolenbroek if (smpmode)
954*b89261baSDavid van Moolenbroek *ip++ = field_index("C");
955*b89261baSDavid van Moolenbroek *ip++ = field_index("TIME");
956*b89261baSDavid van Moolenbroek *ip++ = field_index("CPU");
957*b89261baSDavid van Moolenbroek *ip++ = field_index("COMMAND");
958*b89261baSDavid van Moolenbroek *ip = -1;
959*b89261baSDavid van Moolenbroek
960*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
961*b89261baSDavid van Moolenbroek /* set up the display indices for mode0 showing threads */
962*b89261baSDavid van Moolenbroek ip = mode0thr_display;
963*b89261baSDavid van Moolenbroek *ip++ = field_index("PID");
964*b89261baSDavid van Moolenbroek *ip++ = field_index("USERNAME");
965*b89261baSDavid van Moolenbroek *ip++ = field_index("PRI");
966*b89261baSDavid van Moolenbroek *ip++ = field_index("NICE");
967*b89261baSDavid van Moolenbroek *ip++ = field_index("SIZE");
968*b89261baSDavid van Moolenbroek *ip++ = field_index("RES");
969*b89261baSDavid van Moolenbroek *ip++ = field_index("STATE");
970*b89261baSDavid van Moolenbroek *ip++ = field_index("FLG");
971*b89261baSDavid van Moolenbroek if (smpmode)
972*b89261baSDavid van Moolenbroek *ip++ = field_index("C");
973*b89261baSDavid van Moolenbroek *ip++ = field_index("TIME");
974*b89261baSDavid van Moolenbroek *ip++ = field_index("CPU");
975*b89261baSDavid van Moolenbroek *ip++ = field_index("COMMAND");
976*b89261baSDavid van Moolenbroek *ip = -1;
977*b89261baSDavid van Moolenbroek #endif
978*b89261baSDavid van Moolenbroek
979*b89261baSDavid van Moolenbroek /* set up the display indices for mode1 */
980*b89261baSDavid van Moolenbroek ip = mode1_display;
981*b89261baSDavid van Moolenbroek *ip++ = field_index("PID");
982*b89261baSDavid van Moolenbroek *ip++ = field_index("USERNAME");
983*b89261baSDavid van Moolenbroek *ip++ = field_index("VCSW");
984*b89261baSDavid van Moolenbroek *ip++ = field_index("IVCSW");
985*b89261baSDavid van Moolenbroek *ip++ = field_index("READ");
986*b89261baSDavid van Moolenbroek *ip++ = field_index("WRITE");
987*b89261baSDavid van Moolenbroek *ip++ = field_index("FAULT");
988*b89261baSDavid van Moolenbroek *ip++ = field_index("TOTAL");
989*b89261baSDavid van Moolenbroek *ip++ = field_index("PERCENT");
990*b89261baSDavid van Moolenbroek *ip++ = field_index("COMMAND");
991*b89261baSDavid van Moolenbroek *ip = -1;
992*b89261baSDavid van Moolenbroek
993*b89261baSDavid van Moolenbroek /* all done! */
994*b89261baSDavid van Moolenbroek return(0);
995*b89261baSDavid van Moolenbroek }
996*b89261baSDavid van Moolenbroek
format_header(char * uname_field)997*b89261baSDavid van Moolenbroek char *format_header(char *uname_field)
998*b89261baSDavid van Moolenbroek
999*b89261baSDavid van Moolenbroek {
1000*b89261baSDavid van Moolenbroek return "";
1001*b89261baSDavid van Moolenbroek }
1002*b89261baSDavid van Moolenbroek
1003*b89261baSDavid van Moolenbroek void
get_vm_sum(struct vmmeter * sum)1004*b89261baSDavid van Moolenbroek get_vm_sum(struct vmmeter *sum)
1005*b89261baSDavid van Moolenbroek
1006*b89261baSDavid van Moolenbroek {
1007*b89261baSDavid van Moolenbroek #define GET_VM_STAT(v, s) (void)get_sysctl(v, &(sum->s), sizeof(sum->s))
1008*b89261baSDavid van Moolenbroek
1009*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SWTCH, v_swtch);
1010*b89261baSDavid van Moolenbroek GET_VM_STAT(V_TRAP, v_trap);
1011*b89261baSDavid van Moolenbroek GET_VM_STAT(V_INTR, v_intr);
1012*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SOFT, v_soft);
1013*b89261baSDavid van Moolenbroek GET_VM_STAT(V_VFORKS, v_vforks);
1014*b89261baSDavid van Moolenbroek GET_VM_STAT(V_FORKS, v_forks);
1015*b89261baSDavid van Moolenbroek GET_VM_STAT(V_RFORKS, v_rforks);
1016*b89261baSDavid van Moolenbroek GET_VM_STAT(V_VM_FAULTS, v_vm_faults);
1017*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SWAPIN, v_swapin);
1018*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SWAPOUT, v_swapout);
1019*b89261baSDavid van Moolenbroek GET_VM_STAT(V_TFREE, v_tfree);
1020*b89261baSDavid van Moolenbroek GET_VM_STAT(V_VNODEIN, v_vnodein);
1021*b89261baSDavid van Moolenbroek GET_VM_STAT(V_VNODEOUT, v_vnodeout);
1022*b89261baSDavid van Moolenbroek GET_VM_STAT(V_ACTIVE_COUNT, v_active_count);
1023*b89261baSDavid van Moolenbroek GET_VM_STAT(V_INACTIVE_COUNT, v_inactive_count);
1024*b89261baSDavid van Moolenbroek GET_VM_STAT(V_WIRE_COUNT, v_wire_count);
1025*b89261baSDavid van Moolenbroek GET_VM_STAT(V_CACHE_COUNT, v_cache_count);
1026*b89261baSDavid van Moolenbroek GET_VM_STAT(V_FREE_COUNT, v_free_count);
1027*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SWAPPGSIN, v_swappgsin);
1028*b89261baSDavid van Moolenbroek GET_VM_STAT(V_SWAPPGSOUT, v_swappgsout);
1029*b89261baSDavid van Moolenbroek }
1030*b89261baSDavid van Moolenbroek
1031*b89261baSDavid van Moolenbroek void
get_system_info(struct system_info * si)1032*b89261baSDavid van Moolenbroek get_system_info(struct system_info *si)
1033*b89261baSDavid van Moolenbroek
1034*b89261baSDavid van Moolenbroek {
1035*b89261baSDavid van Moolenbroek long total;
1036*b89261baSDavid van Moolenbroek struct timeval thistime;
1037*b89261baSDavid van Moolenbroek struct timeval timediff;
1038*b89261baSDavid van Moolenbroek
1039*b89261baSDavid van Moolenbroek /* timestamp and time difference */
1040*b89261baSDavid van Moolenbroek gettimeofday(&thistime, 0);
1041*b89261baSDavid van Moolenbroek timersub(&thistime, &lasttime, &timediff);
1042*b89261baSDavid van Moolenbroek elapsed_time = timediff.tv_sec * 1000000 + timediff.tv_usec;
1043*b89261baSDavid van Moolenbroek elapsed_msecs = timediff.tv_sec * 1000 + timediff.tv_usec / 1000;
1044*b89261baSDavid van Moolenbroek
1045*b89261baSDavid van Moolenbroek /* get the load averages */
1046*b89261baSDavid van Moolenbroek if (getloadavg(si->load_avg, NUM_AVERAGES) == -1)
1047*b89261baSDavid van Moolenbroek {
1048*b89261baSDavid van Moolenbroek /* failed: fill in with zeroes */
1049*b89261baSDavid van Moolenbroek (void) memset(si->load_avg, 0, sizeof(si->load_avg));
1050*b89261baSDavid van Moolenbroek }
1051*b89261baSDavid van Moolenbroek
1052*b89261baSDavid van Moolenbroek /* get the cp_time array */
1053*b89261baSDavid van Moolenbroek (void)get_sysctl(K_CP_TIME, &cp_time, sizeof(cp_time));
1054*b89261baSDavid van Moolenbroek
1055*b89261baSDavid van Moolenbroek /* convert cp_time counts to percentages */
1056*b89261baSDavid van Moolenbroek total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
1057*b89261baSDavid van Moolenbroek
1058*b89261baSDavid van Moolenbroek /* sum memory & swap statistics */
1059*b89261baSDavid van Moolenbroek {
1060*b89261baSDavid van Moolenbroek struct vmmeter sum;
1061*b89261baSDavid van Moolenbroek static unsigned int swap_delay = 0;
1062*b89261baSDavid van Moolenbroek static long long swapavail = 0;
1063*b89261baSDavid van Moolenbroek static long long swapfree = 0;
1064*b89261baSDavid van Moolenbroek static int bufspace = 0;
1065*b89261baSDavid van Moolenbroek
1066*b89261baSDavid van Moolenbroek get_vm_sum(&sum);
1067*b89261baSDavid van Moolenbroek
1068*b89261baSDavid van Moolenbroek /* get bufspace */
1069*b89261baSDavid van Moolenbroek bufspace = 0;
1070*b89261baSDavid van Moolenbroek (void) get_sysctl(VFS_BUFSPACE, &bufspace, sizeof(bufspace));
1071*b89261baSDavid van Moolenbroek
1072*b89261baSDavid van Moolenbroek /* kernel stats */
1073*b89261baSDavid van Moolenbroek dprintf("kernel: swtch %d, trap %d, intr %d, soft %d, vforks %d\n",
1074*b89261baSDavid van Moolenbroek sum.v_swtch, sum.v_trap, sum.v_intr, sum.v_soft, sum.v_vforks);
1075*b89261baSDavid van Moolenbroek kernel_stats[0] = per_second(sum.v_swtch - ctxsws, elapsed_msecs);
1076*b89261baSDavid van Moolenbroek kernel_stats[1] = per_second(sum.v_trap - traps, elapsed_msecs);
1077*b89261baSDavid van Moolenbroek kernel_stats[2] = per_second(sum.v_intr - intrs, elapsed_msecs);
1078*b89261baSDavid van Moolenbroek kernel_stats[3] = per_second(sum.v_soft - softs, elapsed_msecs);
1079*b89261baSDavid van Moolenbroek kernel_stats[4] = per_second(sum.v_vforks + sum.v_forks +
1080*b89261baSDavid van Moolenbroek sum.v_rforks - forks, elapsed_msecs);
1081*b89261baSDavid van Moolenbroek kernel_stats[5] = per_second(sum.v_vm_faults - pfaults, elapsed_msecs);
1082*b89261baSDavid van Moolenbroek kernel_stats[6] = per_second(sum.v_swapin + sum.v_vnodein - pagein, elapsed_msecs);
1083*b89261baSDavid van Moolenbroek kernel_stats[7] = per_second(sum.v_swapout + sum.v_vnodeout - pageout, elapsed_msecs);
1084*b89261baSDavid van Moolenbroek kernel_stats[8] = per_second(sum.v_tfree - tfreed, elapsed_msecs);
1085*b89261baSDavid van Moolenbroek ctxsws = sum.v_swtch;
1086*b89261baSDavid van Moolenbroek traps = sum.v_trap;
1087*b89261baSDavid van Moolenbroek intrs = sum.v_intr;
1088*b89261baSDavid van Moolenbroek softs = sum.v_soft;
1089*b89261baSDavid van Moolenbroek forks = (u_int64_t)sum.v_vforks + sum.v_forks + sum.v_rforks;
1090*b89261baSDavid van Moolenbroek pfaults = sum.v_vm_faults;
1091*b89261baSDavid van Moolenbroek pagein = sum.v_swapin + sum.v_vnodein;
1092*b89261baSDavid van Moolenbroek pageout = sum.v_swapout + sum.v_vnodeout;
1093*b89261baSDavid van Moolenbroek tfreed = sum.v_tfree;
1094*b89261baSDavid van Moolenbroek
1095*b89261baSDavid van Moolenbroek /* convert memory stats to Kbytes */
1096*b89261baSDavid van Moolenbroek memory_stats[0] = pagetok(sum.v_active_count);
1097*b89261baSDavid van Moolenbroek memory_stats[1] = pagetok(sum.v_inactive_count);
1098*b89261baSDavid van Moolenbroek memory_stats[2] = pagetok(sum.v_wire_count);
1099*b89261baSDavid van Moolenbroek memory_stats[3] = pagetok(sum.v_cache_count);
1100*b89261baSDavid van Moolenbroek memory_stats[4] = bufspace / 1024;
1101*b89261baSDavid van Moolenbroek memory_stats[5] = pagetok(sum.v_free_count);
1102*b89261baSDavid van Moolenbroek memory_stats[6] = -1;
1103*b89261baSDavid van Moolenbroek
1104*b89261baSDavid van Moolenbroek /* first interval */
1105*b89261baSDavid van Moolenbroek if (swappgsin < 0)
1106*b89261baSDavid van Moolenbroek {
1107*b89261baSDavid van Moolenbroek swap_stats[4] = 0;
1108*b89261baSDavid van Moolenbroek swap_stats[5] = 0;
1109*b89261baSDavid van Moolenbroek }
1110*b89261baSDavid van Moolenbroek
1111*b89261baSDavid van Moolenbroek /* compute differences between old and new swap statistic */
1112*b89261baSDavid van Moolenbroek else
1113*b89261baSDavid van Moolenbroek {
1114*b89261baSDavid van Moolenbroek swap_stats[4] = pagetok(sum.v_swappgsin - swappgsin);
1115*b89261baSDavid van Moolenbroek swap_stats[5] = pagetok(sum.v_swappgsout - swappgsout);
1116*b89261baSDavid van Moolenbroek }
1117*b89261baSDavid van Moolenbroek
1118*b89261baSDavid van Moolenbroek swappgsin = sum.v_swappgsin;
1119*b89261baSDavid van Moolenbroek swappgsout = sum.v_swappgsout;
1120*b89261baSDavid van Moolenbroek
1121*b89261baSDavid van Moolenbroek /* call CPU heavy swap_getdata() only for changes */
1122*b89261baSDavid van Moolenbroek if (swap_stats[4] > 0 || swap_stats[5] > 0 || swap_delay == 0)
1123*b89261baSDavid van Moolenbroek {
1124*b89261baSDavid van Moolenbroek swap_stats[3] = swap_getdata(&swapavail, &swapfree);
1125*b89261baSDavid van Moolenbroek swap_stats[0] = swapavail;
1126*b89261baSDavid van Moolenbroek swap_stats[1] = swapavail - swapfree;
1127*b89261baSDavid van Moolenbroek swap_stats[2] = swapfree;
1128*b89261baSDavid van Moolenbroek }
1129*b89261baSDavid van Moolenbroek swap_delay = 1;
1130*b89261baSDavid van Moolenbroek swap_stats[6] = -1;
1131*b89261baSDavid van Moolenbroek }
1132*b89261baSDavid van Moolenbroek
1133*b89261baSDavid van Moolenbroek /* set arrays and strings */
1134*b89261baSDavid van Moolenbroek si->cpustates = cpu_states;
1135*b89261baSDavid van Moolenbroek si->kernel = kernel_stats;
1136*b89261baSDavid van Moolenbroek si->memory = memory_stats;
1137*b89261baSDavid van Moolenbroek si->swap = swap_stats;
1138*b89261baSDavid van Moolenbroek
1139*b89261baSDavid van Moolenbroek si->last_pid = -1;
1140*b89261baSDavid van Moolenbroek
1141*b89261baSDavid van Moolenbroek lasttime = thistime;
1142*b89261baSDavid van Moolenbroek }
1143*b89261baSDavid van Moolenbroek
1144*b89261baSDavid van Moolenbroek caddr_t
get_process_info(struct system_info * si,struct process_select * sel,int compare_index)1145*b89261baSDavid van Moolenbroek get_process_info(struct system_info *si,
1146*b89261baSDavid van Moolenbroek struct process_select *sel,
1147*b89261baSDavid van Moolenbroek int compare_index)
1148*b89261baSDavid van Moolenbroek
1149*b89261baSDavid van Moolenbroek {
1150*b89261baSDavid van Moolenbroek int i;
1151*b89261baSDavid van Moolenbroek int total_procs;
1152*b89261baSDavid van Moolenbroek int active_procs;
1153*b89261baSDavid van Moolenbroek struct kinfo_proc **prefp;
1154*b89261baSDavid van Moolenbroek struct kinfo_proc *pp;
1155*b89261baSDavid van Moolenbroek struct kinfo_proc *prev_pp = NULL;
1156*b89261baSDavid van Moolenbroek struct save_proc *savep;
1157*b89261baSDavid van Moolenbroek long proc_io;
1158*b89261baSDavid van Moolenbroek pid_t pid;
1159*b89261baSDavid van Moolenbroek size_t size;
1160*b89261baSDavid van Moolenbroek int nproc;
1161*b89261baSDavid van Moolenbroek
1162*b89261baSDavid van Moolenbroek /* these are copied out of sel for speed */
1163*b89261baSDavid van Moolenbroek int show_idle;
1164*b89261baSDavid van Moolenbroek int show_self;
1165*b89261baSDavid van Moolenbroek int show_system;
1166*b89261baSDavid van Moolenbroek int show_uid;
1167*b89261baSDavid van Moolenbroek char *show_command;
1168*b89261baSDavid van Moolenbroek
1169*b89261baSDavid van Moolenbroek /* get proc table size and give it a boost */
1170*b89261baSDavid van Moolenbroek nproc = (int)get_sysctlsize(K_PROC) / sizeof(struct kinfo_proc);
1171*b89261baSDavid van Moolenbroek nproc += nproc >> 4;
1172*b89261baSDavid van Moolenbroek size = nproc * sizeof(struct kinfo_proc);
1173*b89261baSDavid van Moolenbroek dprintf("get_process_info: nproc %d, psize %d, size %d\n", nproc, psize, size);
1174*b89261baSDavid van Moolenbroek
1175*b89261baSDavid van Moolenbroek /* make sure we have enough space allocated */
1176*b89261baSDavid van Moolenbroek if (nproc > psize)
1177*b89261baSDavid van Moolenbroek {
1178*b89261baSDavid van Moolenbroek /* reallocate both pbase and pref */
1179*b89261baSDavid van Moolenbroek pbase = (struct kinfo_proc *)realloc(pbase, size);
1180*b89261baSDavid van Moolenbroek pref = (struct kinfo_proc **)realloc(pref,
1181*b89261baSDavid van Moolenbroek sizeof(struct kinfo_proc *) * nproc);
1182*b89261baSDavid van Moolenbroek psize = nproc;
1183*b89261baSDavid van Moolenbroek }
1184*b89261baSDavid van Moolenbroek
1185*b89261baSDavid van Moolenbroek /* make sure we got the space we asked for */
1186*b89261baSDavid van Moolenbroek if (pref == NULL || pbase == NULL)
1187*b89261baSDavid van Moolenbroek {
1188*b89261baSDavid van Moolenbroek /* abandon all hope */
1189*b89261baSDavid van Moolenbroek message_error(" Out of memory!");
1190*b89261baSDavid van Moolenbroek nproc = psize = 0;
1191*b89261baSDavid van Moolenbroek si->p_total = 0;
1192*b89261baSDavid van Moolenbroek si->p_active = 0;
1193*b89261baSDavid van Moolenbroek return NULL;
1194*b89261baSDavid van Moolenbroek }
1195*b89261baSDavid van Moolenbroek
1196*b89261baSDavid van Moolenbroek /* get all process information (threads, too) */
1197*b89261baSDavid van Moolenbroek if (size > 0)
1198*b89261baSDavid van Moolenbroek {
1199*b89261baSDavid van Moolenbroek nproc = get_sysctl(K_PROC, pbase, size);
1200*b89261baSDavid van Moolenbroek if (nproc == -1)
1201*b89261baSDavid van Moolenbroek {
1202*b89261baSDavid van Moolenbroek nproc = 0;
1203*b89261baSDavid van Moolenbroek }
1204*b89261baSDavid van Moolenbroek else
1205*b89261baSDavid van Moolenbroek {
1206*b89261baSDavid van Moolenbroek nproc /= sizeof(struct kinfo_proc);
1207*b89261baSDavid van Moolenbroek }
1208*b89261baSDavid van Moolenbroek }
1209*b89261baSDavid van Moolenbroek
1210*b89261baSDavid van Moolenbroek /* get a pointer to the states summary array */
1211*b89261baSDavid van Moolenbroek si->procstates = process_states;
1212*b89261baSDavid van Moolenbroek
1213*b89261baSDavid van Moolenbroek /* set up flags which define what we are going to select */
1214*b89261baSDavid van Moolenbroek show_idle = sel->idle;
1215*b89261baSDavid van Moolenbroek show_self = 0;
1216*b89261baSDavid van Moolenbroek show_system = sel->system;
1217*b89261baSDavid van Moolenbroek show_uid = sel->uid != -1;
1218*b89261baSDavid van Moolenbroek show_fullcmd = sel->fullcmd;
1219*b89261baSDavid van Moolenbroek show_command = sel->command;
1220*b89261baSDavid van Moolenbroek show_usernames = sel->usernames;
1221*b89261baSDavid van Moolenbroek display_mode = sel->mode;
1222*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
1223*b89261baSDavid van Moolenbroek show_threads = sel->threads;
1224*b89261baSDavid van Moolenbroek #endif
1225*b89261baSDavid van Moolenbroek
1226*b89261baSDavid van Moolenbroek /* count up process states and get pointers to interesting procs */
1227*b89261baSDavid van Moolenbroek total_procs = 0;
1228*b89261baSDavid van Moolenbroek active_procs = 0;
1229*b89261baSDavid van Moolenbroek total_io = 0;
1230*b89261baSDavid van Moolenbroek memset((char *)process_states, 0, sizeof(process_states));
1231*b89261baSDavid van Moolenbroek prefp = pref;
1232*b89261baSDavid van Moolenbroek for (pp = pbase, i = 0; i < nproc; pp++, i++)
1233*b89261baSDavid van Moolenbroek {
1234*b89261baSDavid van Moolenbroek /*
1235*b89261baSDavid van Moolenbroek * Place pointers to each valid proc structure in pref[].
1236*b89261baSDavid van Moolenbroek * Process slots that are actually in use have a non-zero
1237*b89261baSDavid van Moolenbroek * status field. Processes with P_SYSTEM set are system
1238*b89261baSDavid van Moolenbroek * processes---these get ignored unless show_sysprocs is set.
1239*b89261baSDavid van Moolenbroek */
1240*b89261baSDavid van Moolenbroek pid = PP(pp, pid);
1241*b89261baSDavid van Moolenbroek if (PP(pp, stat) != 0)
1242*b89261baSDavid van Moolenbroek {
1243*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
1244*b89261baSDavid van Moolenbroek int is_thread;
1245*b89261baSDavid van Moolenbroek lwpid_t tid;
1246*b89261baSDavid van Moolenbroek
1247*b89261baSDavid van Moolenbroek /* get thread id */
1248*b89261baSDavid van Moolenbroek tid = PP(pp, tid);
1249*b89261baSDavid van Moolenbroek
1250*b89261baSDavid van Moolenbroek /* is this just a thread? */
1251*b89261baSDavid van Moolenbroek is_thread = (prev_pp != NULL && PP(prev_pp, pid) == pid);
1252*b89261baSDavid van Moolenbroek
1253*b89261baSDavid van Moolenbroek /* count this process and its state */
1254*b89261baSDavid van Moolenbroek /* only count threads if we are showing them */
1255*b89261baSDavid van Moolenbroek if (show_threads || !is_thread)
1256*b89261baSDavid van Moolenbroek {
1257*b89261baSDavid van Moolenbroek total_procs++;
1258*b89261baSDavid van Moolenbroek process_states[(unsigned char) PP(pp, stat)]++;
1259*b89261baSDavid van Moolenbroek }
1260*b89261baSDavid van Moolenbroek
1261*b89261baSDavid van Moolenbroek /* grab old data from hash */
1262*b89261baSDavid van Moolenbroek if ((savep = hash_lookup_lwpid(procs, tid)) != NULL)
1263*b89261baSDavid van Moolenbroek {
1264*b89261baSDavid van Moolenbroek /* verify that this is not a new or different thread */
1265*b89261baSDavid van Moolenbroek /* (freebsd reuses thread ids fairly quickly) */
1266*b89261baSDavid van Moolenbroek /* pids must match and time can't have gone backwards */
1267*b89261baSDavid van Moolenbroek if (pid != savep->sp_pid || PP(pp, runtime) < savep->sp_runtime)
1268*b89261baSDavid van Moolenbroek {
1269*b89261baSDavid van Moolenbroek /* not the same thread -- reuse the save_proc structure */
1270*b89261baSDavid van Moolenbroek memset(savep, 0, sizeof(struct save_proc));
1271*b89261baSDavid van Moolenbroek savep->sp_pid = pid;
1272*b89261baSDavid van Moolenbroek }
1273*b89261baSDavid van Moolenbroek }
1274*b89261baSDavid van Moolenbroek else
1275*b89261baSDavid van Moolenbroek {
1276*b89261baSDavid van Moolenbroek /* havent seen this one before */
1277*b89261baSDavid van Moolenbroek savep = (struct save_proc *)calloc(1, sizeof(struct save_proc));
1278*b89261baSDavid van Moolenbroek savep->sp_pid = pid;
1279*b89261baSDavid van Moolenbroek hash_add_lwpid(procs, tid, savep);
1280*b89261baSDavid van Moolenbroek }
1281*b89261baSDavid van Moolenbroek
1282*b89261baSDavid van Moolenbroek #else /* !HAS_SHOWTHREADS */
1283*b89261baSDavid van Moolenbroek total_procs++;
1284*b89261baSDavid van Moolenbroek process_states[(unsigned char) PP(pp, stat)]++;
1285*b89261baSDavid van Moolenbroek
1286*b89261baSDavid van Moolenbroek /* grab old data from hash */
1287*b89261baSDavid van Moolenbroek if ((savep = hash_lookup_pid(procs, pid)) == NULL)
1288*b89261baSDavid van Moolenbroek {
1289*b89261baSDavid van Moolenbroek /* havent seen this one before */
1290*b89261baSDavid van Moolenbroek savep = (struct save_proc *)calloc(1, sizeof(struct save_proc));
1291*b89261baSDavid van Moolenbroek savep->sp_pid = pid;
1292*b89261baSDavid van Moolenbroek hash_add_pid(procs, pid, savep);
1293*b89261baSDavid van Moolenbroek }
1294*b89261baSDavid van Moolenbroek #endif
1295*b89261baSDavid van Moolenbroek
1296*b89261baSDavid van Moolenbroek /* save the pointer to the sp struct */
1297*b89261baSDavid van Moolenbroek SPPTR(pp) = (void *)savep;
1298*b89261baSDavid van Moolenbroek
1299*b89261baSDavid van Moolenbroek /* calculate %cpu */
1300*b89261baSDavid van Moolenbroek PPCPU(pp) = ((PP(pp, runtime) - savep->sp_runtime) * 10000) /
1301*b89261baSDavid van Moolenbroek elapsed_time;
1302*b89261baSDavid van Moolenbroek dprintf("%d (%d): runtime %lld, saved_pid %d, saved_runtime %lld, elapsed_time %d, ppcpu %d\n",
1303*b89261baSDavid van Moolenbroek pid, PP(pp, tid), PP(pp, runtime), savep->sp_pid, savep->sp_runtime,
1304*b89261baSDavid van Moolenbroek elapsed_time, PPCPU(pp));
1305*b89261baSDavid van Moolenbroek
1306*b89261baSDavid van Moolenbroek /* calculate io differences */
1307*b89261baSDavid van Moolenbroek proc_io = 0;
1308*b89261baSDavid van Moolenbroek savep->sp_vcsw = (RP(pp, nvcsw) - savep->sp_old_nvcsw);
1309*b89261baSDavid van Moolenbroek savep->sp_ivcsw = (RP(pp, nivcsw) - savep->sp_old_nivcsw);
1310*b89261baSDavid van Moolenbroek proc_io += (savep->sp_inblock = (RP(pp, inblock) - savep->sp_old_inblock));
1311*b89261baSDavid van Moolenbroek proc_io += (savep->sp_oublock = (RP(pp, oublock) - savep->sp_old_oublock));
1312*b89261baSDavid van Moolenbroek proc_io += (savep->sp_majflt = (RP(pp, majflt) - savep->sp_old_majflt));
1313*b89261baSDavid van Moolenbroek total_io += proc_io;
1314*b89261baSDavid van Moolenbroek savep->sp_totalio = proc_io;
1315*b89261baSDavid van Moolenbroek
1316*b89261baSDavid van Moolenbroek /* save data for next time */
1317*b89261baSDavid van Moolenbroek savep->sp_runtime = PP(pp, runtime);
1318*b89261baSDavid van Moolenbroek savep->sp_old_nvcsw = RP(pp, nvcsw);
1319*b89261baSDavid van Moolenbroek savep->sp_old_nivcsw = RP(pp, nivcsw);
1320*b89261baSDavid van Moolenbroek savep->sp_old_inblock = RP(pp, inblock);
1321*b89261baSDavid van Moolenbroek savep->sp_old_oublock = RP(pp, oublock);
1322*b89261baSDavid van Moolenbroek savep->sp_old_majflt = RP(pp, majflt);
1323*b89261baSDavid van Moolenbroek
1324*b89261baSDavid van Moolenbroek /* is this one selected for viewing? */
1325*b89261baSDavid van Moolenbroek if ((PP(pp, stat) != SZOMB) &&
1326*b89261baSDavid van Moolenbroek (show_system || ((PP(pp, flag) & P_SYSTEM) == 0)) &&
1327*b89261baSDavid van Moolenbroek (show_idle || (PP(pp, pctcpu) != 0) ||
1328*b89261baSDavid van Moolenbroek (PP(pp, stat) == SRUN)) &&
1329*b89261baSDavid van Moolenbroek (!show_uid || PRUID(pp) == (uid_t)sel->uid) &&
1330*b89261baSDavid van Moolenbroek (show_command == NULL ||
1331*b89261baSDavid van Moolenbroek strcasestr(PP(pp, comm), show_command) != NULL))
1332*b89261baSDavid van Moolenbroek {
1333*b89261baSDavid van Moolenbroek #ifdef HAS_SHOWTHREADS
1334*b89261baSDavid van Moolenbroek /* yes, but make sure it isn't just a thread */
1335*b89261baSDavid van Moolenbroek if (show_threads || !is_thread)
1336*b89261baSDavid van Moolenbroek {
1337*b89261baSDavid van Moolenbroek /* we will be showing this thread */
1338*b89261baSDavid van Moolenbroek *prefp++ = pp;
1339*b89261baSDavid van Moolenbroek active_procs++;
1340*b89261baSDavid van Moolenbroek }
1341*b89261baSDavid van Moolenbroek else
1342*b89261baSDavid van Moolenbroek {
1343*b89261baSDavid van Moolenbroek /* we will not be showing this thread, but we need to roll
1344*b89261baSDavid van Moolenbroek up its cpu usage in to its process */
1345*b89261baSDavid van Moolenbroek PP(prev_pp, pctcpu) += PP(pp, pctcpu);
1346*b89261baSDavid van Moolenbroek }
1347*b89261baSDavid van Moolenbroek #else /* !HAS_SHOWTHREADS */
1348*b89261baSDavid van Moolenbroek /* we will be showing this process */
1349*b89261baSDavid van Moolenbroek *prefp++ = pp;
1350*b89261baSDavid van Moolenbroek active_procs++;
1351*b89261baSDavid van Moolenbroek #endif
1352*b89261baSDavid van Moolenbroek }
1353*b89261baSDavid van Moolenbroek prev_pp = pp;
1354*b89261baSDavid van Moolenbroek }
1355*b89261baSDavid van Moolenbroek }
1356*b89261baSDavid van Moolenbroek
1357*b89261baSDavid van Moolenbroek dprintf("total_io: %d\n", total_io);
1358*b89261baSDavid van Moolenbroek if (total_io == 0) total_io = 1;
1359*b89261baSDavid van Moolenbroek
1360*b89261baSDavid van Moolenbroek /* if requested, sort the "interesting" processes */
1361*b89261baSDavid van Moolenbroek if (active_procs > 1)
1362*b89261baSDavid van Moolenbroek {
1363*b89261baSDavid van Moolenbroek qsort((char *)pref, active_procs, sizeof(struct kinfo_proc *),
1364*b89261baSDavid van Moolenbroek proc_compares[compare_index]);
1365*b89261baSDavid van Moolenbroek }
1366*b89261baSDavid van Moolenbroek
1367*b89261baSDavid van Moolenbroek /* remember active and total counts */
1368*b89261baSDavid van Moolenbroek si->p_total = total_procs;
1369*b89261baSDavid van Moolenbroek si->p_active = pref_len = active_procs;
1370*b89261baSDavid van Moolenbroek
1371*b89261baSDavid van Moolenbroek /* pass back a handle */
1372*b89261baSDavid van Moolenbroek handle.next_proc = pref;
1373*b89261baSDavid van Moolenbroek handle.remaining = active_procs;
1374*b89261baSDavid van Moolenbroek return((caddr_t)&handle);
1375*b89261baSDavid van Moolenbroek }
1376*b89261baSDavid van Moolenbroek
1377*b89261baSDavid van Moolenbroek static char p_header[MAX_COLS];
1378*b89261baSDavid van Moolenbroek
1379*b89261baSDavid van Moolenbroek char *
format_process_header(struct process_select * sel,caddr_t handle,int count)1380*b89261baSDavid van Moolenbroek format_process_header(struct process_select *sel, caddr_t handle, int count)
1381*b89261baSDavid van Moolenbroek
1382*b89261baSDavid van Moolenbroek {
1383*b89261baSDavid van Moolenbroek int cols;
1384*b89261baSDavid van Moolenbroek int n;
1385*b89261baSDavid van Moolenbroek int w;
1386*b89261baSDavid van Moolenbroek char *p;
1387*b89261baSDavid van Moolenbroek int *fi;
1388*b89261baSDavid van Moolenbroek struct kinfo_proc **kip;
1389*b89261baSDavid van Moolenbroek struct proc_field *fp;
1390*b89261baSDavid van Moolenbroek
1391*b89261baSDavid van Moolenbroek /* check for null handle */
1392*b89261baSDavid van Moolenbroek if (handle == NULL)
1393*b89261baSDavid van Moolenbroek {
1394*b89261baSDavid van Moolenbroek return("");
1395*b89261baSDavid van Moolenbroek }
1396*b89261baSDavid van Moolenbroek
1397*b89261baSDavid van Moolenbroek /* remember how many columns there are on the display */
1398*b89261baSDavid van Moolenbroek cols = display_columns();
1399*b89261baSDavid van Moolenbroek
1400*b89261baSDavid van Moolenbroek /* mode & threads dictate format */
1401*b89261baSDavid van Moolenbroek fi = display_fields =
1402*b89261baSDavid van Moolenbroek sel->mode == 0 ?
1403*b89261baSDavid van Moolenbroek (sel->threads == 0 ? mode0_display : mode0thr_display) :
1404*b89261baSDavid van Moolenbroek mode1_display;
1405*b89261baSDavid van Moolenbroek
1406*b89261baSDavid van Moolenbroek /* set username field correctly */
1407*b89261baSDavid van Moolenbroek if (!sel->usernames)
1408*b89261baSDavid van Moolenbroek {
1409*b89261baSDavid van Moolenbroek /* display uids */
1410*b89261baSDavid van Moolenbroek field_subst(fi, FIELD_USERNAME, FIELD_UID);
1411*b89261baSDavid van Moolenbroek }
1412*b89261baSDavid van Moolenbroek else
1413*b89261baSDavid van Moolenbroek {
1414*b89261baSDavid van Moolenbroek /* display usernames */
1415*b89261baSDavid van Moolenbroek field_subst(fi, FIELD_UID, FIELD_USERNAME);
1416*b89261baSDavid van Moolenbroek
1417*b89261baSDavid van Moolenbroek /* we also need to determine the longest username for column width */
1418*b89261baSDavid van Moolenbroek /* calculate namelength from first "count" processes */
1419*b89261baSDavid van Moolenbroek kip = ((struct handle *)handle)->next_proc;
1420*b89261baSDavid van Moolenbroek n = ((struct handle *)handle)->remaining;
1421*b89261baSDavid van Moolenbroek if (n > count)
1422*b89261baSDavid van Moolenbroek n = count;
1423*b89261baSDavid van Moolenbroek namelength = 0;
1424*b89261baSDavid van Moolenbroek while (n-- > 0)
1425*b89261baSDavid van Moolenbroek {
1426*b89261baSDavid van Moolenbroek w = strlen(username(PRUID(*kip)));
1427*b89261baSDavid van Moolenbroek if (w > namelength) namelength = w;
1428*b89261baSDavid van Moolenbroek kip++;
1429*b89261baSDavid van Moolenbroek }
1430*b89261baSDavid van Moolenbroek dprintf("format_process_header: namelength %d\n", namelength);
1431*b89261baSDavid van Moolenbroek
1432*b89261baSDavid van Moolenbroek /* place it in bounds */
1433*b89261baSDavid van Moolenbroek if (namelength < 8)
1434*b89261baSDavid van Moolenbroek {
1435*b89261baSDavid van Moolenbroek namelength = 8;
1436*b89261baSDavid van Moolenbroek }
1437*b89261baSDavid van Moolenbroek
1438*b89261baSDavid van Moolenbroek /* set the column width */
1439*b89261baSDavid van Moolenbroek proc_field[FIELD_USERNAME].width = username_length = namelength;
1440*b89261baSDavid van Moolenbroek }
1441*b89261baSDavid van Moolenbroek
1442*b89261baSDavid van Moolenbroek /* walk thru fields and construct header */
1443*b89261baSDavid van Moolenbroek /* are we worried about overflow??? */
1444*b89261baSDavid van Moolenbroek p = p_header;
1445*b89261baSDavid van Moolenbroek while (*fi != -1)
1446*b89261baSDavid van Moolenbroek {
1447*b89261baSDavid van Moolenbroek fp = &(proc_field[*fi++]);
1448*b89261baSDavid van Moolenbroek if (fp->min_screenwidth <= cols)
1449*b89261baSDavid van Moolenbroek {
1450*b89261baSDavid van Moolenbroek p += sprintf(p, fp->rjust ? "%*s" : "%-*s", fp->width, fp->name);
1451*b89261baSDavid van Moolenbroek *p++ = ' ';
1452*b89261baSDavid van Moolenbroek }
1453*b89261baSDavid van Moolenbroek }
1454*b89261baSDavid van Moolenbroek *--p = '\0';
1455*b89261baSDavid van Moolenbroek
1456*b89261baSDavid van Moolenbroek return p_header;
1457*b89261baSDavid van Moolenbroek }
1458*b89261baSDavid van Moolenbroek
1459*b89261baSDavid van Moolenbroek static char fmt[MAX_COLS]; /* static area where result is built */
1460*b89261baSDavid van Moolenbroek
1461*b89261baSDavid van Moolenbroek char *
format_next_process(caddr_t handle,char * (* get_userid)(int))1462*b89261baSDavid van Moolenbroek format_next_process(caddr_t handle, char *(*get_userid)(int))
1463*b89261baSDavid van Moolenbroek
1464*b89261baSDavid van Moolenbroek {
1465*b89261baSDavid van Moolenbroek struct kinfo_proc *pp;
1466*b89261baSDavid van Moolenbroek struct handle *hp;
1467*b89261baSDavid van Moolenbroek struct proc_field *fp;
1468*b89261baSDavid van Moolenbroek int *fi;
1469*b89261baSDavid van Moolenbroek int i;
1470*b89261baSDavid van Moolenbroek int cols;
1471*b89261baSDavid van Moolenbroek char *p;
1472*b89261baSDavid van Moolenbroek int len;
1473*b89261baSDavid van Moolenbroek int x;
1474*b89261baSDavid van Moolenbroek
1475*b89261baSDavid van Moolenbroek /* find and remember the next proc structure */
1476*b89261baSDavid van Moolenbroek hp = (struct handle *)handle;
1477*b89261baSDavid van Moolenbroek pp = *(hp->next_proc++);
1478*b89261baSDavid van Moolenbroek hp->remaining--;
1479*b89261baSDavid van Moolenbroek
1480*b89261baSDavid van Moolenbroek /* mode & threads dictate format */
1481*b89261baSDavid van Moolenbroek fi = display_fields;
1482*b89261baSDavid van Moolenbroek
1483*b89261baSDavid van Moolenbroek /* screen width is a consideration, too */
1484*b89261baSDavid van Moolenbroek cols = display_columns();
1485*b89261baSDavid van Moolenbroek
1486*b89261baSDavid van Moolenbroek /* build output by field */
1487*b89261baSDavid van Moolenbroek p = fmt;
1488*b89261baSDavid van Moolenbroek len = MAX_COLS;
1489*b89261baSDavid van Moolenbroek while ((i = *fi++) != -1)
1490*b89261baSDavid van Moolenbroek {
1491*b89261baSDavid van Moolenbroek fp = &(proc_field[i]);
1492*b89261baSDavid van Moolenbroek if (len > 0 && fp->min_screenwidth <= cols)
1493*b89261baSDavid van Moolenbroek {
1494*b89261baSDavid van Moolenbroek x = (*(fp->format))(p, len, pp);
1495*b89261baSDavid van Moolenbroek if (x >= len)
1496*b89261baSDavid van Moolenbroek {
1497*b89261baSDavid van Moolenbroek dprintf("format_next_process: formatter overflow: x %d, len %d, p %08x => %08x, fmt %08x - %08x\n",
1498*b89261baSDavid van Moolenbroek x, len, p, p + len, fmt, fmt + sizeof(fmt));
1499*b89261baSDavid van Moolenbroek p += len;
1500*b89261baSDavid van Moolenbroek len = 0;
1501*b89261baSDavid van Moolenbroek }
1502*b89261baSDavid van Moolenbroek else
1503*b89261baSDavid van Moolenbroek {
1504*b89261baSDavid van Moolenbroek p += x;
1505*b89261baSDavid van Moolenbroek *p++ = ' ';
1506*b89261baSDavid van Moolenbroek len -= x + 1;
1507*b89261baSDavid van Moolenbroek }
1508*b89261baSDavid van Moolenbroek }
1509*b89261baSDavid van Moolenbroek }
1510*b89261baSDavid van Moolenbroek *--p = '\0';
1511*b89261baSDavid van Moolenbroek
1512*b89261baSDavid van Moolenbroek /* return the result */
1513*b89261baSDavid van Moolenbroek return(fmt);
1514*b89261baSDavid van Moolenbroek }
1515*b89261baSDavid van Moolenbroek
1516*b89261baSDavid van Moolenbroek /* comparison routines for qsort */
1517*b89261baSDavid van Moolenbroek
1518*b89261baSDavid van Moolenbroek /*
1519*b89261baSDavid van Moolenbroek * proc_compare - comparison function for "qsort"
1520*b89261baSDavid van Moolenbroek * Compares the resource consumption of two processes using five
1521*b89261baSDavid van Moolenbroek * distinct keys. The keys (in descending order of importance) are:
1522*b89261baSDavid van Moolenbroek * percent cpu, cpu ticks, state, resident set size, total virtual
1523*b89261baSDavid van Moolenbroek * memory usage. The process states are ordered as follows (from least
1524*b89261baSDavid van Moolenbroek * to most important): WAIT, zombie, sleep, stop, start, run. The
1525*b89261baSDavid van Moolenbroek * array declaration below maps a process state index into a number
1526*b89261baSDavid van Moolenbroek * that reflects this ordering.
1527*b89261baSDavid van Moolenbroek */
1528*b89261baSDavid van Moolenbroek
1529*b89261baSDavid van Moolenbroek static unsigned char sorted_state[] =
1530*b89261baSDavid van Moolenbroek {
1531*b89261baSDavid van Moolenbroek 0, /* not used */
1532*b89261baSDavid van Moolenbroek 3, /* sleep */
1533*b89261baSDavid van Moolenbroek 1, /* ABANDONED (WAIT) */
1534*b89261baSDavid van Moolenbroek 6, /* run */
1535*b89261baSDavid van Moolenbroek 5, /* start */
1536*b89261baSDavid van Moolenbroek 2, /* zombie */
1537*b89261baSDavid van Moolenbroek 4 /* stop */
1538*b89261baSDavid van Moolenbroek };
1539*b89261baSDavid van Moolenbroek
1540*b89261baSDavid van Moolenbroek
1541*b89261baSDavid van Moolenbroek #define ORDERKEY_PCTCPU \
1542*b89261baSDavid van Moolenbroek if (lresult = (long) PPCPU(p2) - (long) PPCPU(p1), \
1543*b89261baSDavid van Moolenbroek (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0)
1544*b89261baSDavid van Moolenbroek
1545*b89261baSDavid van Moolenbroek #define ORDERKEY_CPTICKS \
1546*b89261baSDavid van Moolenbroek if ((result = PP(p2, runtime) > PP(p1, runtime) ? 1 : \
1547*b89261baSDavid van Moolenbroek PP(p2, runtime) < PP(p1, runtime) ? -1 : 0) == 0)
1548*b89261baSDavid van Moolenbroek
1549*b89261baSDavid van Moolenbroek #define ORDERKEY_STATE \
1550*b89261baSDavid van Moolenbroek if ((result = sorted_state[(unsigned char) PP(p2, stat)] - \
1551*b89261baSDavid van Moolenbroek sorted_state[(unsigned char) PP(p1, stat)]) == 0)
1552*b89261baSDavid van Moolenbroek
1553*b89261baSDavid van Moolenbroek #if OSMAJOR <= 4
1554*b89261baSDavid van Moolenbroek #define ORDERKEY_PRIO \
1555*b89261baSDavid van Moolenbroek if ((result = PP(p2, priority) - PP(p1, priority)) == 0)
1556*b89261baSDavid van Moolenbroek #else
1557*b89261baSDavid van Moolenbroek #define ORDERKEY_PRIO \
1558*b89261baSDavid van Moolenbroek if ((result = PP(p2, pri.pri_level) - PP(p1, pri.pri_level)) == 0)
1559*b89261baSDavid van Moolenbroek #endif
1560*b89261baSDavid van Moolenbroek
1561*b89261baSDavid van Moolenbroek #define ORDERKEY_RSSIZE \
1562*b89261baSDavid van Moolenbroek if ((result = VP(p2, rssize) - VP(p1, rssize)) == 0)
1563*b89261baSDavid van Moolenbroek
1564*b89261baSDavid van Moolenbroek #define ORDERKEY_MEM \
1565*b89261baSDavid van Moolenbroek if ( (result = PROCSIZE(p2) - PROCSIZE(p1)) == 0 )
1566*b89261baSDavid van Moolenbroek
1567*b89261baSDavid van Moolenbroek #define ORDERKEY_IO \
1568*b89261baSDavid van Moolenbroek if ( (result = SP(p2, totalio) - SP(p1, totalio)) == 0)
1569*b89261baSDavid van Moolenbroek
1570*b89261baSDavid van Moolenbroek #define ORDERKEY_PID \
1571*b89261baSDavid van Moolenbroek if ( (result = PP(p1, pid) - PP(p2, pid)) == 0)
1572*b89261baSDavid van Moolenbroek
1573*b89261baSDavid van Moolenbroek /* compare_cpu - the comparison function for sorting by cpu percentage */
1574*b89261baSDavid van Moolenbroek
1575*b89261baSDavid van Moolenbroek int
proc_compare(struct proc ** pp1,struct proc ** pp2)1576*b89261baSDavid van Moolenbroek proc_compare(struct proc **pp1, struct proc **pp2)
1577*b89261baSDavid van Moolenbroek
1578*b89261baSDavid van Moolenbroek {
1579*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1580*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1581*b89261baSDavid van Moolenbroek int result;
1582*b89261baSDavid van Moolenbroek pctcpu lresult;
1583*b89261baSDavid van Moolenbroek
1584*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1585*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1586*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1587*b89261baSDavid van Moolenbroek
1588*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1589*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1590*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1591*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1592*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1593*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1594*b89261baSDavid van Moolenbroek ;
1595*b89261baSDavid van Moolenbroek
1596*b89261baSDavid van Moolenbroek return(result);
1597*b89261baSDavid van Moolenbroek }
1598*b89261baSDavid van Moolenbroek
1599*b89261baSDavid van Moolenbroek /* compare_size - the comparison function for sorting by total memory usage */
1600*b89261baSDavid van Moolenbroek
1601*b89261baSDavid van Moolenbroek int
compare_size(struct proc ** pp1,struct proc ** pp2)1602*b89261baSDavid van Moolenbroek compare_size(struct proc **pp1, struct proc **pp2)
1603*b89261baSDavid van Moolenbroek
1604*b89261baSDavid van Moolenbroek {
1605*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1606*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1607*b89261baSDavid van Moolenbroek int result;
1608*b89261baSDavid van Moolenbroek pctcpu lresult;
1609*b89261baSDavid van Moolenbroek
1610*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1611*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1612*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1613*b89261baSDavid van Moolenbroek
1614*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1615*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1616*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1617*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1618*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1619*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1620*b89261baSDavid van Moolenbroek ;
1621*b89261baSDavid van Moolenbroek
1622*b89261baSDavid van Moolenbroek return(result);
1623*b89261baSDavid van Moolenbroek }
1624*b89261baSDavid van Moolenbroek
1625*b89261baSDavid van Moolenbroek /* compare_res - the comparison function for sorting by resident set size */
1626*b89261baSDavid van Moolenbroek
1627*b89261baSDavid van Moolenbroek int
compare_res(struct proc ** pp1,struct proc ** pp2)1628*b89261baSDavid van Moolenbroek compare_res(struct proc **pp1, struct proc **pp2)
1629*b89261baSDavid van Moolenbroek
1630*b89261baSDavid van Moolenbroek {
1631*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1632*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1633*b89261baSDavid van Moolenbroek int result;
1634*b89261baSDavid van Moolenbroek pctcpu lresult;
1635*b89261baSDavid van Moolenbroek
1636*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1637*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1638*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1639*b89261baSDavid van Moolenbroek
1640*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1641*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1642*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1643*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1644*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1645*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1646*b89261baSDavid van Moolenbroek ;
1647*b89261baSDavid van Moolenbroek
1648*b89261baSDavid van Moolenbroek return(result);
1649*b89261baSDavid van Moolenbroek }
1650*b89261baSDavid van Moolenbroek
1651*b89261baSDavid van Moolenbroek /* compare_time - the comparison function for sorting by total cpu time */
1652*b89261baSDavid van Moolenbroek
1653*b89261baSDavid van Moolenbroek int
compare_time(struct proc ** pp1,struct proc ** pp2)1654*b89261baSDavid van Moolenbroek compare_time(struct proc **pp1, struct proc **pp2)
1655*b89261baSDavid van Moolenbroek
1656*b89261baSDavid van Moolenbroek {
1657*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1658*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1659*b89261baSDavid van Moolenbroek int result;
1660*b89261baSDavid van Moolenbroek pctcpu lresult;
1661*b89261baSDavid van Moolenbroek
1662*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1663*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1664*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1665*b89261baSDavid van Moolenbroek
1666*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1667*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1668*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1669*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1670*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1671*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1672*b89261baSDavid van Moolenbroek ;
1673*b89261baSDavid van Moolenbroek
1674*b89261baSDavid van Moolenbroek return(result);
1675*b89261baSDavid van Moolenbroek }
1676*b89261baSDavid van Moolenbroek
1677*b89261baSDavid van Moolenbroek /* compare_prio - the comparison function for sorting by priority */
1678*b89261baSDavid van Moolenbroek
1679*b89261baSDavid van Moolenbroek int
compare_prio(struct proc ** pp1,struct proc ** pp2)1680*b89261baSDavid van Moolenbroek compare_prio(struct proc **pp1, struct proc **pp2)
1681*b89261baSDavid van Moolenbroek
1682*b89261baSDavid van Moolenbroek {
1683*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1684*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1685*b89261baSDavid van Moolenbroek int result;
1686*b89261baSDavid van Moolenbroek pctcpu lresult;
1687*b89261baSDavid van Moolenbroek
1688*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1689*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1690*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1691*b89261baSDavid van Moolenbroek
1692*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1693*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1694*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1695*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1696*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1697*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1698*b89261baSDavid van Moolenbroek ;
1699*b89261baSDavid van Moolenbroek
1700*b89261baSDavid van Moolenbroek return(result);
1701*b89261baSDavid van Moolenbroek }
1702*b89261baSDavid van Moolenbroek
1703*b89261baSDavid van Moolenbroek /* compare_io - the comparison function for sorting by io count */
1704*b89261baSDavid van Moolenbroek
1705*b89261baSDavid van Moolenbroek int
compare_io(struct proc ** pp1,struct proc ** pp2)1706*b89261baSDavid van Moolenbroek compare_io(struct proc **pp1, struct proc **pp2)
1707*b89261baSDavid van Moolenbroek
1708*b89261baSDavid van Moolenbroek {
1709*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1710*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1711*b89261baSDavid van Moolenbroek int result;
1712*b89261baSDavid van Moolenbroek pctcpu lresult;
1713*b89261baSDavid van Moolenbroek
1714*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1715*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1716*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1717*b89261baSDavid van Moolenbroek
1718*b89261baSDavid van Moolenbroek ORDERKEY_IO
1719*b89261baSDavid van Moolenbroek ORDERKEY_PCTCPU
1720*b89261baSDavid van Moolenbroek ORDERKEY_CPTICKS
1721*b89261baSDavid van Moolenbroek ORDERKEY_STATE
1722*b89261baSDavid van Moolenbroek ORDERKEY_PRIO
1723*b89261baSDavid van Moolenbroek ORDERKEY_RSSIZE
1724*b89261baSDavid van Moolenbroek ORDERKEY_MEM
1725*b89261baSDavid van Moolenbroek ;
1726*b89261baSDavid van Moolenbroek
1727*b89261baSDavid van Moolenbroek return(result);
1728*b89261baSDavid van Moolenbroek }
1729*b89261baSDavid van Moolenbroek
1730*b89261baSDavid van Moolenbroek /* compare_pid - the comparison function for sorting by process id */
1731*b89261baSDavid van Moolenbroek
1732*b89261baSDavid van Moolenbroek int
compare_pid(struct proc ** pp1,struct proc ** pp2)1733*b89261baSDavid van Moolenbroek compare_pid(struct proc **pp1, struct proc **pp2)
1734*b89261baSDavid van Moolenbroek
1735*b89261baSDavid van Moolenbroek {
1736*b89261baSDavid van Moolenbroek struct kinfo_proc *p1;
1737*b89261baSDavid van Moolenbroek struct kinfo_proc *p2;
1738*b89261baSDavid van Moolenbroek int result;
1739*b89261baSDavid van Moolenbroek
1740*b89261baSDavid van Moolenbroek /* remove one level of indirection */
1741*b89261baSDavid van Moolenbroek p1 = *(struct kinfo_proc **) pp1;
1742*b89261baSDavid van Moolenbroek p2 = *(struct kinfo_proc **) pp2;
1743*b89261baSDavid van Moolenbroek
1744*b89261baSDavid van Moolenbroek ORDERKEY_PID
1745*b89261baSDavid van Moolenbroek ;
1746*b89261baSDavid van Moolenbroek
1747*b89261baSDavid van Moolenbroek return(result);
1748*b89261baSDavid van Moolenbroek }
1749*b89261baSDavid van Moolenbroek
1750*b89261baSDavid van Moolenbroek /*
1751*b89261baSDavid van Moolenbroek * proc_owner(pid) - returns the uid that owns process "pid", or -1 if
1752*b89261baSDavid van Moolenbroek * the process does not exist.
1753*b89261baSDavid van Moolenbroek * It is EXTREMLY IMPORTANT that this function work correctly.
1754*b89261baSDavid van Moolenbroek * If top runs setuid root (as in SVR4), then this function
1755*b89261baSDavid van Moolenbroek * is the only thing that stands in the way of a serious
1756*b89261baSDavid van Moolenbroek * security problem. It validates requests for the "kill"
1757*b89261baSDavid van Moolenbroek * and "renice" commands.
1758*b89261baSDavid van Moolenbroek */
1759*b89261baSDavid van Moolenbroek
1760*b89261baSDavid van Moolenbroek int
proc_owner(int pid)1761*b89261baSDavid van Moolenbroek proc_owner(int pid)
1762*b89261baSDavid van Moolenbroek
1763*b89261baSDavid van Moolenbroek {
1764*b89261baSDavid van Moolenbroek int cnt;
1765*b89261baSDavid van Moolenbroek struct kinfo_proc **prefp;
1766*b89261baSDavid van Moolenbroek struct kinfo_proc *pp;
1767*b89261baSDavid van Moolenbroek
1768*b89261baSDavid van Moolenbroek prefp = pref;
1769*b89261baSDavid van Moolenbroek cnt = pref_len;
1770*b89261baSDavid van Moolenbroek while (--cnt >= 0)
1771*b89261baSDavid van Moolenbroek {
1772*b89261baSDavid van Moolenbroek pp = *prefp++;
1773*b89261baSDavid van Moolenbroek if (PP(pp, pid) == (pid_t)pid)
1774*b89261baSDavid van Moolenbroek {
1775*b89261baSDavid van Moolenbroek return((int)PRUID(pp));
1776*b89261baSDavid van Moolenbroek }
1777*b89261baSDavid van Moolenbroek }
1778*b89261baSDavid van Moolenbroek return(-1);
1779*b89261baSDavid van Moolenbroek }
1780*b89261baSDavid van Moolenbroek
1781