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