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