From: David van Moolenbroek Date: Thu, 17 Dec 2015 13:07:17 +0000 (+0000) Subject: Import NetBSD ipcs(1) X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/man.dnssec-coverage.html?a=commitdiff_plain;h=7b09d0426a4cc7fc50177a445527ffe3ebc4cb89;p=minix.git Import NetBSD ipcs(1) The old ipcs(1) utility had a dubious license at best. Change-Id: Ic4c0a24f04c94cc77a43658f6c939d138461bd6a --- diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 527dcb8fd..3e5286270 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -147,6 +147,7 @@ ./usr/man/man1/infokey.1 minix-man ./usr/man/man1/install-info.1 minix-man ./usr/man/man1/install.1 minix-man +./usr/man/man1/ipcs.1 minix-man ./usr/man/man1/isodir.1 minix-man ./usr/man/man1/isoinfo.1 minix-man ./usr/man/man1/isoread.1 minix-man diff --git a/minix/commands/Makefile b/minix/commands/Makefile index b0c37e757..0296baa41 100644 --- a/minix/commands/Makefile +++ b/minix/commands/Makefile @@ -12,7 +12,7 @@ SUBDIR= add_route arp at backup \ fix format fsck.mfs \ gcov-pull host \ hostaddr ifconfig ifdef \ - intr ipcrm ipcs irdpd isoread \ + intr ipcrm irdpd isoread \ loadkeys loadramdisk logger look lp \ lpd lspci mail MAKEDEV \ mount mt netconf \ diff --git a/minix/commands/ipcs/Makefile b/minix/commands/ipcs/Makefile deleted file mode 100644 index d521fca15..000000000 --- a/minix/commands/ipcs/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= ipcs -MAN= - -.include diff --git a/minix/commands/ipcs/ipcs.c b/minix/commands/ipcs/ipcs.c deleted file mode 100644 index 94ea9ae15..000000000 --- a/minix/commands/ipcs/ipcs.c +++ /dev/null @@ -1,683 +0,0 @@ -/* Original author unknown, may be "krishna balasub@cis.ohio-state.edu" */ -/* - - Modified Sat Oct 9 10:55:28 1993 for 0.99.13 - - Patches from Mike Jagdis (jaggy@purplet.demon.co.uk) applied Wed Feb - 8 12:12:21 1995 by faith@cs.unc.edu to print numeric uids if no - passwd file entry. - - Patch from arnolds@ifns.de (Heinz-Ado Arnolds) applied Mon Jul 1 - 19:30:41 1996 by janl@math.uio.no to add code missing in case PID: - clauses. - - Patched to display the key field -- hy@picksys.com 12/18/96 - - 1999-02-22 Arkadiusz Mi秌iewicz - - added Native Language Support - -*/ - -#define __USE_MISC - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* remove _() stuff */ -#define _(a) a - -/*-------------------------------------------------------------------*/ -/* SHM_DEST and SHM_LOCKED are defined in kernel headers, - but inside #ifdef __KERNEL__ ... #endif */ -#ifndef SHM_DEST -/* shm_mode upper byte flags */ -#define SHM_DEST 01000 /* segment will be destroyed on last detach */ -#define SHM_LOCKED 02000 /* segment will not be swapped */ -#endif - -/* For older kernels the same holds for the defines below */ -#ifndef MSG_STAT -#define MSG_STAT 11 -#define MSG_INFO 12 -#endif - -#ifndef SHM_STAT -#define SHM_STAT 13 -#define SHM_INFO 14 -struct shm_info { - int used_ids; - ulong shm_tot; /* total allocated shm */ - ulong shm_rss; /* total resident shm */ - ulong shm_swp; /* total swapped shm */ - ulong swap_attempts; - ulong swap_successes; -}; -#endif - -#ifndef SEM_STAT -#define SEM_STAT 18 -#define SEM_INFO 19 -#endif - -/* Some versions of libc only define IPC_INFO when __USE_GNU is defined. */ -#ifndef IPC_INFO -#define IPC_INFO 3 -#endif -/*-------------------------------------------------------------------*/ - -/* The last arg of semctl is a union semun, but where is it defined? - X/OPEN tells us to define it ourselves, but until recently - Linux include files would also define it. */ -#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) -/* union semun is defined by including */ -#else -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; - struct semid_ds *buf; - unsigned short int *array; - struct seminfo *__buf; -}; -#endif - -/* X/OPEN (Jan 1987) does not define fields key, seq in struct ipc_perm; - libc 4/5 does not mention struct ipc_term at all, but includes - , which defines a struct ipc_perm with such fields. - glibc-1.09 has no support for sysv ipc. - glibc 2 uses __key, __seq */ -#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1 -#define KEY __key -#else -#define KEY _key -#endif - -#define LIMITS 1 -#define STATUS 2 -#define CREATOR 3 -#define TIME 4 -#define PID 5 - -void do_shm (char format); -void do_sem (char format); -void do_msg (char format); -void print_shm (int id); -void print_msg (int id); -void print_sem (int id); - -static char *progname; - -static void -usage(int rc) { - printf (_("usage : %s -asmq -tclup \n"), progname); - printf (_("\t%s [-s -m -q] -i id\n"), progname); - printf (_("\t%s -h for help.\n"), progname); - exit(rc); -} - -static void -help (int rc) { - printf (_("%s provides information on ipc facilities for" - " which you have read access.\n"), progname); - printf (_("Resource Specification:\n\t-m : shared_mem\n\t-q : messages\n")); - printf (_("\t-s : semaphores\n\t-a : all (default)\n")); - printf (_("Output Format:\n\t-t : time\n\t-p : pid\n\t-c : creator\n")); - printf (_("\t-l : limits\n\t-u : summary\n")); - printf (_("-i id [-s -q -m] : details on resource identified by id\n")); - usage(rc); -} - -int -main (int argc, char **argv) { - int opt, msg = 0, sem = 0, shm = 0, id=0, print=0; - char format = 0; - char options[] = "atcluphsmqi:"; - - progname = argv[0]; - while ((opt = getopt (argc, argv, options)) != -1) { - switch (opt) { - case 'i': - id = atoi (optarg); - print = 1; - break; - case 'a': - msg = shm = sem = 1; - break; - case 'q': - msg = 1; - break; - case 's': - sem = 1; - break; - case 'm': - shm = 1; - break; - case 't': - format = TIME; - break; - case 'c': - format = CREATOR; - break; - case 'p': - format = PID; - break; - case 'l': - format = LIMITS; - break; - case 'u': - format = STATUS; - break; - case 'h': - help(EXIT_SUCCESS); - case '?': - usage(EXIT_SUCCESS); - } - } - - if (print) { - if (shm) - print_shm (id); - else if (sem) - print_sem (id); - else if (msg) - print_msg (id); - else - usage (EXIT_FAILURE); - } else { - if ( !shm && !msg && !sem) - msg = sem = shm = 1; - printf ("\n"); - - if (shm) { - do_shm (format); - printf ("\n"); - } - if (sem) { - do_sem (format); - printf ("\n"); - } - if (msg) { - do_msg (format); - printf ("\n"); - } - } - return EXIT_SUCCESS; -} - - -static void -print_perms (int id, struct ipc_perm *ipcp) { - struct passwd *pw; - struct group *gr; - - printf ("%-10d %-10o", id, ipcp->mode & 0777); - - if ((pw = getpwuid(ipcp->cuid))) - printf(" %-10s", pw->pw_name); - else - printf(" %-10d", ipcp->cuid); - if ((gr = getgrgid(ipcp->cgid))) - printf(" %-10s", gr->gr_name); - else - printf(" %-10d", ipcp->cgid); - - if ((pw = getpwuid(ipcp->uid))) - printf(" %-10s", pw->pw_name); - else - printf(" %-10d", ipcp->uid); - if ((gr = getgrgid(ipcp->gid))) - printf(" %-10s\n", gr->gr_name); - else - printf(" %-10d\n", ipcp->gid); -} - - -void do_shm (char format) -{ - int maxid, shmid, id; - struct shmid_ds shmseg; - struct shm_info shm_info; - struct shminfo shminfo; - struct ipc_perm *ipcp = &shmseg.shm_perm; - struct passwd *pw; - - maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info); - if (maxid < 0 && errno == ENOSYS) { - printf (_("kernel not configured for shared memory\n")); - return; - } - - switch (format) { - case LIMITS: - printf (_("------ Shared Memory Limits --------\n")); - if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 ) - return; - /* glibc 2.1.3 and all earlier libc's have ints as fields - of struct shminfo; glibc 2.1.91 has unsigned long; ach */ - printf (_("max number of segments = %lu\n"), - (unsigned long) shminfo.shmmni); - printf (_("max seg size (kbytes) = %lu\n"), - (unsigned long) (shminfo.shmmax >> 10)); - printf (_("max total shared memory (kbytes) = %lu\n"), - getpagesize() / 1024 * (unsigned long) shminfo.shmall); - printf (_("min seg size (bytes) = %lu\n"), - (unsigned long) shminfo.shmmin); - return; - - case STATUS: - printf (_("------ Shared Memory Status --------\n")); - printf (_("segments allocated %d\n"), shm_info.used_ids); - printf (_("pages allocated %ld\n"), shm_info.shm_tot); - printf (_("pages resident %ld\n"), shm_info.shm_rss); - printf (_("pages swapped %ld\n"), shm_info.shm_swp); - printf (_("Swap performance: %ld attempts\t %ld successes\n"), - shm_info.swap_attempts, shm_info.swap_successes); - return; - - case CREATOR: - printf (_("------ Shared Memory Segment Creators/Owners --------\n")); - printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n", - _("shmid"),_("perms"),_("cuid"),_("cgid"),_("uid"),_("gid")); - break; - - case TIME: - printf (_("------ Shared Memory Attach/Detach/Change Times --------\n")); - printf ("%-10s %-10s %-20s %-20s %-20s\n", - _("shmid"),_("owner"),_("attached"),_("detached"), - _("changed")); - break; - - case PID: - printf (_("------ Shared Memory Creator/Last-op --------\n")); - printf ("%-10s %-10s %-10s %-10s\n", - _("shmid"),_("owner"),_("cpid"),_("lpid")); - break; - - default: - printf (_("------ Shared Memory Segments --------\n")); - printf ("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", - _("key"),_("shmid"),_("owner"),_("perms"),_("bytes"), - _("nattch"),_("status")); - break; - } - - for (id = 0; id <= maxid; id++) { - shmid = shmctl (id, SHM_STAT, &shmseg); - if (shmid < 0) - continue; - if (format == CREATOR) { - print_perms (shmid, ipcp); - continue; - } - pw = getpwuid(ipcp->uid); - switch (format) { - case TIME: - if (pw) - printf ("%-10d %-10.10s", shmid, pw->pw_name); - else - printf ("%-10d %-10d", shmid, ipcp->uid); - /* ctime uses static buffer: use separate calls */ - printf(" %-20.16s", shmseg.shm_atime - ? ctime(&shmseg.shm_atime) + 4 : _("Not set")); - printf(" %-20.16s", shmseg.shm_dtime - ? ctime(&shmseg.shm_dtime) + 4 : _("Not set")); - printf(" %-20.16s\n", shmseg.shm_ctime - ? ctime(&shmseg.shm_ctime) + 4 : _("Not set")); - break; - case PID: - if (pw) - printf ("%-10d %-10.10s", shmid, pw->pw_name); - else - printf ("%-10d %-10d", shmid, ipcp->uid); - printf (" %-10d %-10d\n", - shmseg.shm_cpid, shmseg.shm_lpid); - break; - - default: - printf("0x%08lx ",ipcp->KEY ); - if (pw) - printf ("%-10d %-10.10s", shmid, pw->pw_name); - else - printf ("%-10d %-10d", shmid, ipcp->uid); - printf (" %-10o %-10lu %-10ld %-6s %-6s\n", - ipcp->mode & 0777, - /* - * earlier: int, Austin has size_t - */ - (unsigned long) shmseg.shm_segsz, - /* - * glibc-2.1.3 and earlier has unsigned short; - * Austin has shmatt_t - */ - (long) shmseg.shm_nattch, - ipcp->mode & SHM_DEST ? _("dest") : " ", - ipcp->mode & SHM_LOCKED ? _("locked") : " "); - break; - } - } - return; -} - - -void do_sem (char format) -{ - int maxid, semid, id; - struct semid_ds semary; - struct seminfo seminfo; - struct ipc_perm *ipcp = &semary.sem_perm; - struct passwd *pw; - union semun arg; - - arg.array = (unsigned short *) (void *) &seminfo; - maxid = semctl (0, 0, SEM_INFO, arg); - if (maxid < 0) { - printf (_("kernel not configured for semaphores\n")); - return; - } - - switch (format) { - case LIMITS: - printf (_("------ Semaphore Limits --------\n")); - arg.array = (unsigned short *) (void *) &seminfo; /* damn union */ - if ((semctl (0, 0, IPC_INFO, arg)) < 0 ) - return; - printf (_("max number of arrays = %d\n"), seminfo.semmni); - printf (_("max semaphores per array = %d\n"), seminfo.semmsl); - printf (_("max semaphores system wide = %d\n"), seminfo.semmns); - printf (_("max ops per semop call = %d\n"), seminfo.semopm); - printf (_("semaphore max value = %d\n"), seminfo.semvmx); - return; - - case STATUS: - printf (_("------ Semaphore Status --------\n")); - printf (_("used arrays = %d\n"), seminfo.semusz); - printf (_("allocated semaphores = %d\n"), seminfo.semaem); - return; - - case CREATOR: - printf (_("------ Semaphore Arrays Creators/Owners --------\n")); - printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n", - _("semid"),_("perms"),_("cuid"),_("cgid"),_("uid"),_("gid")); - break; - - case TIME: - printf (_("------ Semaphore Operation/Change Times --------\n")); - printf ("%-8s %-10s %-26.24s %-26.24s\n", - _("semid"),_("owner"),_("last-op"),_("last-changed")); - break; - - case PID: - break; - - default: - printf (_("------ Semaphore Arrays --------\n")); - printf ("%-10s %-10s %-10s %-10s %-10s\n", - _("key"),_("semid"),_("owner"),_("perms"),_("nsems")); - break; - } - - for (id = 0; id <= maxid; id++) { - arg.buf = (struct semid_ds *) &semary; - semid = semctl (id, 0, SEM_STAT, arg); - if (semid < 0) - continue; - if (format == CREATOR) { - print_perms (semid, ipcp); - continue; - } - pw = getpwuid(ipcp->uid); - switch (format) { - case TIME: - if (pw) - printf ("%-8d %-10.10s", semid, pw->pw_name); - else - printf ("%-8d %-10d", semid, ipcp->uid); - printf (" %-26.24s", semary.sem_otime - ? ctime(&semary.sem_otime) : _("Not set")); - printf (" %-26.24s\n", semary.sem_ctime - ? ctime(&semary.sem_ctime) : _("Not set")); - break; - case PID: - break; - - default: - printf("0x%08lx ", ipcp->KEY); - if (pw) - printf ("%-10d %-10.10s", semid, pw->pw_name); - else - printf ("%-10d %-10d", semid, ipcp->uid); - printf (" %-10o %-10ld\n", - ipcp->mode & 0777, - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short and unsigned long - * Austin prescribes unsigned short. - */ - (long) semary.sem_nsems); - break; - } - } -} - - -void do_msg (char format) -{ -#if 0 - int maxid, msqid, id; - struct msqid_ds msgque; - struct msginfo msginfo; - struct ipc_perm *ipcp = &msgque.msg_perm; - struct passwd *pw; - - maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo); - if (maxid < 0) { - printf (_("kernel not configured for message queues\n")); - return; - } - - switch (format) { - case LIMITS: - if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 ) - return; - printf (_("------ Messages: Limits --------\n")); - printf (_("max queues system wide = %d\n"), msginfo.msgmni); - printf (_("max size of message (bytes) = %d\n"), msginfo.msgmax); - printf (_("default max size of queue (bytes) = %d\n"), msginfo.msgmnb); - return; - - case STATUS: - printf (_("------ Messages: Status --------\n")); - printf (_("allocated queues = %d\n"), msginfo.msgpool); - printf (_("used headers = %d\n"), msginfo.msgmap); - printf (_("used space = %d bytes\n"), msginfo.msgtql); - return; - - case CREATOR: - printf (_("------ Message Queues: Creators/Owners --------\n")); - printf ("%-10s %-10s %-10s %-10s %-10s %-10s\n", - _("msqid"),_("perms"),_("cuid"),_("cgid"),_("uid"),_("gid")); - break; - - case TIME: - printf (_("------ Message Queues Send/Recv/Change Times --------\n")); - printf ("%-8s %-10s %-20s %-20s %-20s\n", - _("msqid"),_("owner"),_("send"),_("recv"),_("change")); - break; - - case PID: - printf (_("------ Message Queues PIDs --------\n")); - printf ("%-10s %-10s %-10s %-10s\n", - _("msqid"),_("owner"),_("lspid"),_("lrpid")); - break; - - default: - printf (_("------ Message Queues --------\n")); - printf ("%-10s %-10s %-10s %-10s %-12s %-12s\n", - _("key"), _("msqid"), _("owner"), _("perms"), - _("used-bytes"), _("messages")); - break; - } - - for (id = 0; id <= maxid; id++) { - msqid = msgctl (id, MSG_STAT, &msgque); - if (msqid < 0) - continue; - if (format == CREATOR) { - print_perms (msqid, ipcp); - continue; - } - pw = getpwuid(ipcp->uid); - switch (format) { - case TIME: - if (pw) - printf ("%-8d %-10.10s", msqid, pw->pw_name); - else - printf ("%-8d %-10d", msqid, ipcp->uid); - printf (" %-20.16s", msgque.msg_stime - ? ctime(&msgque.msg_stime) + 4 : _("Not set")); - printf (" %-20.16s", msgque.msg_rtime - ? ctime(&msgque.msg_rtime) + 4 : _("Not set")); - printf (" %-20.16s\n", msgque.msg_ctime - ? ctime(&msgque.msg_ctime) + 4 : _("Not set")); - break; - case PID: - if (pw) - printf ("%-8d %-10.10s", msqid, pw->pw_name); - else - printf ("%-8d %-10d", msqid, ipcp->uid); - printf (" %5d %5d\n", - msgque.msg_lspid, msgque.msg_lrpid); - break; - - default: - printf( "0x%08x ",ipcp->KEY ); - if (pw) - printf ("%-10d %-10.10s", msqid, pw->pw_name); - else - printf ("%-10d %-10d", msqid, ipcp->uid); - printf (" %-10o %-12ld %-12ld\n", - ipcp->mode & 0777, - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short, unsigned long - * Austin has msgqnum_t - */ - (long) msgque.msg_cbytes, - (long) msgque.msg_qnum); - break; - } - } - return; -#endif -} - - -void print_shm (int shmid) -{ - struct shmid_ds shmds; - struct ipc_perm *ipcp = &shmds.shm_perm; - - if (shmctl (shmid, IPC_STAT, &shmds) == -1) - err(EXIT_FAILURE, _("shmctl failed")); - - printf (_("\nShared memory Segment shmid=%d\n"), shmid); - printf (_("uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"), - ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid); - printf (_("mode=%#o\taccess_perms=%#o\n"), - ipcp->mode, ipcp->mode & 0777); - printf (_("bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n"), - (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, - (long) shmds.shm_nattch); - printf (_("att_time=%-26.24s\n"), - shmds.shm_atime ? ctime (&shmds.shm_atime) : _("Not set")); - printf (_("det_time=%-26.24s\n"), - shmds.shm_dtime ? ctime (&shmds.shm_dtime) : _("Not set")); - printf (_("change_time=%-26.24s\n"), ctime (&shmds.shm_ctime)); - printf ("\n"); - return; -} - - -void print_msg (int msqid) -{ -#if 0 - struct msqid_ds buf; - struct ipc_perm *ipcp = &buf.msg_perm; - - if (msgctl (msqid, IPC_STAT, &buf) == -1) - err(EXIT_FAILURE, _("msgctl failed")); - - printf (_("\nMessage Queue msqid=%d\n"), msqid); - printf (_("uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"), - ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode); - printf (_("cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n"), - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short, unsigned long - * Austin has msgqnum_t (for msg_qbytes) - */ - (long) buf.msg_cbytes, (long) buf.msg_qbytes, - (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); - printf (_("send_time=%-26.24s\n"), - buf.msg_stime ? ctime (&buf.msg_stime) : _("Not set")); - printf (_("rcv_time=%-26.24s\n"), - buf.msg_rtime ? ctime (&buf.msg_rtime) : _("Not set")); - printf (_("change_time=%-26.24s\n"), - buf.msg_ctime ? ctime (&buf.msg_ctime) : _("Not set")); - printf ("\n"); - return; -#endif -} - -void print_sem (int semid) -{ - struct semid_ds semds; - struct ipc_perm *ipcp = &semds.sem_perm; - union semun arg; - int i; - - arg.buf = &semds; - if (semctl (semid, 0, IPC_STAT, arg) < 0) - err(EXIT_FAILURE, _("semctl failed")); - - printf (_("\nSemaphore Array semid=%d\n"), semid); - printf (_("uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"), - ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid); - printf (_("mode=%#o, access_perms=%#o\n"), - ipcp->mode, ipcp->mode & 0777); - printf (_("nsems = %ld\n"), (long) semds.sem_nsems); - printf (_("otime = %-26.24s\n"), - semds.sem_otime ? ctime (&semds.sem_otime) : _("Not set")); - printf (_("ctime = %-26.24s\n"), ctime (&semds.sem_ctime)); - - printf ("%-10s %-10s %-10s %-10s %-10s\n", - _("semnum"),_("value"),_("ncount"),_("zcount"),_("pid")); - arg.val = 0; - for (i=0; i< semds.sem_nsems; i++) { - int val, ncnt, zcnt, pid; - val = semctl (semid, i, GETVAL, arg); - ncnt = semctl (semid, i, GETNCNT, arg); - zcnt = semctl (semid, i, GETZCNT, arg); - pid = semctl (semid, i, GETPID, arg); - if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) - err(EXIT_FAILURE, _("semctl failed")); - - printf ("%-10d %-10d %-10d %-10d %-10d\n", - i, val, ncnt, zcnt, pid); - } - printf ("\n"); - return; -} diff --git a/usr.bin/Makefile b/usr.bin/Makefile index cb2eea606..edb0917b5 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -13,7 +13,7 @@ SUBDIR= asa \ false find finger flock fold fpr from \ fsplit ftp genassym \ getopt \ - head hexdump id indent infocmp join jot \ + head hexdump id indent infocmp ipcs join jot \ lam last ldd leave \ lock login logname lorder m4 \ machine make man menuc mesg \ diff --git a/usr.bin/ipcs/Makefile b/usr.bin/ipcs/Makefile new file mode 100644 index 000000000..0c39958f3 --- /dev/null +++ b/usr.bin/ipcs/Makefile @@ -0,0 +1,5 @@ +# $NetBSD: Makefile,v 1.11 2014/06/11 14:57:55 joerg Exp $ + +PROG= ipcs + +.include diff --git a/usr.bin/ipcs/ipcs.1 b/usr.bin/ipcs/ipcs.1 new file mode 100644 index 000000000..86bd34e5f --- /dev/null +++ b/usr.bin/ipcs/ipcs.1 @@ -0,0 +1,141 @@ +.\" $NetBSD: ipcs.1,v 1.20 2014/06/11 14:57:55 joerg Exp $ +.\" +.\" Copyright (c) 1994 SigmaSoft, Th. Lockert +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd June 11, 2014 +.Dt IPCS 1 +.Os +.Sh NAME +.Nm ipcs +.Nd report System V interprocess communication facilities status +.Sh SYNOPSIS +.Nm +.Op Fl abcmopqstMQST +.Sh DESCRIPTION +The +.Nm +program provides information on System V interprocess communication +(IPC) facilities on the system. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl a +Show the maximum amount of information possible when +displaying active semaphores, message queues, +and shared memory segments. +(This is shorthand for specifying the +.Fl b , +.Fl c , +.Fl o , +.Fl p , +and +.Fl t +options.) +.It Fl b +Show the maximum allowed sizes for active semaphores, message queues, +and shared memory segments. +The +.Dq maximum allowed size +is the maximum number of bytes in a message on a message queue, +the size of a shared memory segment, +or the number of semaphores in a set of semaphores. +.It Fl c +Show the creator's name and group for active semaphores, message queues, +and shared memory segments. +.It Fl m +Display information about active shared memory segments. +.It Fl o +Show outstanding usage for active message queues, +and shared memory segments. +The +.Dq outstanding usage +is the number of messages in a message queue, or the number +of processes attached to a shared memory segment. +.It Fl p +Show the process ID information for active semaphores, message queues, +and shared memory segments. +The +.Dq process ID information +is the last process to send a message to or receive a message from +a message queue, +the process that created a semaphore, or the last process to attach +or detach a shared memory segment. +.It Fl q +Display information about active message queues. +.It Fl s +Display information about active semaphores. +.It Fl t +Show access times for active semaphores, message queues, +and shared memory segments. +The access times is the time +of the last control operation on an IPC object, +the last send or receive of a message, +the last attach or detach of a shared memory segment, +or the last operation on a semaphore. +.It Fl M +Display system information about shared memory. +.It Fl Q +Display system information about messages queues. +.It Fl S +Display system information about semaphores. +.It Fl T +Display system information about shared memory, message queues +and semaphores. +(This is shorthand for specifying the +.Fl M , +.Fl Q , +and +.Fl S +options.) +.El +.Pp +If none of the +.Fl M , +.Fl m , +.Fl Q , +.Fl q , +.Fl S , +.Fl s , +or +.Fl T +options are specified, information about all active IPC facilities is +listed. +.Sh RESTRICTIONS +System data structures may change while +.Nm +is running; the output of +.Nm +is not guaranteed to be consistent. +.Sh SEE ALSO +.Xr ipcrm 1 , +.Xr shmat 2 , +.Xr shmctl 2 , +.Xr shmdt 2 , +.Xr shmget 2 +.Sh AUTHORS +.An Thorsten Lockert Aq Mt tholo@sigmasoft.com +.Sh BUGS +This manual page is woefully incomplete, because it does not +at all attempt to explain the information printed by +.Nm . diff --git a/usr.bin/ipcs/ipcs.c b/usr.bin/ipcs/ipcs.c new file mode 100644 index 000000000..8fbae9067 --- /dev/null +++ b/usr.bin/ipcs/ipcs.c @@ -0,0 +1,678 @@ +/* $NetBSD: ipcs.c,v 1.43 2014/06/11 14:57:55 joerg Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Simon Burge. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1994 SigmaSoft, Th. Lockert + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SHMINFO 1 +#define SHMTOTAL 2 +#define MSGINFO 4 +#define MSGTOTAL 8 +#define SEMINFO 16 +#define SEMTOTAL 32 + +#define BIGGEST 1 +#define CREATOR 2 +#define OUTSTANDING 4 +#define PID 8 +#define TIME 16 + +static int display = 0; +static int option = 0; + +static void cvt_time(time_t, char *, size_t); +static char *fmt_perm(u_short); +static void msg_sysctl(void); +static void sem_sysctl(void); +static void shm_sysctl(void); +static void show_msginfo(time_t, time_t, time_t, int, u_int64_t, mode_t, + uid_t, gid_t, uid_t, gid_t, u_int64_t, u_int64_t, u_int64_t, pid_t, pid_t); +static void show_msginfo_hdr(void); +static void show_msgtotal(struct msginfo *); +static void show_seminfo_hdr(void); +static void show_seminfo(time_t, time_t, int, u_int64_t, mode_t, uid_t, + gid_t, uid_t, gid_t, int16_t); +static void show_semtotal(struct seminfo *); +static void show_shminfo(time_t, time_t, time_t, int, u_int64_t, mode_t, + uid_t, gid_t, uid_t, gid_t, u_int32_t, u_int64_t, pid_t, pid_t); +static void show_shminfo_hdr(void); +static void show_shmtotal(struct shminfo *); +static void usage(void) __dead; +static void unconfsem(void); +static void unconfmsg(void); +static void unconfshm(void); + +static void +unconfsem(void) +{ + warnx("SVID semaphores facility not configured in the system"); +} + +static void +unconfmsg(void) +{ + warnx("SVID messages facility not configured in the system"); +} + +static void +unconfshm(void) +{ + warnx("SVID shared memory facility not configured in the system"); +} + +static char * +fmt_perm(u_short mode) +{ + static char buffer[12]; + + buffer[0] = '-'; + buffer[1] = '-'; + buffer[2] = ((mode & 0400) ? 'r' : '-'); + buffer[3] = ((mode & 0200) ? 'w' : '-'); + buffer[4] = ((mode & 0100) ? 'a' : '-'); + buffer[5] = ((mode & 0040) ? 'r' : '-'); + buffer[6] = ((mode & 0020) ? 'w' : '-'); + buffer[7] = ((mode & 0010) ? 'a' : '-'); + buffer[8] = ((mode & 0004) ? 'r' : '-'); + buffer[9] = ((mode & 0002) ? 'w' : '-'); + buffer[10] = ((mode & 0001) ? 'a' : '-'); + buffer[11] = '\0'; + return (&buffer[0]); +} + +static void +cvt_time(time_t t, char *buf, size_t buflen) +{ + struct tm *tm; + + if (t == 0) + (void)strlcpy(buf, "no-entry", buflen); + else { + tm = localtime(&t); + (void)snprintf(buf, buflen, "%2d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + } +} +int +main(int argc, char *argv[]) +{ + int i; + time_t now; + + while ((i = getopt(argc, argv, "MmQqSsabcoptT")) != -1) + switch (i) { + case 'M': + display |= SHMTOTAL; + break; + case 'm': + display |= SHMINFO; + break; + case 'Q': + display |= MSGTOTAL; + break; + case 'q': + display |= MSGINFO; + break; + case 'S': + display |= SEMTOTAL; + break; + case 's': + display |= SEMINFO; + break; + case 'T': + display |= SHMTOTAL | MSGTOTAL | SEMTOTAL; + break; + case 'a': + option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME; + break; + case 'b': + option |= BIGGEST; + break; + case 'c': + option |= CREATOR; + break; + case 'o': + option |= OUTSTANDING; + break; + case 'p': + option |= PID; + break; + case 't': + option |= TIME; + break; + default: + usage(); + } + + if (argc - optind > 0) + usage(); + + (void)time(&now); + (void)printf("IPC status from as of %s\n", + /* and extra \n from ctime(3) */ + ctime(&now)); + + if (display == 0) + display = SHMINFO | MSGINFO | SEMINFO; + + if (display & (MSGINFO | MSGTOTAL)) + msg_sysctl(); + if (display & (SHMINFO | SHMTOTAL)) + shm_sysctl(); + if (display & (SEMINFO | SEMTOTAL)) + sem_sysctl(); + return 0; +} + +static void +show_msgtotal(struct msginfo *msginfo) +{ + (void)printf("msginfo:\n"); + (void)printf("\tmsgmax: %6d\t(max characters in a message)\n", + msginfo->msgmax); + (void)printf("\tmsgmni: %6d\t(# of message queues)\n", + msginfo->msgmni); + (void)printf("\tmsgmnb: %6d\t(max characters in a message queue)\n", + msginfo->msgmnb); + (void)printf("\tmsgtql: %6d\t(max # of messages in system)\n", + msginfo->msgtql); + (void)printf("\tmsgssz: %6d\t(size of a message segment)\n", + msginfo->msgssz); + (void)printf("\tmsgseg: %6d\t(# of message segments in system)\n\n", + msginfo->msgseg); +} + +static void +show_shmtotal(struct shminfo *shminfo) +{ + (void)printf("shminfo:\n"); + (void)printf("\tshmmax: %" PRIu64 "\t(max shared memory segment size)\n", + shminfo->shmmax); + (void)printf("\tshmmin: %7d\t(min shared memory segment size)\n", + shminfo->shmmin); + (void)printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n", + shminfo->shmmni); + (void)printf("\tshmseg: %7d\t(max shared memory segments per process)\n", + shminfo->shmseg); + (void)printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n", + shminfo->shmall); +} + +static void +show_semtotal(struct seminfo *seminfo) +{ + (void)printf("seminfo:\n"); + (void)printf("\tsemmap: %6d\t(# of entries in semaphore map)\n", + seminfo->semmap); + (void)printf("\tsemmni: %6d\t(# of semaphore identifiers)\n", + seminfo->semmni); + (void)printf("\tsemmns: %6d\t(# of semaphores in system)\n", + seminfo->semmns); + (void)printf("\tsemmnu: %6d\t(# of undo structures in system)\n", + seminfo->semmnu); + (void)printf("\tsemmsl: %6d\t(max # of semaphores per id)\n", + seminfo->semmsl); + (void)printf("\tsemopm: %6d\t(max # of operations per semop call)\n", + seminfo->semopm); + (void)printf("\tsemume: %6d\t(max # of undo entries per process)\n", + seminfo->semume); + (void)printf("\tsemusz: %6d\t(size in bytes of undo structure)\n", + seminfo->semusz); + (void)printf("\tsemvmx: %6d\t(semaphore maximum value)\n", + seminfo->semvmx); + (void)printf("\tsemaem: %6d\t(adjust on exit max value)\n\n", + seminfo->semaem); +} + +static void +show_msginfo_hdr(void) +{ + (void)printf("Message Queues:\n"); + (void)printf("T ID KEY MODE OWNER GROUP"); + if (option & CREATOR) + (void)printf(" CREATOR CGROUP"); + if (option & OUTSTANDING) + (void)printf(" CBYTES QNUM"); + if (option & BIGGEST) + (void)printf(" QBYTES"); + if (option & PID) + (void)printf(" LSPID LRPID"); + if (option & TIME) + (void)printf(" STIME RTIME CTIME"); + (void)printf("\n"); +} + +static void +show_msginfo(time_t s_time, time_t r_time, time_t c_time, int ipcid, + u_int64_t key, + mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, + u_int64_t cbytes, u_int64_t qnum, u_int64_t qbytes, pid_t lspid, + pid_t lrpid) +{ + char s_time_buf[100], r_time_buf[100], c_time_buf[100]; + + if (option & TIME) { + cvt_time(s_time, s_time_buf, sizeof(s_time_buf)); + cvt_time(r_time, r_time_buf, sizeof(r_time_buf)); + cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); + } + + (void)printf("q %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), + user_from_uid(uid, 0), group_from_gid(gid, 0)); + + if (option & CREATOR) + (void)printf(" %8s %8s", user_from_uid(cuid, 0), + group_from_gid(cgid, 0)); + + if (option & OUTSTANDING) + (void)printf(" %6lld %5lld", (long long)cbytes, (long long)qnum); + + if (option & BIGGEST) + (void)printf(" %6lld", (long long)qbytes); + + if (option & PID) + (void)printf(" %5d %5d", lspid, lrpid); + + if (option & TIME) + (void)printf(" %s %s %s", s_time_buf, r_time_buf, c_time_buf); + + (void)printf("\n"); +} + +static void +show_shminfo_hdr(void) +{ + (void)printf("Shared Memory:\n"); + (void)printf("T ID KEY MODE OWNER GROUP"); + if (option & CREATOR) + (void)printf(" CREATOR CGROUP"); + if (option & OUTSTANDING) + (void)printf(" NATTCH"); + if (option & BIGGEST) + (void)printf(" SEGSZ"); + if (option & PID) + (void)printf(" CPID LPID"); + if (option & TIME) + (void)printf(" ATIME DTIME CTIME"); + (void)printf("\n"); +} + +static void +show_shminfo(time_t atime, time_t dtime, time_t c_time, int ipcid, u_int64_t key, + mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, + u_int32_t nattch, u_int64_t segsz, pid_t cpid, pid_t lpid) +{ + char atime_buf[100], dtime_buf[100], c_time_buf[100]; + + if (option & TIME) { + cvt_time(atime, atime_buf, sizeof(atime_buf)); + cvt_time(dtime, dtime_buf, sizeof(dtime_buf)); + cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); + } + + (void)printf("m %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), + user_from_uid(uid, 0), group_from_gid(gid, 0)); + + if (option & CREATOR) + (void)printf(" %8s %8s", user_from_uid(cuid, 0), + group_from_gid(cgid, 0)); + + if (option & OUTSTANDING) + (void)printf(" %6d", nattch); + + if (option & BIGGEST) + (void)printf(" %7llu", (long long)segsz); + + if (option & PID) + (void)printf(" %5d %5d", cpid, lpid); + + if (option & TIME) + (void)printf(" %s %s %s", + atime_buf, + dtime_buf, + c_time_buf); + + (void)printf("\n"); +} + +static void +show_seminfo_hdr(void) +{ + (void)printf("Semaphores:\n"); + (void)printf("T ID KEY MODE OWNER GROUP"); + if (option & CREATOR) + (void)printf(" CREATOR CGROUP"); + if (option & BIGGEST) + (void)printf(" NSEMS"); + if (option & TIME) + (void)printf(" OTIME CTIME"); + (void)printf("\n"); +} + +static void +show_seminfo(time_t otime, time_t c_time, int ipcid, u_int64_t key, mode_t mode, + uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, int16_t nsems) +{ + char c_time_buf[100], otime_buf[100]; + + if (option & TIME) { + cvt_time(otime, otime_buf, sizeof(otime_buf)); + cvt_time(c_time, c_time_buf, sizeof(c_time_buf)); + } + + (void)printf("s %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode), + user_from_uid(uid, 0), group_from_gid(gid, 0)); + + if (option & CREATOR) + (void)printf(" %8s %8s", user_from_uid(cuid, 0), + group_from_gid(cgid, 0)); + + if (option & BIGGEST) + (void)printf(" %5d", nsems); + + if (option & TIME) + (void)printf(" %s %s", otime_buf, c_time_buf); + + (void)printf("\n"); +} + +static void +msg_sysctl(void) +{ + struct msg_sysctl_info *msgsi; + void *buf; + int mib[4]; + size_t len; + int i, valid; + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_MSG; + len = sizeof(valid); + if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_MSG)"); + return; + } + if (!valid) { + unconfmsg(); + return; + } + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_INFO; + mib[3] = KERN_SYSVIPC_MSG_INFO; + + if (!(display & MSGINFO)) { + /* totals only */ + len = sizeof(struct msginfo); + } else { + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); + return; + } + } + + if ((buf = malloc(len)) == NULL) + err(1, "malloc"); + msgsi = (struct msg_sysctl_info *)buf; + if (sysctl(mib, 4, msgsi, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_MSG_INFO)"); + goto done; + } + + if (display & MSGTOTAL) + show_msgtotal(&msgsi->msginfo); + + if (display & MSGINFO) { + show_msginfo_hdr(); + for (i = 0; i < msgsi->msginfo.msgmni; i++) { + struct msgid_ds_sysctl *msqptr = &msgsi->msgids[i]; + if (msqptr->msg_qbytes != 0) + show_msginfo(msqptr->msg_stime, + msqptr->msg_rtime, + msqptr->msg_ctime, + IXSEQ_TO_IPCID(i, msqptr->msg_perm), + msqptr->msg_perm._key, + msqptr->msg_perm.mode, + msqptr->msg_perm.uid, + msqptr->msg_perm.gid, + msqptr->msg_perm.cuid, + msqptr->msg_perm.cgid, + msqptr->_msg_cbytes, + msqptr->msg_qnum, + msqptr->msg_qbytes, + msqptr->msg_lspid, + msqptr->msg_lrpid); + } + (void)printf("\n"); + } +done: + free(buf); +} + +static void +shm_sysctl(void) +{ + struct shm_sysctl_info *shmsi; + void *buf; + int mib[4]; + size_t len; + uint32_t i; + long valid; + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_SHM; + len = sizeof(valid); + if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SHM)"); + return; + } + if (!valid) { + unconfshm(); + return; + } + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_INFO; + mib[3] = KERN_SYSVIPC_SHM_INFO; + + if (!(display & SHMINFO)) { + /* totals only */ + len = sizeof(struct shminfo); + } else { + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); + return; + } + } + + if ((buf = malloc(len)) == NULL) + err(1, "malloc"); + shmsi = (struct shm_sysctl_info *)buf; + if (sysctl(mib, 4, shmsi, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SHM_INFO)"); + goto done; + } + + if (display & SHMTOTAL) + show_shmtotal(&shmsi->shminfo); + + if (display & SHMINFO) { + show_shminfo_hdr(); + for (i = 0; i < shmsi->shminfo.shmmni; i++) { + struct shmid_ds_sysctl *shmptr = &shmsi->shmids[i]; + if (shmptr->shm_perm.mode & 0x0800) + show_shminfo(shmptr->shm_atime, + shmptr->shm_dtime, + shmptr->shm_ctime, + IXSEQ_TO_IPCID(i, shmptr->shm_perm), + shmptr->shm_perm._key, + shmptr->shm_perm.mode, + shmptr->shm_perm.uid, + shmptr->shm_perm.gid, + shmptr->shm_perm.cuid, + shmptr->shm_perm.cgid, + shmptr->shm_nattch, + shmptr->shm_segsz, + shmptr->shm_cpid, + shmptr->shm_lpid); + } + (void)printf("\n"); + } +done: + free(buf); +} + +static void +sem_sysctl(void) +{ + struct sem_sysctl_info *semsi; + void *buf; + int mib[4]; + size_t len; + int i, valid; + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_SEM; + len = sizeof(valid); + if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SEM)"); + return; + } + if (!valid) { + unconfsem(); + return; + } + + mib[0] = CTL_KERN; + mib[1] = KERN_SYSVIPC; + mib[2] = KERN_SYSVIPC_INFO; + mib[3] = KERN_SYSVIPC_SEM_INFO; + + if (!(display & SEMINFO)) { + /* totals only */ + len = sizeof(struct seminfo); + } else { + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); + return; + } + } + + if ((buf = malloc(len)) == NULL) + err(1, "malloc"); + semsi = (struct sem_sysctl_info *)buf; + if (sysctl(mib, 4, semsi, &len, NULL, 0) < 0) { + warn("sysctl(KERN_SYSVIPC_SEM_INFO)"); + goto done; + } + + if (display & SEMTOTAL) + show_semtotal(&semsi->seminfo); + + if (display & SEMINFO) { + show_seminfo_hdr(); + for (i = 0; i < semsi->seminfo.semmni; i++) { + struct semid_ds_sysctl *semaptr = &semsi->semids[i]; + if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) + show_seminfo(semaptr->sem_otime, + semaptr->sem_ctime, + IXSEQ_TO_IPCID(i, semaptr->sem_perm), + semaptr->sem_perm._key, + semaptr->sem_perm.mode, + semaptr->sem_perm.uid, + semaptr->sem_perm.gid, + semaptr->sem_perm.cuid, + semaptr->sem_perm.cgid, + semaptr->sem_nsems); + } + (void)printf("\n"); + } +done: + free(buf); +} + +static void +usage(void) +{ + + (void)fprintf(stderr, + "Usage: %s [-abcmopqstMQST]\n", + getprogname()); + exit(1); +}