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