1 /* $NetBSD: ipcs.c,v 1.27 2002/05/21 01:10:06 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)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 shared memory 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