1 /* $NetBSD: ipcs.c,v 1.43 2014/06/11 14:57:55 joerg 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 46 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 47 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 48 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 49 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 50 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 51 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 52 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 53 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 54 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 #include <sys/cdefs.h> 58 #include <sys/param.h> 59 #include <sys/sysctl.h> 60 #include <sys/inttypes.h> 61 #include <sys/ipc.h> 62 #include <sys/sem.h> 63 #include <sys/shm.h> 64 #include <sys/msg.h> 65 66 #include <err.h> 67 #include <fcntl.h> 68 #include <grp.h> 69 #include <limits.h> 70 #include <paths.h> 71 #include <pwd.h> 72 #include <stdio.h> 73 #include <stdlib.h> 74 #include <string.h> 75 #include <time.h> 76 #include <unistd.h> 77 78 #define SHMINFO 1 79 #define SHMTOTAL 2 80 #define MSGINFO 4 81 #define MSGTOTAL 8 82 #define SEMINFO 16 83 #define SEMTOTAL 32 84 85 #define BIGGEST 1 86 #define CREATOR 2 87 #define OUTSTANDING 4 88 #define PID 8 89 #define TIME 16 90 91 static int display = 0; 92 static int option = 0; 93 94 static void cvt_time(time_t, char *, size_t); 95 static char *fmt_perm(u_short); 96 static void msg_sysctl(void); 97 static void sem_sysctl(void); 98 static void shm_sysctl(void); 99 static void show_msginfo(time_t, time_t, time_t, int, u_int64_t, mode_t, 100 uid_t, gid_t, uid_t, gid_t, u_int64_t, u_int64_t, u_int64_t, pid_t, pid_t); 101 static void show_msginfo_hdr(void); 102 static void show_msgtotal(struct msginfo *); 103 static void show_seminfo_hdr(void); 104 static void show_seminfo(time_t, time_t, int, u_int64_t, mode_t, uid_t, 105 gid_t, uid_t, gid_t, int16_t); 106 static void show_semtotal(struct seminfo *); 107 static void show_shminfo(time_t, time_t, time_t, int, u_int64_t, mode_t, 108 uid_t, gid_t, uid_t, gid_t, u_int32_t, u_int64_t, pid_t, pid_t); 109 static void show_shminfo_hdr(void); 110 static void show_shmtotal(struct shminfo *); 111 static void usage(void) __dead; 112 static void unconfsem(void); 113 static void unconfmsg(void); 114 static void unconfshm(void); 115 116 static void 117 unconfsem(void) 118 { 119 warnx("SVID semaphores facility not configured in the system"); 120 } 121 122 static void 123 unconfmsg(void) 124 { 125 warnx("SVID messages facility not configured in the system"); 126 } 127 128 static void 129 unconfshm(void) 130 { 131 warnx("SVID shared memory facility not configured in the system"); 132 } 133 134 static char * 135 fmt_perm(u_short mode) 136 { 137 static char buffer[12]; 138 139 buffer[0] = '-'; 140 buffer[1] = '-'; 141 buffer[2] = ((mode & 0400) ? 'r' : '-'); 142 buffer[3] = ((mode & 0200) ? 'w' : '-'); 143 buffer[4] = ((mode & 0100) ? 'a' : '-'); 144 buffer[5] = ((mode & 0040) ? 'r' : '-'); 145 buffer[6] = ((mode & 0020) ? 'w' : '-'); 146 buffer[7] = ((mode & 0010) ? 'a' : '-'); 147 buffer[8] = ((mode & 0004) ? 'r' : '-'); 148 buffer[9] = ((mode & 0002) ? 'w' : '-'); 149 buffer[10] = ((mode & 0001) ? 'a' : '-'); 150 buffer[11] = '\0'; 151 return (&buffer[0]); 152 } 153 154 static void 155 cvt_time(time_t t, char *buf, size_t buflen) 156 { 157 struct tm *tm; 158 159 if (t == 0) 160 (void)strlcpy(buf, "no-entry", buflen); 161 else { 162 tm = localtime(&t); 163 (void)snprintf(buf, buflen, "%2d:%02d:%02d", 164 tm->tm_hour, tm->tm_min, tm->tm_sec); 165 } 166 } 167 int 168 main(int argc, char *argv[]) 169 { 170 int i; 171 time_t now; 172 173 while ((i = getopt(argc, argv, "MmQqSsabcoptT")) != -1) 174 switch (i) { 175 case 'M': 176 display |= SHMTOTAL; 177 break; 178 case 'm': 179 display |= SHMINFO; 180 break; 181 case 'Q': 182 display |= MSGTOTAL; 183 break; 184 case 'q': 185 display |= MSGINFO; 186 break; 187 case 'S': 188 display |= SEMTOTAL; 189 break; 190 case 's': 191 display |= SEMINFO; 192 break; 193 case 'T': 194 display |= SHMTOTAL | MSGTOTAL | SEMTOTAL; 195 break; 196 case 'a': 197 option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; 198 break; 199 case 'b': 200 option |= BIGGEST; 201 break; 202 case 'c': 203 option |= CREATOR; 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 (void)time(&now); 222 (void)printf("IPC status from <running system> as of %s\n", 223 /* and extra \n from ctime(3) */ 224 ctime(&now)); 225 226 if (display == 0) 227 display = SHMINFO | MSGINFO | SEMINFO; 228 229 if (display & (MSGINFO | MSGTOTAL)) 230 msg_sysctl(); 231 if (display & (SHMINFO | SHMTOTAL)) 232 shm_sysctl(); 233 if (display & (SEMINFO | SEMTOTAL)) 234 sem_sysctl(); 235 return 0; 236 } 237 238 static void 239 show_msgtotal(struct msginfo *msginfo) 240 { 241 (void)printf("msginfo:\n"); 242 (void)printf("\tmsgmax: %6d\t(max characters in a message)\n", 243 msginfo->msgmax); 244 (void)printf("\tmsgmni: %6d\t(# of message queues)\n", 245 msginfo->msgmni); 246 (void)printf("\tmsgmnb: %6d\t(max characters in a message queue)\n", 247 msginfo->msgmnb); 248 (void)printf("\tmsgtql: %6d\t(max # of messages in system)\n", 249 msginfo->msgtql); 250 (void)printf("\tmsgssz: %6d\t(size of a message segment)\n", 251 msginfo->msgssz); 252 (void)printf("\tmsgseg: %6d\t(# of message segments in system)\n\n", 253 msginfo->msgseg); 254 } 255 256 static void 257 show_shmtotal(struct shminfo *shminfo) 258 { 259 (void)printf("shminfo:\n"); 260 (void)printf("\tshmmax: %" PRIu64 "\t(max shared memory segment size)\n", 261 shminfo->shmmax); 262 (void)printf("\tshmmin: %7d\t(min shared memory segment size)\n", 263 shminfo->shmmin); 264 (void)printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n", 265 shminfo->shmmni); 266 (void)printf("\tshmseg: %7d\t(max shared memory segments per process)\n", 267 shminfo->shmseg); 268 (void)printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n", 269 shminfo->shmall); 270 } 271 272 static void 273 show_semtotal(struct seminfo *seminfo) 274 { 275 (void)printf("seminfo:\n"); 276 (void)printf("\tsemmap: %6d\t(# of entries in semaphore map)\n", 277 seminfo->semmap); 278 (void)printf("\tsemmni: %6d\t(# of semaphore identifiers)\n", 279 seminfo->semmni); 280 (void)printf("\tsemmns: %6d\t(# of semaphores in system)\n", 281 seminfo->semmns); 282 (void)printf("\tsemmnu: %6d\t(# of undo structures in system)\n", 283 seminfo->semmnu); 284 (void)printf("\tsemmsl: %6d\t(max # of semaphores per id)\n", 285 seminfo->semmsl); 286 (void)printf("\tsemopm: %6d\t(max # of operations per semop call)\n", 287 seminfo->semopm); 288 (void)printf("\tsemume: %6d\t(max # of undo entries per process)\n", 289 seminfo->semume); 290 (void)printf("\tsemusz: %6d\t(size in bytes of undo structure)\n", 291 seminfo->semusz); 292 (void)printf("\tsemvmx: %6d\t(semaphore maximum value)\n", 293 seminfo->semvmx); 294 (void)printf("\tsemaem: %6d\t(adjust on exit max value)\n\n", 295 seminfo->semaem); 296 } 297 298 static void 299 show_msginfo_hdr(void) 300 { 301 (void)printf("Message Queues:\n"); 302 (void)printf("T ID KEY MODE OWNER GROUP"); 303 if (option & CREATOR) 304 (void)printf(" CREATOR CGROUP"); 305 if (option & OUTSTANDING) 306 (void)printf(" CBYTES QNUM"); 307 if (option & BIGGEST) 308 (void)printf(" QBYTES"); 309 if (option & PID) 310 (void)printf(" LSPID LRPID"); 311 if (option & TIME) 312 (void)printf(" STIME RTIME CTIME"); 313 (void)printf("\n"); 314 } 315 316 static void 317 show_msginfo(time_t s_time, time_t r_time, time_t c_time, int ipcid, 318 u_int64_t key, 319 mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, 320 u_int64_t cbytes, u_int64_t qnum, u_int64_t qbytes, pid_t lspid, 321 pid_t lrpid) 322 { 323 char s_time_buf[100], r_time_buf[100], c_time_buf[100]; 324 325 if (option & TIME) { 326 cvt_time(s_time, s_time_buf, sizeof(s_time_buf)); 327 cvt_time(r_time, r_time_buf, sizeof(r_time_buf)); 328 cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); 329 } 330 331 (void)printf("q %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), 332 user_from_uid(uid, 0), group_from_gid(gid, 0)); 333 334 if (option & CREATOR) 335 (void)printf(" %8s %8s", user_from_uid(cuid, 0), 336 group_from_gid(cgid, 0)); 337 338 if (option & OUTSTANDING) 339 (void)printf(" %6lld %5lld", (long long)cbytes, (long long)qnum); 340 341 if (option & BIGGEST) 342 (void)printf(" %6lld", (long long)qbytes); 343 344 if (option & PID) 345 (void)printf(" %5d %5d", lspid, lrpid); 346 347 if (option & TIME) 348 (void)printf(" %s %s %s", s_time_buf, r_time_buf, c_time_buf); 349 350 (void)printf("\n"); 351 } 352 353 static void 354 show_shminfo_hdr(void) 355 { 356 (void)printf("Shared Memory:\n"); 357 (void)printf("T ID KEY MODE OWNER GROUP"); 358 if (option & CREATOR) 359 (void)printf(" CREATOR CGROUP"); 360 if (option & OUTSTANDING) 361 (void)printf(" NATTCH"); 362 if (option & BIGGEST) 363 (void)printf(" SEGSZ"); 364 if (option & PID) 365 (void)printf(" CPID LPID"); 366 if (option & TIME) 367 (void)printf(" ATIME DTIME CTIME"); 368 (void)printf("\n"); 369 } 370 371 static void 372 show_shminfo(time_t atime, time_t dtime, time_t c_time, int ipcid, u_int64_t key, 373 mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, 374 u_int32_t nattch, u_int64_t segsz, pid_t cpid, pid_t lpid) 375 { 376 char atime_buf[100], dtime_buf[100], c_time_buf[100]; 377 378 if (option & TIME) { 379 cvt_time(atime, atime_buf, sizeof(atime_buf)); 380 cvt_time(dtime, dtime_buf, sizeof(dtime_buf)); 381 cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); 382 } 383 384 (void)printf("m %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), 385 user_from_uid(uid, 0), group_from_gid(gid, 0)); 386 387 if (option & CREATOR) 388 (void)printf(" %8s %8s", user_from_uid(cuid, 0), 389 group_from_gid(cgid, 0)); 390 391 if (option & OUTSTANDING) 392 (void)printf(" %6d", nattch); 393 394 if (option & BIGGEST) 395 (void)printf(" %7llu", (long long)segsz); 396 397 if (option & PID) 398 (void)printf(" %5d %5d", cpid, lpid); 399 400 if (option & TIME) 401 (void)printf(" %s %s %s", 402 atime_buf, 403 dtime_buf, 404 c_time_buf); 405 406 (void)printf("\n"); 407 } 408 409 static void 410 show_seminfo_hdr(void) 411 { 412 (void)printf("Semaphores:\n"); 413 (void)printf("T ID KEY MODE OWNER GROUP"); 414 if (option & CREATOR) 415 (void)printf(" CREATOR CGROUP"); 416 if (option & BIGGEST) 417 (void)printf(" NSEMS"); 418 if (option & TIME) 419 (void)printf(" OTIME CTIME"); 420 (void)printf("\n"); 421 } 422 423 static void 424 show_seminfo(time_t otime, time_t c_time, int ipcid, u_int64_t key, mode_t mode, 425 uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, int16_t nsems) 426 { 427 char c_time_buf[100], otime_buf[100]; 428 429 if (option & TIME) { 430 cvt_time(otime, otime_buf, sizeof(otime_buf)); 431 cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); 432 } 433 434 (void)printf("s %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), 435 user_from_uid(uid, 0), group_from_gid(gid, 0)); 436 437 if (option & CREATOR) 438 (void)printf(" %8s %8s", user_from_uid(cuid, 0), 439 group_from_gid(cgid, 0)); 440 441 if (option & BIGGEST) 442 (void)printf(" %5d", nsems); 443 444 if (option & TIME) 445 (void)printf(" %s %s", otime_buf, c_time_buf); 446 447 (void)printf("\n"); 448 } 449 450 static void 451 msg_sysctl(void) 452 { 453 struct msg_sysctl_info *msgsi; 454 void *buf; 455 int mib[4]; 456 size_t len; 457 int i, valid; 458 459 mib[0] = CTL_KERN; 460 mib[1] = KERN_SYSVIPC; 461 mib[2] = KERN_SYSVIPC_MSG; 462 len = sizeof(valid); 463 if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { 464 warn("sysctl(KERN_SYSVIPC_MSG)"); 465 return; 466 } 467 if (!valid) { 468 unconfmsg(); 469 return; 470 } 471 472 mib[0] = CTL_KERN; 473 mib[1] = KERN_SYSVIPC; 474 mib[2] = KERN_SYSVIPC_INFO; 475 mib[3] = KERN_SYSVIPC_MSG_INFO; 476 477 if (!(display & MSGINFO)) { 478 /* totals only */ 479 len = sizeof(struct msginfo); 480 } else { 481 if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { 482 warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); 483 return; 484 } 485 } 486 487 if ((buf = malloc(len)) == NULL) 488 err(1, "malloc"); 489 msgsi = (struct msg_sysctl_info *)buf; 490 if (sysctl(mib, 4, msgsi, &len, NULL, 0) < 0) { 491 warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); 492 goto done; 493 } 494 495 if (display & MSGTOTAL) 496 show_msgtotal(&msgsi->msginfo); 497 498 if (display & MSGINFO) { 499 show_msginfo_hdr(); 500 for (i = 0; i < msgsi->msginfo.msgmni; i++) { 501 struct msgid_ds_sysctl *msqptr = &msgsi->msgids[i]; 502 if (msqptr->msg_qbytes != 0) 503 show_msginfo(msqptr->msg_stime, 504 msqptr->msg_rtime, 505 msqptr->msg_ctime, 506 IXSEQ_TO_IPCID(i, msqptr->msg_perm), 507 msqptr->msg_perm._key, 508 msqptr->msg_perm.mode, 509 msqptr->msg_perm.uid, 510 msqptr->msg_perm.gid, 511 msqptr->msg_perm.cuid, 512 msqptr->msg_perm.cgid, 513 msqptr->_msg_cbytes, 514 msqptr->msg_qnum, 515 msqptr->msg_qbytes, 516 msqptr->msg_lspid, 517 msqptr->msg_lrpid); 518 } 519 (void)printf("\n"); 520 } 521 done: 522 free(buf); 523 } 524 525 static void 526 shm_sysctl(void) 527 { 528 struct shm_sysctl_info *shmsi; 529 void *buf; 530 int mib[4]; 531 size_t len; 532 uint32_t i; 533 long valid; 534 535 mib[0] = CTL_KERN; 536 mib[1] = KERN_SYSVIPC; 537 mib[2] = KERN_SYSVIPC_SHM; 538 len = sizeof(valid); 539 if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { 540 warn("sysctl(KERN_SYSVIPC_SHM)"); 541 return; 542 } 543 if (!valid) { 544 unconfshm(); 545 return; 546 } 547 548 mib[0] = CTL_KERN; 549 mib[1] = KERN_SYSVIPC; 550 mib[2] = KERN_SYSVIPC_INFO; 551 mib[3] = KERN_SYSVIPC_SHM_INFO; 552 553 if (!(display & SHMINFO)) { 554 /* totals only */ 555 len = sizeof(struct shminfo); 556 } else { 557 if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { 558 warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); 559 return; 560 } 561 } 562 563 if ((buf = malloc(len)) == NULL) 564 err(1, "malloc"); 565 shmsi = (struct shm_sysctl_info *)buf; 566 if (sysctl(mib, 4, shmsi, &len, NULL, 0) < 0) { 567 warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); 568 goto done; 569 } 570 571 if (display & SHMTOTAL) 572 show_shmtotal(&shmsi->shminfo); 573 574 if (display & SHMINFO) { 575 show_shminfo_hdr(); 576 for (i = 0; i < shmsi->shminfo.shmmni; i++) { 577 struct shmid_ds_sysctl *shmptr = &shmsi->shmids[i]; 578 if (shmptr->shm_perm.mode & 0x0800) 579 show_shminfo(shmptr->shm_atime, 580 shmptr->shm_dtime, 581 shmptr->shm_ctime, 582 IXSEQ_TO_IPCID(i, shmptr->shm_perm), 583 shmptr->shm_perm._key, 584 shmptr->shm_perm.mode, 585 shmptr->shm_perm.uid, 586 shmptr->shm_perm.gid, 587 shmptr->shm_perm.cuid, 588 shmptr->shm_perm.cgid, 589 shmptr->shm_nattch, 590 shmptr->shm_segsz, 591 shmptr->shm_cpid, 592 shmptr->shm_lpid); 593 } 594 (void)printf("\n"); 595 } 596 done: 597 free(buf); 598 } 599 600 static void 601 sem_sysctl(void) 602 { 603 struct sem_sysctl_info *semsi; 604 void *buf; 605 int mib[4]; 606 size_t len; 607 int i, valid; 608 609 mib[0] = CTL_KERN; 610 mib[1] = KERN_SYSVIPC; 611 mib[2] = KERN_SYSVIPC_SEM; 612 len = sizeof(valid); 613 if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { 614 warn("sysctl(KERN_SYSVIPC_SEM)"); 615 return; 616 } 617 if (!valid) { 618 unconfsem(); 619 return; 620 } 621 622 mib[0] = CTL_KERN; 623 mib[1] = KERN_SYSVIPC; 624 mib[2] = KERN_SYSVIPC_INFO; 625 mib[3] = KERN_SYSVIPC_SEM_INFO; 626 627 if (!(display & SEMINFO)) { 628 /* totals only */ 629 len = sizeof(struct seminfo); 630 } else { 631 if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { 632 warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); 633 return; 634 } 635 } 636 637 if ((buf = malloc(len)) == NULL) 638 err(1, "malloc"); 639 semsi = (struct sem_sysctl_info *)buf; 640 if (sysctl(mib, 4, semsi, &len, NULL, 0) < 0) { 641 warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); 642 goto done; 643 } 644 645 if (display & SEMTOTAL) 646 show_semtotal(&semsi->seminfo); 647 648 if (display & SEMINFO) { 649 show_seminfo_hdr(); 650 for (i = 0; i < semsi->seminfo.semmni; i++) { 651 struct semid_ds_sysctl *semaptr = &semsi->semids[i]; 652 if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) 653 show_seminfo(semaptr->sem_otime, 654 semaptr->sem_ctime, 655 IXSEQ_TO_IPCID(i, semaptr->sem_perm), 656 semaptr->sem_perm._key, 657 semaptr->sem_perm.mode, 658 semaptr->sem_perm.uid, 659 semaptr->sem_perm.gid, 660 semaptr->sem_perm.cuid, 661 semaptr->sem_perm.cgid, 662 semaptr->sem_nsems); 663 } 664 (void)printf("\n"); 665 } 666 done: 667 free(buf); 668 } 669 670 static void 671 usage(void) 672 { 673 674 (void)fprintf(stderr, 675 "Usage: %s [-abcmopqstMQST]\n", 676 getprogname()); 677 exit(1); 678 } 679