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