1 /* $OpenBSD: nlist.c,v 1.15 2005/01/07 20:41:13 otto Exp $ */
2 /* $NetBSD: nlist.c,v 1.11 1995/03/21 09:08:03 cgd Exp $ */
3
4 /*-
5 * Copyright (c) 1990, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)nlist.c 8.4 (Berkeley) 4/2/94";
36 #else
37 static char rcsid[] = "$OpenBSD: nlist.c,v 1.15 2005/01/07 20:41:13 otto Exp $";
38 #endif
39 #endif /* not lint */
40
41 #include <sys/param.h>
42 #include <sys/time.h>
43 #include <sys/proc.h>
44 #include <sys/resource.h>
45 #include <sys/sysctl.h>
46
47 #include <err.h>
48 #include <errno.h>
49 #include <kvm.h>
50 #include <nlist.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <unistd.h>
54
55 #include "ps.h"
56
57 struct nlist psnl[] = {
58 {"_fscale"},
59 #define X_FSCALE 0
60 {"_ccpu"},
61 #define X_CCPU 1
62 {"_physmem"},
63 #define X_PHYSMEM 2
64 {"_maxslp"},
65 #define X_MAXSLP 3
66 {NULL}
67 };
68
69 fixpt_t ccpu; /* kernel _ccpu variable */
70 int nlistread; /* if nlist already read. */
71 u_int mempages; /* number of pages of phys. memory */
72 int fscale; /* kernel _fscale variable */
73 int maxslp;
74
75 extern kvm_t *kd;
76 extern int kvm_sysctl_only;
77
78 #define kread(x, v) \
79 kvm_read(kd, psnl[x].n_value, &v, sizeof v) != sizeof(v)
80
81 int
donlist(void)82 donlist(void)
83 {
84 int rval, mib[2];
85 size_t siz;
86
87 rval = 0;
88 nlistread = 1;
89
90 if (kd != NULL && !kvm_sysctl_only) {
91 if (kvm_nlist(kd, psnl)) {
92 nlisterr(psnl);
93 eval = 1;
94 return (1);
95 }
96 if (kread(X_FSCALE, fscale)) {
97 warnx("fscale: %s", kvm_geterr(kd));
98 eval = rval = 1;
99 }
100 if (kread(X_PHYSMEM, mempages)) {
101 warnx("physmem: %s", kvm_geterr(kd));
102 eval = rval = 1;
103 }
104 if (kread(X_CCPU, ccpu)) {
105 warnx("ccpu: %s", kvm_geterr(kd));
106 eval = rval = 1;
107 }
108 if (kread(X_MAXSLP, maxslp)) {
109 warnx("maxslp: %s", kvm_geterr(kd));
110 eval = rval = 1;
111 }
112 } else {
113 siz = sizeof (fscale);
114 mib[0] = CTL_KERN;
115 mib[1] = KERN_FSCALE;
116 if (sysctl(mib, 2, &fscale, &siz, NULL, 0) < 0) {
117 warnx("fscale: failed to get kern.fscale");
118 eval = rval = 1;
119 }
120 siz = sizeof (mempages);
121 mib[0] = CTL_HW;
122 mib[1] = HW_PHYSMEM;
123 if (sysctl(mib, 2, &mempages, &siz, NULL, 0) < 0) {
124 warnx("physmem: failed to get hw.physmem");
125 eval = rval = 1;
126 }
127 mempages /= getpagesize(); /* translate bytes into page count */
128 siz = sizeof (ccpu);
129 mib[0] = CTL_KERN;
130 mib[1] = KERN_CCPU;
131 if (sysctl(mib, 2, &ccpu, &siz, NULL, 0) < 0) {
132 warnx("ccpu: failed to get kern.ccpu");
133 eval = rval = 1;
134 }
135 siz = sizeof (maxslp);
136 mib[0] = CTL_VM;
137 mib[1] = VM_MAXSLP;
138 if (sysctl(mib, 2, &maxslp, &siz, NULL, 0) < 0) {
139 warnx("maxslp: failed to get vm.maxslp");
140 eval = rval = 1;
141 }
142 }
143 return (rval);
144 }
145
146 void
nlisterr(struct nlist nl[])147 nlisterr(struct nlist nl[])
148 {
149 int i;
150
151 (void)fprintf(stderr, "ps: nlist: can't find following symbols:");
152 for (i = 0; nl[i].n_name != NULL; i++)
153 if (nl[i].n_value == 0)
154 (void)fprintf(stderr, " %s", nl[i].n_name);
155 (void)fprintf(stderr, "\n");
156 }
157