1 |
|
|
/* $OpenBSD: ipcs.c,v 1.26 2015/01/16 06:40:08 deraadt Exp $ */ |
2 |
|
|
/* $NetBSD: ipcs.c,v 1.25 2000/06/16 03:58:20 simonb Exp $ */ |
3 |
|
|
|
4 |
|
|
/*- |
5 |
|
|
* Copyright (c) 2000 The NetBSD Foundation, Inc. |
6 |
|
|
* All rights reserved. |
7 |
|
|
* |
8 |
|
|
* This code is derived from software contributed to The NetBSD Foundation |
9 |
|
|
* by Simon Burge. |
10 |
|
|
* |
11 |
|
|
* Redistribution and use in source and binary forms, with or without |
12 |
|
|
* modification, are permitted provided that the following conditions |
13 |
|
|
* are met: |
14 |
|
|
* 1. Redistributions of source code must retain the above copyright |
15 |
|
|
* notice, this list of conditions and the following disclaimer. |
16 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
17 |
|
|
* notice, this list of conditions and the following disclaimer in the |
18 |
|
|
* documentation and/or other materials provided with the distribution. |
19 |
|
|
* |
20 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 |
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 |
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 |
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 |
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 |
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 |
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 |
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 |
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 |
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 |
|
|
* POSSIBILITY OF SUCH DAMAGE. |
31 |
|
|
*/ |
32 |
|
|
|
33 |
|
|
/* |
34 |
|
|
* Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> |
35 |
|
|
* All rights reserved. |
36 |
|
|
* |
37 |
|
|
* Redistribution and use in source and binary forms, with or without |
38 |
|
|
* modification, are permitted provided that the following conditions |
39 |
|
|
* are met: |
40 |
|
|
* 1. Redistributions of source code must retain the above copyright |
41 |
|
|
* notice, this list of conditions and the following disclaimer. |
42 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
43 |
|
|
* notice, this list of conditions and the following disclaimer in the |
44 |
|
|
* documentation and/or other materials provided with the distribution. |
45 |
|
|
* |
46 |
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, |
47 |
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
48 |
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
49 |
|
|
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
50 |
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
51 |
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
52 |
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
53 |
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
54 |
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
55 |
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
56 |
|
|
*/ |
57 |
|
|
|
58 |
|
|
#include <sys/types.h> |
59 |
|
|
#include <sys/sysctl.h> |
60 |
|
|
#define _KERNEL /* XXX */ |
61 |
|
|
#include <sys/ipc.h> |
62 |
|
|
#include <sys/sem.h> |
63 |
|
|
#include <sys/shm.h> |
64 |
|
|
#include <sys/msg.h> |
65 |
|
|
#undef _KERNEL |
66 |
|
|
|
67 |
|
|
#include <err.h> |
68 |
|
|
#include <fcntl.h> |
69 |
|
|
#include <grp.h> |
70 |
|
|
#include <kvm.h> |
71 |
|
|
#include <limits.h> |
72 |
|
|
#include <nlist.h> |
73 |
|
|
#include <paths.h> |
74 |
|
|
#include <pwd.h> |
75 |
|
|
#include <stdio.h> |
76 |
|
|
#include <stdlib.h> |
77 |
|
|
#include <string.h> |
78 |
|
|
#include <time.h> |
79 |
|
|
#include <unistd.h> |
80 |
|
|
|
81 |
|
|
void cvt_time(time_t, char *, size_t); |
82 |
|
|
char *fmt_perm(mode_t); |
83 |
|
|
void ipcs_kvm(void); |
84 |
|
|
int main(int, char **); |
85 |
|
|
void msg_sysctl(void); |
86 |
|
|
void sem_sysctl(void); |
87 |
|
|
void shm_sysctl(void); |
88 |
|
|
void show_msginfo(time_t, time_t, time_t, int, key_t, mode_t, uid_t, |
89 |
|
|
gid_t, uid_t, gid_t, u_long, u_long, u_long, pid_t, pid_t); |
90 |
|
|
void show_msginfo_hdr(void); |
91 |
|
|
void show_msgtotal(struct msginfo *); |
92 |
|
|
void show_seminfo_hdr(void); |
93 |
|
|
void show_seminfo(time_t, time_t, int, key_t, mode_t, uid_t, gid_t, |
94 |
|
|
uid_t, gid_t, int16_t); |
95 |
|
|
void show_semtotal(struct seminfo *); |
96 |
|
|
void show_shminfo(time_t, time_t, time_t, int, key_t, mode_t, uid_t, |
97 |
|
|
gid_t, uid_t, gid_t, u_int32_t, int, pid_t, pid_t); |
98 |
|
|
void show_shminfo_hdr(void); |
99 |
|
|
void show_shmtotal(struct shminfo *); |
100 |
|
|
__dead void usage(void); |
101 |
|
|
|
102 |
|
|
char * |
103 |
|
|
fmt_perm(mode_t mode) |
104 |
|
|
{ |
105 |
|
|
static char buffer[12]; |
106 |
|
|
|
107 |
|
|
buffer[0] = '-'; |
108 |
|
|
buffer[1] = '-'; |
109 |
|
|
buffer[2] = ((mode & 0400) ? 'r' : '-'); |
110 |
|
|
buffer[3] = ((mode & 0200) ? 'w' : '-'); |
111 |
|
|
buffer[4] = ((mode & 0100) ? 'a' : '-'); |
112 |
|
|
buffer[5] = ((mode & 0040) ? 'r' : '-'); |
113 |
|
|
buffer[6] = ((mode & 0020) ? 'w' : '-'); |
114 |
|
|
buffer[7] = ((mode & 0010) ? 'a' : '-'); |
115 |
|
|
buffer[8] = ((mode & 0004) ? 'r' : '-'); |
116 |
|
|
buffer[9] = ((mode & 0002) ? 'w' : '-'); |
117 |
|
|
buffer[10] = ((mode & 0001) ? 'a' : '-'); |
118 |
|
|
buffer[11] = '\0'; |
119 |
|
|
return (&buffer[0]); |
120 |
|
|
} |
121 |
|
|
|
122 |
|
|
void |
123 |
|
|
cvt_time(time_t t, char *buf, size_t buflen) |
124 |
|
|
{ |
125 |
|
|
struct tm *tm; |
126 |
|
|
|
127 |
|
|
if (t == 0) |
128 |
|
|
(void)strlcpy(buf, "no-entry", buflen); |
129 |
|
|
else { |
130 |
|
|
tm = localtime(&t); |
131 |
|
|
(void)snprintf(buf, buflen, "%2d:%02d:%02d", |
132 |
|
|
tm->tm_hour, tm->tm_min, tm->tm_sec); |
133 |
|
|
} |
134 |
|
|
} |
135 |
|
|
#define SHMINFO 1 |
136 |
|
|
#define SHMTOTAL 2 |
137 |
|
|
#define MSGINFO 4 |
138 |
|
|
#define MSGTOTAL 8 |
139 |
|
|
#define SEMINFO 16 |
140 |
|
|
#define SEMTOTAL 32 |
141 |
|
|
|
142 |
|
|
#define BIGGEST 1 |
143 |
|
|
#define CREATOR 2 |
144 |
|
|
#define OUTSTANDING 4 |
145 |
|
|
#define PID 8 |
146 |
|
|
#define TIME 16 |
147 |
|
|
|
148 |
|
|
char *core = NULL, *namelist = NULL; |
149 |
|
|
int display = SHMINFO | MSGINFO | SEMINFO; |
150 |
|
|
int option = 0; |
151 |
|
|
|
152 |
|
|
int |
153 |
|
|
main(int argc, char **argv) |
154 |
|
|
{ |
155 |
|
|
int ch; |
156 |
|
|
|
157 |
|
|
while ((ch = getopt(argc, argv, "MmQqSsabC:cN:optT")) != -1) |
158 |
|
|
switch (ch) { |
159 |
|
|
case 'M': |
160 |
|
|
display = SHMTOTAL; |
161 |
|
|
break; |
162 |
|
|
case 'm': |
163 |
|
|
display = SHMINFO; |
164 |
|
|
break; |
165 |
|
|
case 'Q': |
166 |
|
|
display = MSGTOTAL; |
167 |
|
|
break; |
168 |
|
|
case 'q': |
169 |
|
|
display = MSGINFO; |
170 |
|
|
break; |
171 |
|
|
case 'S': |
172 |
|
|
display = SEMTOTAL; |
173 |
|
|
break; |
174 |
|
|
case 's': |
175 |
|
|
display = SEMINFO; |
176 |
|
|
break; |
177 |
|
|
case 'T': |
178 |
|
|
display = SHMTOTAL | MSGTOTAL | SEMTOTAL; |
179 |
|
|
break; |
180 |
|
|
case 'a': |
181 |
|
|
option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; |
182 |
|
|
break; |
183 |
|
|
case 'b': |
184 |
|
|
option |= BIGGEST; |
185 |
|
|
break; |
186 |
|
|
case 'C': |
187 |
|
|
core = optarg; |
188 |
|
|
break; |
189 |
|
|
case 'c': |
190 |
|
|
option |= CREATOR; |
191 |
|
|
break; |
192 |
|
|
case 'N': |
193 |
|
|
namelist = optarg; |
194 |
|
|
break; |
195 |
|
|
case 'o': |
196 |
|
|
option |= OUTSTANDING; |
197 |
|
|
break; |
198 |
|
|
case 'p': |
199 |
|
|
option |= PID; |
200 |
|
|
break; |
201 |
|
|
case 't': |
202 |
|
|
option |= TIME; |
203 |
|
|
break; |
204 |
|
|
default: |
205 |
|
|
usage(); |
206 |
|
|
} |
207 |
|
|
|
208 |
|
|
if (argc - optind > 0) |
209 |
|
|
usage(); |
210 |
|
|
|
211 |
|
|
if (namelist == NULL && core == NULL) { |
212 |
|
|
if (display & (MSGINFO | MSGTOTAL)) |
213 |
|
|
msg_sysctl(); |
214 |
|
|
if (display & (SHMINFO | SHMTOTAL)) |
215 |
|
|
shm_sysctl(); |
216 |
|
|
if (display & (SEMINFO | SEMTOTAL)) |
217 |
|
|
sem_sysctl(); |
218 |
|
|
} else |
219 |
|
|
ipcs_kvm(); |
220 |
|
|
|
221 |
|
|
exit(0); |
222 |
|
|
} |
223 |
|
|
|
224 |
|
|
void |
225 |
|
|
show_msgtotal(struct msginfo *msginfo) |
226 |
|
|
{ |
227 |
|
|
|
228 |
|
|
printf("msginfo:\n"); |
229 |
|
|
printf("\tmsgmax: %6d\t(max characters in a message)\n", |
230 |
|
|
msginfo->msgmax); |
231 |
|
|
printf("\tmsgmni: %6d\t(# of message queues)\n", |
232 |
|
|
msginfo->msgmni); |
233 |
|
|
printf("\tmsgmnb: %6d\t(max characters in a message queue)\n", |
234 |
|
|
msginfo->msgmnb); |
235 |
|
|
printf("\tmsgtql: %6d\t(max # of messages in system)\n", |
236 |
|
|
msginfo->msgtql); |
237 |
|
|
printf("\tmsgssz: %6d\t(size of a message segment)\n", |
238 |
|
|
msginfo->msgssz); |
239 |
|
|
printf("\tmsgseg: %6d\t(# of message segments in system)\n\n", |
240 |
|
|
msginfo->msgseg); |
241 |
|
|
} |
242 |
|
|
|
243 |
|
|
void |
244 |
|
|
show_shmtotal(struct shminfo *shminfo) |
245 |
|
|
{ |
246 |
|
|
|
247 |
|
|
printf("shminfo:\n"); |
248 |
|
|
printf("\tshmmax: %7d\t(max shared memory segment size)\n", |
249 |
|
|
shminfo->shmmax); |
250 |
|
|
printf("\tshmmin: %7d\t(min shared memory segment size)\n", |
251 |
|
|
shminfo->shmmin); |
252 |
|
|
printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n", |
253 |
|
|
shminfo->shmmni); |
254 |
|
|
printf("\tshmseg: %7d\t(max shared memory segments per process)\n", |
255 |
|
|
shminfo->shmseg); |
256 |
|
|
printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n", |
257 |
|
|
shminfo->shmall); |
258 |
|
|
} |
259 |
|
|
|
260 |
|
|
void |
261 |
|
|
show_semtotal(struct seminfo *seminfo) |
262 |
|
|
{ |
263 |
|
|
|
264 |
|
|
printf("seminfo:\n"); |
265 |
|
|
printf("\tsemmni: %6d\t(# of semaphore identifiers)\n", |
266 |
|
|
seminfo->semmni); |
267 |
|
|
printf("\tsemmns: %6d\t(# of semaphores in system)\n", |
268 |
|
|
seminfo->semmns); |
269 |
|
|
printf("\tsemmnu: %6d\t(# of undo structures in system)\n", |
270 |
|
|
seminfo->semmnu); |
271 |
|
|
printf("\tsemmsl: %6d\t(max # of semaphores per id)\n", |
272 |
|
|
seminfo->semmsl); |
273 |
|
|
printf("\tsemopm: %6d\t(max # of operations per semop call)\n", |
274 |
|
|
seminfo->semopm); |
275 |
|
|
printf("\tsemume: %6d\t(max # of undo entries per process)\n", |
276 |
|
|
seminfo->semume); |
277 |
|
|
printf("\tsemusz: %6d\t(size in bytes of undo structure)\n", |
278 |
|
|
seminfo->semusz); |
279 |
|
|
printf("\tsemvmx: %6d\t(semaphore maximum value)\n", |
280 |
|
|
seminfo->semvmx); |
281 |
|
|
printf("\tsemaem: %6d\t(adjust on exit max value)\n\n", |
282 |
|
|
seminfo->semaem); |
283 |
|
|
} |
284 |
|
|
|
285 |
|
|
void |
286 |
|
|
show_msginfo_hdr(void) |
287 |
|
|
{ |
288 |
|
|
|
289 |
|
|
printf("Message Queues:\n"); |
290 |
|
|
printf("T ID KEY MODE OWNER GROUP"); |
291 |
|
|
if (option & CREATOR) |
292 |
|
|
printf(" CREATOR CGROUP"); |
293 |
|
|
if (option & OUTSTANDING) |
294 |
|
|
printf(" CBYTES QNUM"); |
295 |
|
|
if (option & BIGGEST) |
296 |
|
|
printf(" QBYTES"); |
297 |
|
|
if (option & PID) |
298 |
|
|
printf(" LSPID LRPID"); |
299 |
|
|
if (option & TIME) |
300 |
|
|
printf(" STIME RTIME CTIME"); |
301 |
|
|
printf("\n"); |
302 |
|
|
} |
303 |
|
|
|
304 |
|
|
void |
305 |
|
|
show_msginfo(time_t stime, time_t rtime, time_t ctime, int ipcid, key_t key, |
306 |
|
|
mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, |
307 |
|
|
u_long cbytes, u_long qnum, u_long qbytes, pid_t lspid, |
308 |
|
|
pid_t lrpid) |
309 |
|
|
{ |
310 |
|
|
char stime_buf[100], rtime_buf[100], ctime_buf[100]; |
311 |
|
|
|
312 |
|
|
if (option & TIME) { |
313 |
|
|
cvt_time(stime, stime_buf, sizeof(stime_buf)); |
314 |
|
|
cvt_time(rtime, rtime_buf, sizeof(rtime_buf)); |
315 |
|
|
cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); |
316 |
|
|
} |
317 |
|
|
|
318 |
|
|
printf("q %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), |
319 |
|
|
user_from_uid(uid, 0), group_from_gid(gid, 0)); |
320 |
|
|
|
321 |
|
|
if (option & CREATOR) |
322 |
|
|
printf(" %8s %8s", user_from_uid(cuid, 0), |
323 |
|
|
group_from_gid(cgid, 0)); |
324 |
|
|
|
325 |
|
|
if (option & OUTSTANDING) |
326 |
|
|
printf(" %6lu %5lu", cbytes, qnum); |
327 |
|
|
|
328 |
|
|
if (option & BIGGEST) |
329 |
|
|
printf(" %6lu", qbytes); |
330 |
|
|
|
331 |
|
|
if (option & PID) |
332 |
|
|
printf(" %5ld %5ld", (long)lspid, (long)lrpid); |
333 |
|
|
|
334 |
|
|
if (option & TIME) |
335 |
|
|
printf(" %s %s %s", stime_buf, rtime_buf, ctime_buf); |
336 |
|
|
|
337 |
|
|
printf("\n"); |
338 |
|
|
} |
339 |
|
|
|
340 |
|
|
void |
341 |
|
|
show_shminfo_hdr(void) |
342 |
|
|
{ |
343 |
|
|
|
344 |
|
|
printf("Shared Memory:\n"); |
345 |
|
|
printf("T ID KEY MODE OWNER GROUP"); |
346 |
|
|
if (option & CREATOR) |
347 |
|
|
printf(" CREATOR CGROUP"); |
348 |
|
|
if (option & OUTSTANDING) |
349 |
|
|
printf(" NATTCH"); |
350 |
|
|
if (option & BIGGEST) |
351 |
|
|
printf(" SEGSZ"); |
352 |
|
|
if (option & PID) |
353 |
|
|
printf(" CPID LPID"); |
354 |
|
|
if (option & TIME) |
355 |
|
|
printf(" ATIME DTIME CTIME"); |
356 |
|
|
printf("\n"); |
357 |
|
|
} |
358 |
|
|
|
359 |
|
|
void |
360 |
|
|
show_shminfo(time_t atime, time_t dtime, time_t ctime, int ipcid, key_t key, |
361 |
|
|
mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, |
362 |
|
|
u_int32_t nattch, int segsz, pid_t cpid, pid_t lpid) |
363 |
|
|
{ |
364 |
|
|
char atime_buf[100], dtime_buf[100], ctime_buf[100]; |
365 |
|
|
|
366 |
|
|
if (option & TIME) { |
367 |
|
|
cvt_time(atime, atime_buf, sizeof(atime_buf)); |
368 |
|
|
cvt_time(dtime, dtime_buf, sizeof(dtime_buf)); |
369 |
|
|
cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); |
370 |
|
|
} |
371 |
|
|
|
372 |
|
|
printf("m %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), |
373 |
|
|
user_from_uid(uid, 0), group_from_gid(gid, 0)); |
374 |
|
|
|
375 |
|
|
if (option & CREATOR) |
376 |
|
|
printf(" %8s %8s", user_from_uid(cuid, 0), |
377 |
|
|
group_from_gid(cgid, 0)); |
378 |
|
|
|
379 |
|
|
if (option & OUTSTANDING) |
380 |
|
|
printf(" %6d", nattch); |
381 |
|
|
|
382 |
|
|
if (option & BIGGEST) |
383 |
|
|
printf(" %7d", segsz); |
384 |
|
|
|
385 |
|
|
if (option & PID) |
386 |
|
|
printf(" %5d %5d", cpid, lpid); |
387 |
|
|
|
388 |
|
|
if (option & TIME) |
389 |
|
|
printf(" %s %s %s", |
390 |
|
|
atime_buf, |
391 |
|
|
dtime_buf, |
392 |
|
|
ctime_buf); |
393 |
|
|
|
394 |
|
|
printf("\n"); |
395 |
|
|
} |
396 |
|
|
|
397 |
|
|
void |
398 |
|
|
show_seminfo_hdr(void) |
399 |
|
|
{ |
400 |
|
|
|
401 |
|
|
printf("Semaphores:\n"); |
402 |
|
|
printf("T ID KEY MODE OWNER GROUP"); |
403 |
|
|
if (option & CREATOR) |
404 |
|
|
printf(" CREATOR CGROUP"); |
405 |
|
|
if (option & BIGGEST) |
406 |
|
|
printf(" NSEMS"); |
407 |
|
|
if (option & TIME) |
408 |
|
|
printf(" OTIME CTIME"); |
409 |
|
|
printf("\n"); |
410 |
|
|
} |
411 |
|
|
|
412 |
|
|
void |
413 |
|
|
show_seminfo(time_t otime, time_t ctime, int ipcid, key_t key, mode_t mode, |
414 |
|
|
uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, int16_t nsems) |
415 |
|
|
{ |
416 |
|
|
char ctime_buf[100], otime_buf[100]; |
417 |
|
|
|
418 |
|
|
if (option & TIME) { |
419 |
|
|
cvt_time(otime, otime_buf, sizeof(otime_buf)); |
420 |
|
|
cvt_time(ctime, ctime_buf, sizeof(ctime_buf)); |
421 |
|
|
} |
422 |
|
|
|
423 |
|
|
printf("s %8d %10ld %s %8s %8s", ipcid, key, fmt_perm(mode), |
424 |
|
|
user_from_uid(uid, 0), group_from_gid(gid, 0)); |
425 |
|
|
|
426 |
|
|
if (option & CREATOR) |
427 |
|
|
printf(" %8s %8s", user_from_uid(cuid, 0), |
428 |
|
|
group_from_gid(cgid, 0)); |
429 |
|
|
|
430 |
|
|
if (option & BIGGEST) |
431 |
|
|
printf(" %5d", nsems); |
432 |
|
|
|
433 |
|
|
if (option & TIME) |
434 |
|
|
printf(" %s %s", otime_buf, ctime_buf); |
435 |
|
|
|
436 |
|
|
printf("\n"); |
437 |
|
|
} |
438 |
|
|
|
439 |
|
|
void |
440 |
|
|
msg_sysctl(void) |
441 |
|
|
{ |
442 |
|
|
struct msg_sysctl_info *msgsi; |
443 |
|
|
char *buf; |
444 |
|
|
int mib[3]; |
445 |
|
|
size_t len; |
446 |
|
|
int i, valid; |
447 |
|
|
|
448 |
|
|
mib[0] = CTL_KERN; |
449 |
|
|
mib[1] = KERN_SYSVMSG; |
450 |
|
|
len = sizeof(valid); |
451 |
|
|
if (sysctl(mib, 2, &valid, &len, NULL, 0) < 0) { |
452 |
|
|
warn("sysctl(KERN_SYSVMSG)"); |
453 |
|
|
return; |
454 |
|
|
} |
455 |
|
|
if (!valid) { |
456 |
|
|
warnx("SVID messages facility not configured in the system"); |
457 |
|
|
return; |
458 |
|
|
} |
459 |
|
|
|
460 |
|
|
mib[0] = CTL_KERN; |
461 |
|
|
mib[1] = KERN_SYSVIPC_INFO; |
462 |
|
|
mib[2] = KERN_SYSVIPC_MSG_INFO; |
463 |
|
|
|
464 |
|
|
if (!(display & MSGINFO)) { |
465 |
|
|
/* totals only */ |
466 |
|
|
len = sizeof(struct msginfo); |
467 |
|
|
} else { |
468 |
|
|
if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) { |
469 |
|
|
warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); |
470 |
|
|
return; |
471 |
|
|
} |
472 |
|
|
} |
473 |
|
|
|
474 |
|
|
if ((buf = malloc(len)) == NULL) |
475 |
|
|
err(1, "malloc"); |
476 |
|
|
msgsi = (struct msg_sysctl_info *)buf; |
477 |
|
|
if (sysctl(mib, 3, msgsi, &len, NULL, 0) < 0) { |
478 |
|
|
warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); |
479 |
|
|
return; |
480 |
|
|
} |
481 |
|
|
|
482 |
|
|
if (display & MSGTOTAL) |
483 |
|
|
show_msgtotal(&msgsi->msginfo); |
484 |
|
|
|
485 |
|
|
if (display & MSGINFO) { |
486 |
|
|
show_msginfo_hdr(); |
487 |
|
|
for (i = 0; i < msgsi->msginfo.msgmni; i++) { |
488 |
|
|
struct msqid_ds *msqptr = &msgsi->msgids[i]; |
489 |
|
|
if (msqptr->msg_qbytes != 0) |
490 |
|
|
show_msginfo(msqptr->msg_stime, |
491 |
|
|
msqptr->msg_rtime, |
492 |
|
|
msqptr->msg_ctime, |
493 |
|
|
IXSEQ_TO_IPCID(i, msqptr->msg_perm), |
494 |
|
|
msqptr->msg_perm.key, |
495 |
|
|
msqptr->msg_perm.mode, |
496 |
|
|
msqptr->msg_perm.uid, |
497 |
|
|
msqptr->msg_perm.gid, |
498 |
|
|
msqptr->msg_perm.cuid, |
499 |
|
|
msqptr->msg_perm.cgid, |
500 |
|
|
msqptr->msg_cbytes, |
501 |
|
|
msqptr->msg_qnum, |
502 |
|
|
msqptr->msg_qbytes, |
503 |
|
|
msqptr->msg_lspid, |
504 |
|
|
msqptr->msg_lrpid); |
505 |
|
|
} |
506 |
|
|
printf("\n"); |
507 |
|
|
} |
508 |
|
|
} |
509 |
|
|
|
510 |
|
|
void |
511 |
|
|
shm_sysctl(void) |
512 |
|
|
{ |
513 |
|
|
struct shm_sysctl_info *shmsi; |
514 |
|
|
char *buf; |
515 |
|
|
int mib[3]; |
516 |
|
|
size_t len; |
517 |
|
|
int i, valid; |
518 |
|
|
|
519 |
|
|
mib[0] = CTL_KERN; |
520 |
|
|
mib[1] = KERN_SYSVSHM; |
521 |
|
|
len = sizeof(valid); |
522 |
|
|
if (sysctl(mib, 2, &valid, &len, NULL, 0) < 0) { |
523 |
|
|
warn("sysctl(KERN_SYSVSHM)"); |
524 |
|
|
return; |
525 |
|
|
} |
526 |
|
|
if (!valid) { |
527 |
|
|
warnx("SVID shared memory facility not configured in " |
528 |
|
|
"the system"); |
529 |
|
|
return; |
530 |
|
|
} |
531 |
|
|
|
532 |
|
|
mib[0] = CTL_KERN; |
533 |
|
|
mib[1] = KERN_SYSVIPC_INFO; |
534 |
|
|
mib[2] = KERN_SYSVIPC_SHM_INFO; |
535 |
|
|
|
536 |
|
|
if (!(display & SHMINFO)) { |
537 |
|
|
/* totals only */ |
538 |
|
|
len = sizeof(struct shminfo); |
539 |
|
|
} else { |
540 |
|
|
if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) { |
541 |
|
|
warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); |
542 |
|
|
return; |
543 |
|
|
} |
544 |
|
|
} |
545 |
|
|
|
546 |
|
|
if ((buf = malloc(len)) == NULL) |
547 |
|
|
err(1, "malloc"); |
548 |
|
|
shmsi = (struct shm_sysctl_info *)buf; |
549 |
|
|
if (sysctl(mib, 3, shmsi, &len, NULL, 0) < 0) { |
550 |
|
|
warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); |
551 |
|
|
return; |
552 |
|
|
} |
553 |
|
|
|
554 |
|
|
if (display & SHMTOTAL) |
555 |
|
|
show_shmtotal(&shmsi->shminfo); |
556 |
|
|
|
557 |
|
|
if (display & SHMINFO) { |
558 |
|
|
show_shminfo_hdr(); |
559 |
|
|
for (i = 0; i < shmsi->shminfo.shmmni; i++) { |
560 |
|
|
struct shmid_ds *shmptr = &shmsi->shmids[i]; |
561 |
|
|
if (shmptr->shm_internal) |
562 |
|
|
show_shminfo(shmptr->shm_atime, |
563 |
|
|
shmptr->shm_dtime, |
564 |
|
|
shmptr->shm_ctime, |
565 |
|
|
IXSEQ_TO_IPCID(i, shmptr->shm_perm), |
566 |
|
|
shmptr->shm_perm.key, |
567 |
|
|
shmptr->shm_perm.mode, |
568 |
|
|
shmptr->shm_perm.uid, |
569 |
|
|
shmptr->shm_perm.gid, |
570 |
|
|
shmptr->shm_perm.cuid, |
571 |
|
|
shmptr->shm_perm.cgid, |
572 |
|
|
shmptr->shm_nattch, |
573 |
|
|
shmptr->shm_segsz, |
574 |
|
|
shmptr->shm_cpid, |
575 |
|
|
shmptr->shm_lpid); |
576 |
|
|
} |
577 |
|
|
printf("\n"); |
578 |
|
|
} |
579 |
|
|
} |
580 |
|
|
|
581 |
|
|
void |
582 |
|
|
sem_sysctl(void) |
583 |
|
|
{ |
584 |
|
|
struct sem_sysctl_info *semsi; |
585 |
|
|
char *buf; |
586 |
|
|
int mib[3]; |
587 |
|
|
size_t len; |
588 |
|
|
int i, valid; |
589 |
|
|
|
590 |
|
|
mib[0] = CTL_KERN; |
591 |
|
|
mib[1] = KERN_SYSVSEM; |
592 |
|
|
len = sizeof(valid); |
593 |
|
|
if (sysctl(mib, 2, &valid, &len, NULL, 0) < 0) { |
594 |
|
|
warn("sysctl(KERN_SYSVSEM)"); |
595 |
|
|
return; |
596 |
|
|
} |
597 |
|
|
if (!valid) { |
598 |
|
|
warnx("SVID shared memory facility not configured in " |
599 |
|
|
"the system"); |
600 |
|
|
return; |
601 |
|
|
} |
602 |
|
|
|
603 |
|
|
mib[0] = CTL_KERN; |
604 |
|
|
mib[1] = KERN_SYSVIPC_INFO; |
605 |
|
|
mib[2] = KERN_SYSVIPC_SEM_INFO; |
606 |
|
|
|
607 |
|
|
if (!(display & SEMINFO)) { |
608 |
|
|
/* totals only */ |
609 |
|
|
len = sizeof(struct seminfo); |
610 |
|
|
} else { |
611 |
|
|
if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) { |
612 |
|
|
warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); |
613 |
|
|
return; |
614 |
|
|
} |
615 |
|
|
} |
616 |
|
|
|
617 |
|
|
if ((buf = malloc(len)) == NULL) |
618 |
|
|
err(1, "malloc"); |
619 |
|
|
semsi = (struct sem_sysctl_info *)buf; |
620 |
|
|
if (sysctl(mib, 3, semsi, &len, NULL, 0) < 0) { |
621 |
|
|
warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); |
622 |
|
|
return; |
623 |
|
|
} |
624 |
|
|
|
625 |
|
|
if (display & SEMTOTAL) |
626 |
|
|
show_semtotal(&semsi->seminfo); |
627 |
|
|
|
628 |
|
|
if (display & SEMINFO) { |
629 |
|
|
show_seminfo_hdr(); |
630 |
|
|
for (i = 0; i < semsi->seminfo.semmni; i++) { |
631 |
|
|
struct semid_ds *semaptr = &semsi->semids[i]; |
632 |
|
|
|
633 |
|
|
if (semaptr->sem_base != NULL) |
634 |
|
|
show_seminfo(semaptr->sem_otime, |
635 |
|
|
semaptr->sem_ctime, |
636 |
|
|
IXSEQ_TO_IPCID(i, semaptr->sem_perm), |
637 |
|
|
semaptr->sem_perm.key, |
638 |
|
|
semaptr->sem_perm.mode, |
639 |
|
|
semaptr->sem_perm.uid, |
640 |
|
|
semaptr->sem_perm.gid, |
641 |
|
|
semaptr->sem_perm.cuid, |
642 |
|
|
semaptr->sem_perm.cgid, |
643 |
|
|
semaptr->sem_nsems); |
644 |
|
|
} |
645 |
|
|
printf("\n"); |
646 |
|
|
} |
647 |
|
|
} |
648 |
|
|
|
649 |
|
|
void |
650 |
|
|
ipcs_kvm(void) |
651 |
|
|
{ |
652 |
|
|
struct msginfo msginfo; |
653 |
|
|
struct que msgque; |
654 |
|
|
struct msqid_ds *msqids; |
655 |
|
|
struct seminfo seminfo; |
656 |
|
|
struct semid_ds sem, **sema; |
657 |
|
|
struct shminfo shminfo; |
658 |
|
|
struct shmid_ds shmseg, **shmsegs; |
659 |
|
|
char errbuf[_POSIX2_LINE_MAX]; |
660 |
|
|
u_long addr; |
661 |
|
|
kvm_t *kd; |
662 |
|
|
int i; |
663 |
|
|
struct nlist symbols[] = { |
664 |
|
|
{"_sema"}, |
665 |
|
|
#define X_SEMA 0 |
666 |
|
|
{"_seminfo"}, |
667 |
|
|
#define X_SEMINFO 1 |
668 |
|
|
{"_semu"}, |
669 |
|
|
#define X_SEMU 2 |
670 |
|
|
{"_msginfo"}, |
671 |
|
|
#define X_MSGINFO 3 |
672 |
|
|
{"_msg_queues"}, |
673 |
|
|
#define X_MSG_QUEUES 4 |
674 |
|
|
{"_shminfo"}, |
675 |
|
|
#define X_SHMINFO 5 |
676 |
|
|
{"_shmsegs"}, |
677 |
|
|
#define X_SHMSEGS 6 |
678 |
|
|
{NULL} |
679 |
|
|
}; |
680 |
|
|
|
681 |
|
|
if ((kd = kvm_openfiles(namelist, core, NULL, O_RDONLY, |
682 |
|
|
errbuf)) == NULL) |
683 |
|
|
errx(1, "can't open kvm: %s", errbuf); |
684 |
|
|
|
685 |
|
|
switch (kvm_nlist(kd, symbols)) { |
686 |
|
|
case 0: |
687 |
|
|
break; |
688 |
|
|
case -1: |
689 |
|
|
errx(1, "%s: unable to read symbol table.", |
690 |
|
|
namelist == NULL ? _PATH_UNIX : namelist); |
691 |
|
|
/* NOTREACHED */ |
692 |
|
|
default: |
693 |
|
|
#ifdef notdef /* they'll be told more civilly later */ |
694 |
|
|
warnx("nlist failed"); |
695 |
|
|
for (i = 0; symbols[i].n_name != NULL; i++) |
696 |
|
|
if (symbols[i].n_value == 0) |
697 |
|
|
warnx("symbol %s not found", symbols[i].n_name); |
698 |
|
|
#endif |
699 |
|
|
break; |
700 |
|
|
} |
701 |
|
|
|
702 |
|
|
if ((display & (MSGINFO | MSGTOTAL)) && |
703 |
|
|
(kvm_read(kd, symbols[X_MSGINFO].n_value, |
704 |
|
|
&msginfo, sizeof(msginfo)) == sizeof(msginfo))) { |
705 |
|
|
|
706 |
|
|
if (display & MSGTOTAL) |
707 |
|
|
show_msgtotal(&msginfo); |
708 |
|
|
|
709 |
|
|
if (display & MSGINFO) { |
710 |
|
|
if (kvm_read(kd, symbols[X_MSG_QUEUES].n_value, |
711 |
|
|
&addr, sizeof(addr)) != sizeof(addr)) |
712 |
|
|
errx(1, "kvm_read (%s): %s", |
713 |
|
|
symbols[X_MSG_QUEUES].n_name, |
714 |
|
|
kvm_geterr(kd)); |
715 |
|
|
|
716 |
|
|
msqids = calloc(sizeof(struct msqid_ds), |
717 |
|
|
msginfo.msgmni); |
718 |
|
|
if (msqids == NULL) |
719 |
|
|
err(1, "calloc"); |
720 |
|
|
|
721 |
|
|
/* walk the TAILQ */ |
722 |
|
|
while (addr != 0) { |
723 |
|
|
if (kvm_read(kd, addr, &msgque, sizeof(msgque)) |
724 |
|
|
!= sizeof(msgque)) |
725 |
|
|
errx(1, "kvm_read (%s): %s", |
726 |
|
|
"msg que", kvm_geterr(kd)); |
727 |
|
|
msqids[msgque.que_ix] = msgque.msqid_ds; |
728 |
|
|
addr = (u_long)TAILQ_NEXT(&msgque, que_next); |
729 |
|
|
} |
730 |
|
|
|
731 |
|
|
show_msginfo_hdr(); |
732 |
|
|
for (i = 0; i < msginfo.msgmni; i++) { |
733 |
|
|
struct msqid_ds *msqptr = &msqids[i]; |
734 |
|
|
if (msqptr->msg_qbytes != 0) |
735 |
|
|
show_msginfo(msqptr->msg_stime, |
736 |
|
|
msqptr->msg_rtime, |
737 |
|
|
msqptr->msg_ctime, |
738 |
|
|
IXSEQ_TO_IPCID(i, msqptr->msg_perm), |
739 |
|
|
msqptr->msg_perm.key, |
740 |
|
|
msqptr->msg_perm.mode, |
741 |
|
|
msqptr->msg_perm.uid, |
742 |
|
|
msqptr->msg_perm.gid, |
743 |
|
|
msqptr->msg_perm.cuid, |
744 |
|
|
msqptr->msg_perm.cgid, |
745 |
|
|
msqptr->msg_cbytes, |
746 |
|
|
msqptr->msg_qnum, |
747 |
|
|
msqptr->msg_qbytes, |
748 |
|
|
msqptr->msg_lspid, |
749 |
|
|
msqptr->msg_lrpid); |
750 |
|
|
} |
751 |
|
|
printf("\n"); |
752 |
|
|
} |
753 |
|
|
} else { |
754 |
|
|
if (display & (MSGINFO | MSGTOTAL)) { |
755 |
|
|
warnx("SVID messages facility not configured in " |
756 |
|
|
"the system"); |
757 |
|
|
} |
758 |
|
|
} |
759 |
|
|
if ((display & (SHMINFO | SHMTOTAL)) && |
760 |
|
|
(kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo, |
761 |
|
|
sizeof(shminfo)) == sizeof(shminfo))) { |
762 |
|
|
|
763 |
|
|
if (display & SHMTOTAL) |
764 |
|
|
show_shmtotal(&shminfo); |
765 |
|
|
|
766 |
|
|
if (display & SHMINFO) { |
767 |
|
|
if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &addr, |
768 |
|
|
sizeof(addr)) != sizeof(addr)) |
769 |
|
|
errx(1, "kvm_read (%s): %s", |
770 |
|
|
symbols[X_SHMSEGS].n_name, kvm_geterr(kd)); |
771 |
|
|
|
772 |
|
|
shmsegs = calloc(sizeof(struct shmid_ds *), |
773 |
|
|
shminfo.shmmni); |
774 |
|
|
if (shmsegs == NULL) |
775 |
|
|
err(1, "calloc"); |
776 |
|
|
|
777 |
|
|
if (kvm_read(kd, addr, shmsegs, |
778 |
|
|
sizeof(struct shmid_ds *) * shminfo.shmmni) != |
779 |
|
|
sizeof(struct shmid_ds *) * shminfo.shmmni) |
780 |
|
|
errx(1, "kvm_read (shmsegs): %s", |
781 |
|
|
kvm_geterr(kd)); |
782 |
|
|
|
783 |
|
|
show_shminfo_hdr(); |
784 |
|
|
for (i = 0; i < shminfo.shmmni; i++) { |
785 |
|
|
if (shmsegs[i] == NULL) |
786 |
|
|
continue; |
787 |
|
|
|
788 |
|
|
if (kvm_read(kd, (u_long)shmsegs[i], &shmseg, |
789 |
|
|
sizeof(shmseg)) != sizeof(shmseg)) |
790 |
|
|
errx(1, "kvm_read (shmseg): %s", |
791 |
|
|
kvm_geterr(kd)); |
792 |
|
|
show_shminfo(shmseg.shm_atime, |
793 |
|
|
shmseg.shm_dtime, |
794 |
|
|
shmseg.shm_ctime, |
795 |
|
|
IXSEQ_TO_IPCID(i, shmseg.shm_perm), |
796 |
|
|
shmseg.shm_perm.key, |
797 |
|
|
shmseg.shm_perm.mode, |
798 |
|
|
shmseg.shm_perm.uid, |
799 |
|
|
shmseg.shm_perm.gid, |
800 |
|
|
shmseg.shm_perm.cuid, |
801 |
|
|
shmseg.shm_perm.cgid, |
802 |
|
|
shmseg.shm_nattch, |
803 |
|
|
shmseg.shm_segsz, |
804 |
|
|
shmseg.shm_cpid, |
805 |
|
|
shmseg.shm_lpid); |
806 |
|
|
} |
807 |
|
|
printf("\n"); |
808 |
|
|
} |
809 |
|
|
} else |
810 |
|
|
if (display & (SHMINFO | SHMTOTAL)) { |
811 |
|
|
warnx("SVID shared memory facility not configured in " |
812 |
|
|
"the system"); |
813 |
|
|
} |
814 |
|
|
if ((display & (SEMINFO | SEMTOTAL)) && |
815 |
|
|
(kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, |
816 |
|
|
sizeof(seminfo)) == sizeof(seminfo))) { |
817 |
|
|
if (display & SEMTOTAL) |
818 |
|
|
show_semtotal(&seminfo); |
819 |
|
|
|
820 |
|
|
if (display & SEMINFO) { |
821 |
|
|
if (kvm_read(kd, symbols[X_SEMA].n_value, &addr, |
822 |
|
|
sizeof(addr)) != sizeof(addr)) |
823 |
|
|
errx(1, "kvm_read (%s): %s", |
824 |
|
|
symbols[X_SEMA].n_name, kvm_geterr(kd)); |
825 |
|
|
|
826 |
|
|
sema = calloc(sizeof(struct semid_ds *), |
827 |
|
|
seminfo.semmni); |
828 |
|
|
if (sema == NULL) |
829 |
|
|
err(1, "calloc"); |
830 |
|
|
|
831 |
|
|
if (kvm_read(kd, addr, sema, |
832 |
|
|
sizeof(struct semid_ds *) * seminfo.semmni) != |
833 |
|
|
sizeof(struct semid_ds *) * seminfo.semmni) |
834 |
|
|
errx(1, "kvm_read (sema): %s", |
835 |
|
|
kvm_geterr(kd)); |
836 |
|
|
|
837 |
|
|
show_seminfo_hdr(); |
838 |
|
|
for (i = 0; i < seminfo.semmni; i++) { |
839 |
|
|
if (sema[i] == NULL) |
840 |
|
|
continue; |
841 |
|
|
|
842 |
|
|
if (kvm_read(kd, (u_long)sema[i], &sem, |
843 |
|
|
sizeof(sem)) != sizeof(sem)) |
844 |
|
|
errx(1, "kvm_read (sem): %s", |
845 |
|
|
kvm_geterr(kd)); |
846 |
|
|
show_seminfo(sem.sem_otime, |
847 |
|
|
sem.sem_ctime, |
848 |
|
|
IXSEQ_TO_IPCID(i, sem.sem_perm), |
849 |
|
|
sem.sem_perm.key, |
850 |
|
|
sem.sem_perm.mode, |
851 |
|
|
sem.sem_perm.uid, |
852 |
|
|
sem.sem_perm.gid, |
853 |
|
|
sem.sem_perm.cuid, |
854 |
|
|
sem.sem_perm.cgid, |
855 |
|
|
sem.sem_nsems); |
856 |
|
|
} |
857 |
|
|
printf("\n"); |
858 |
|
|
} |
859 |
|
|
} else |
860 |
|
|
if (display & (SEMINFO | SEMTOTAL)) { |
861 |
|
|
warnx("SVID semaphores facility not configured in " |
862 |
|
|
"the system"); |
863 |
|
|
} |
864 |
|
|
kvm_close(kd); |
865 |
|
|
} |
866 |
|
|
|
867 |
|
|
void |
868 |
|
|
usage(void) |
869 |
|
|
{ |
870 |
|
|
extern char *__progname; |
871 |
|
|
|
872 |
|
|
fprintf(stderr, |
873 |
|
|
"usage: %s [-abcMmopQqSsTt] [-C core] [-N system]\n", |
874 |
|
|
__progname); |
875 |
|
|
exit(1); |
876 |
|
|
} |