Home | History | Annotate | Line # | Download | only in ipcs
ipcs.c revision 1.40
      1  1.40     rmind /*	$NetBSD: ipcs.c,v 1.40 2008/04/12 20:49:22 rmind Exp $	*/
      2  1.23    simonb 
      3  1.23    simonb /*-
      4  1.23    simonb  * Copyright (c) 2000 The NetBSD Foundation, Inc.
      5  1.23    simonb  * All rights reserved.
      6  1.23    simonb  *
      7  1.23    simonb  * This code is derived from software contributed to The NetBSD Foundation
      8  1.23    simonb  * by Simon Burge.
      9  1.23    simonb  *
     10  1.23    simonb  * Redistribution and use in source and binary forms, with or without
     11  1.23    simonb  * modification, are permitted provided that the following conditions
     12  1.23    simonb  * are met:
     13  1.23    simonb  * 1. Redistributions of source code must retain the above copyright
     14  1.23    simonb  *    notice, this list of conditions and the following disclaimer.
     15  1.23    simonb  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.23    simonb  *    notice, this list of conditions and the following disclaimer in the
     17  1.23    simonb  *    documentation and/or other materials provided with the distribution.
     18  1.23    simonb  * 3. All advertising materials mentioning features or use of this software
     19  1.23    simonb  *    must display the following acknowledgement:
     20  1.23    simonb  *        This product includes software developed by the NetBSD
     21  1.23    simonb  *        Foundation, Inc. and its contributors.
     22  1.23    simonb  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.23    simonb  *    contributors may be used to endorse or promote products derived
     24  1.23    simonb  *    from this software without specific prior written permission.
     25  1.23    simonb  *
     26  1.23    simonb  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.23    simonb  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.23    simonb  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.23    simonb  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.23    simonb  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.23    simonb  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.23    simonb  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.23    simonb  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.23    simonb  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.23    simonb  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.23    simonb  * POSSIBILITY OF SUCH DAMAGE.
     37  1.23    simonb  */
     38   1.8       cgd 
     39   1.1       cgd /*
     40   1.6       cgd  * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo (at) sigmasoft.com>
     41   1.6       cgd  * All rights reserved.
     42   1.1       cgd  *
     43   1.6       cgd  * Redistribution and use in source and binary forms, with or without
     44   1.6       cgd  * modification, are permitted provided that the following conditions
     45   1.6       cgd  * are met:
     46   1.6       cgd  * 1. Redistributions of source code must retain the above copyright
     47   1.6       cgd  *    notice, this list of conditions and the following disclaimer.
     48   1.6       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     49   1.6       cgd  *    notice, this list of conditions and the following disclaimer in the
     50   1.6       cgd  *    documentation and/or other materials provided with the distribution.
     51   1.6       cgd  *
     52   1.6       cgd  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     53   1.6       cgd  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     54   1.6       cgd  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     55   1.6       cgd  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     56   1.6       cgd  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     57   1.6       cgd  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     58   1.6       cgd  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     59   1.6       cgd  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     60   1.6       cgd  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     61   1.6       cgd  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     62   1.1       cgd  */
     63   1.1       cgd 
     64  1.38     perry #include <sys/cdefs.h>
     65   1.1       cgd #include <sys/param.h>
     66  1.23    simonb #include <sys/sysctl.h>
     67  1.40     rmind #include <sys/inttypes.h>
     68   1.1       cgd #include <sys/ipc.h>
     69   1.1       cgd #include <sys/sem.h>
     70   1.1       cgd #include <sys/shm.h>
     71   1.1       cgd #include <sys/msg.h>
     72   1.1       cgd 
     73  1.11   thorpej #include <err.h>
     74  1.11   thorpej #include <fcntl.h>
     75  1.14     lukem #include <grp.h>
     76  1.11   thorpej #include <kvm.h>
     77  1.11   thorpej #include <limits.h>
     78  1.11   thorpej #include <nlist.h>
     79  1.11   thorpej #include <paths.h>
     80  1.14     lukem #include <pwd.h>
     81  1.11   thorpej #include <stdio.h>
     82  1.11   thorpej #include <stdlib.h>
     83  1.11   thorpej #include <string.h>
     84  1.15    kleink #include <time.h>
     85  1.11   thorpej #include <unistd.h>
     86  1.19  augustss 
     87  1.35  christos #define	SHMINFO		1
     88  1.35  christos #define	SHMTOTAL	2
     89  1.35  christos #define	MSGINFO		4
     90  1.35  christos #define	MSGTOTAL	8
     91  1.35  christos #define	SEMINFO		16
     92  1.35  christos #define	SEMTOTAL	32
     93  1.35  christos 
     94  1.35  christos #define BIGGEST		1
     95  1.35  christos #define CREATOR		2
     96  1.35  christos #define OUTSTANDING	4
     97  1.35  christos #define PID		8
     98  1.35  christos #define TIME		16
     99  1.35  christos 
    100  1.35  christos static char	*core = NULL, *namelist = NULL;
    101  1.35  christos static int	display = 0;
    102  1.35  christos static int	option = 0;
    103  1.35  christos 
    104  1.35  christos static void	cvt_time(time_t, char *, size_t);
    105  1.35  christos static char    *fmt_perm(u_short);
    106  1.35  christos static void	ipcs_kvm(void);
    107  1.35  christos static void	msg_sysctl(void);
    108  1.35  christos static void	sem_sysctl(void);
    109  1.35  christos static void	shm_sysctl(void);
    110  1.35  christos static void	show_msginfo(time_t, time_t, time_t, int, u_int64_t, mode_t,
    111  1.35  christos     uid_t, gid_t, uid_t, gid_t, u_int64_t, u_int64_t, u_int64_t, pid_t, pid_t);
    112  1.35  christos static void	show_msginfo_hdr(void);
    113  1.35  christos static void	show_msgtotal(struct msginfo *);
    114  1.35  christos static void	show_seminfo_hdr(void);
    115  1.35  christos static void	show_seminfo(time_t, time_t, int, u_int64_t, mode_t, uid_t,
    116  1.35  christos     gid_t, uid_t, gid_t, int16_t);
    117  1.35  christos static void	show_semtotal(struct seminfo *);
    118  1.35  christos static void	show_shminfo(time_t, time_t, time_t, int, u_int64_t, mode_t,
    119  1.35  christos     uid_t, gid_t, uid_t, gid_t, u_int32_t, u_int64_t, pid_t, pid_t);
    120  1.35  christos static void	show_shminfo_hdr(void);
    121  1.35  christos static void	show_shmtotal(struct shminfo *);
    122  1.39     perry static void	usage(void) __dead;
    123  1.35  christos static void	unconfsem(void);
    124  1.35  christos static void	unconfmsg(void);
    125  1.35  christos static void	unconfshm(void);
    126  1.35  christos 
    127  1.35  christos static void
    128  1.35  christos unconfsem(void)
    129  1.35  christos {
    130  1.35  christos 	warnx("SVID semaphores facility not configured in the system");
    131  1.35  christos }
    132  1.35  christos 
    133  1.35  christos static void
    134  1.35  christos unconfmsg(void)
    135  1.35  christos {
    136  1.35  christos 	warnx("SVID messages facility not configured in the system");
    137  1.35  christos }
    138  1.35  christos 
    139  1.35  christos static void
    140  1.35  christos unconfshm(void)
    141  1.35  christos {
    142  1.35  christos 	warnx("SVID shared memory facility not configured in the system");
    143  1.35  christos }
    144   1.4       cgd 
    145  1.35  christos static char *
    146  1.23    simonb fmt_perm(u_short mode)
    147   1.1       cgd {
    148  1.17       mrg 	static char buffer[12];
    149   1.1       cgd 
    150   1.1       cgd 	buffer[0] = '-';
    151   1.1       cgd 	buffer[1] = '-';
    152   1.1       cgd 	buffer[2] = ((mode & 0400) ? 'r' : '-');
    153   1.1       cgd 	buffer[3] = ((mode & 0200) ? 'w' : '-');
    154   1.1       cgd 	buffer[4] = ((mode & 0100) ? 'a' : '-');
    155   1.1       cgd 	buffer[5] = ((mode & 0040) ? 'r' : '-');
    156   1.1       cgd 	buffer[6] = ((mode & 0020) ? 'w' : '-');
    157   1.1       cgd 	buffer[7] = ((mode & 0010) ? 'a' : '-');
    158   1.1       cgd 	buffer[8] = ((mode & 0004) ? 'r' : '-');
    159   1.1       cgd 	buffer[9] = ((mode & 0002) ? 'w' : '-');
    160   1.1       cgd 	buffer[10] = ((mode & 0001) ? 'a' : '-');
    161   1.1       cgd 	buffer[11] = '\0';
    162   1.1       cgd 	return (&buffer[0]);
    163   1.1       cgd }
    164   1.1       cgd 
    165  1.35  christos static void
    166  1.23    simonb cvt_time(time_t t, char *buf, size_t buflen)
    167   1.1       cgd {
    168   1.4       cgd 	struct tm *tm;
    169   1.1       cgd 
    170  1.30    itojun 	if (t == 0)
    171  1.30    itojun 		(void)strlcpy(buf, "no-entry", buflen);
    172  1.30    itojun 	else {
    173   1.4       cgd 		tm = localtime(&t);
    174  1.13       mrg 		(void)snprintf(buf, buflen, "%2d:%02d:%02d",
    175   1.4       cgd 			tm->tm_hour, tm->tm_min, tm->tm_sec);
    176   1.1       cgd 	}
    177   1.1       cgd }
    178   1.4       cgd int
    179  1.23    simonb main(int argc, char *argv[])
    180  1.23    simonb {
    181  1.23    simonb 	int i;
    182  1.34    simonb 	time_t now;
    183   1.4       cgd 
    184  1.14     lukem 	while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != -1)
    185   1.4       cgd 		switch (i) {
    186   1.4       cgd 		case 'M':
    187  1.32    simonb 			display |= SHMTOTAL;
    188   1.4       cgd 			break;
    189   1.4       cgd 		case 'm':
    190  1.32    simonb 			display |= SHMINFO;
    191   1.4       cgd 			break;
    192   1.4       cgd 		case 'Q':
    193  1.32    simonb 			display |= MSGTOTAL;
    194   1.4       cgd 			break;
    195   1.4       cgd 		case 'q':
    196  1.32    simonb 			display |= MSGINFO;
    197   1.4       cgd 			break;
    198   1.4       cgd 		case 'S':
    199  1.32    simonb 			display |= SEMTOTAL;
    200   1.4       cgd 			break;
    201   1.4       cgd 		case 's':
    202  1.32    simonb 			display |= SEMINFO;
    203   1.4       cgd 			break;
    204   1.4       cgd 		case 'T':
    205  1.32    simonb 			display |= SHMTOTAL | MSGTOTAL | SEMTOTAL;
    206   1.4       cgd 			break;
    207   1.4       cgd 		case 'a':
    208   1.4       cgd 			option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME;
    209   1.4       cgd 			break;
    210   1.4       cgd 		case 'b':
    211   1.4       cgd 			option |= BIGGEST;
    212   1.4       cgd 			break;
    213   1.4       cgd 		case 'C':
    214   1.4       cgd 			core = optarg;
    215   1.4       cgd 			break;
    216   1.4       cgd 		case 'c':
    217   1.4       cgd 			option |= CREATOR;
    218   1.4       cgd 			break;
    219   1.4       cgd 		case 'N':
    220   1.4       cgd 			namelist = optarg;
    221   1.4       cgd 			break;
    222   1.4       cgd 		case 'o':
    223   1.4       cgd 			option |= OUTSTANDING;
    224   1.4       cgd 			break;
    225   1.4       cgd 		case 'p':
    226   1.4       cgd 			option |= PID;
    227   1.4       cgd 			break;
    228   1.4       cgd 		case 't':
    229   1.4       cgd 			option |= TIME;
    230   1.4       cgd 			break;
    231   1.4       cgd 		default:
    232   1.5       cgd 			usage();
    233   1.4       cgd 		}
    234  1.11   thorpej 
    235  1.24    simonb 	if (argc - optind > 0)
    236  1.24    simonb 		usage();
    237  1.24    simonb 
    238  1.35  christos 	(void)time(&now);
    239  1.35  christos 	(void)printf("IPC status from %s as of %s\n",
    240  1.35  christos 	    /* and extra \n from ctime(3) */
    241  1.34    simonb 	    core == NULL ? "<running system>" : core, ctime(&now));
    242  1.34    simonb 
    243  1.32    simonb         if (display == 0)
    244  1.32    simonb 		display = SHMINFO | MSGINFO | SEMINFO;
    245  1.32    simonb 
    246  1.25    simonb 	if (core == NULL) {
    247  1.23    simonb 		if (display & (MSGINFO | MSGTOTAL))
    248  1.23    simonb 			msg_sysctl();
    249  1.23    simonb 		if (display & (SHMINFO | SHMTOTAL))
    250  1.23    simonb 			shm_sysctl();
    251  1.23    simonb 		if (display & (SEMINFO | SEMTOTAL))
    252  1.23    simonb 			sem_sysctl();
    253  1.23    simonb 	} else
    254  1.23    simonb 		ipcs_kvm();
    255  1.35  christos 	return 0;
    256  1.23    simonb }
    257  1.23    simonb 
    258  1.35  christos static void
    259  1.23    simonb show_msgtotal(struct msginfo *msginfo)
    260  1.23    simonb {
    261  1.35  christos 	(void)printf("msginfo:\n");
    262  1.35  christos 	(void)printf("\tmsgmax: %6d\t(max characters in a message)\n",
    263  1.23    simonb 	    msginfo->msgmax);
    264  1.35  christos 	(void)printf("\tmsgmni: %6d\t(# of message queues)\n",
    265  1.23    simonb 	    msginfo->msgmni);
    266  1.35  christos 	(void)printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
    267  1.23    simonb 	    msginfo->msgmnb);
    268  1.35  christos 	(void)printf("\tmsgtql: %6d\t(max # of messages in system)\n",
    269  1.23    simonb 	    msginfo->msgtql);
    270  1.35  christos 	(void)printf("\tmsgssz: %6d\t(size of a message segment)\n",
    271  1.23    simonb 	    msginfo->msgssz);
    272  1.35  christos 	(void)printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
    273  1.23    simonb 	    msginfo->msgseg);
    274  1.23    simonb }
    275  1.23    simonb 
    276  1.35  christos static void
    277  1.23    simonb show_shmtotal(struct shminfo *shminfo)
    278  1.23    simonb {
    279  1.35  christos 	(void)printf("shminfo:\n");
    280  1.40     rmind 	(void)printf("\tshmmax: %" PRIu64 "\t(max shared memory segment size)\n",
    281  1.23    simonb 	    shminfo->shmmax);
    282  1.35  christos 	(void)printf("\tshmmin: %7d\t(min shared memory segment size)\n",
    283  1.23    simonb 	    shminfo->shmmin);
    284  1.35  christos 	(void)printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n",
    285  1.23    simonb 	    shminfo->shmmni);
    286  1.35  christos 	(void)printf("\tshmseg: %7d\t(max shared memory segments per process)\n",
    287  1.23    simonb 	    shminfo->shmseg);
    288  1.35  christos 	(void)printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n",
    289  1.23    simonb 	    shminfo->shmall);
    290  1.23    simonb }
    291  1.23    simonb 
    292  1.35  christos static void
    293  1.23    simonb show_semtotal(struct seminfo *seminfo)
    294  1.23    simonb {
    295  1.35  christos 	(void)printf("seminfo:\n");
    296  1.35  christos 	(void)printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
    297  1.23    simonb 	    seminfo->semmap);
    298  1.35  christos 	(void)printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
    299  1.23    simonb 	    seminfo->semmni);
    300  1.35  christos 	(void)printf("\tsemmns: %6d\t(# of semaphores in system)\n",
    301  1.23    simonb 	    seminfo->semmns);
    302  1.35  christos 	(void)printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
    303  1.23    simonb 	    seminfo->semmnu);
    304  1.35  christos 	(void)printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
    305  1.23    simonb 	    seminfo->semmsl);
    306  1.35  christos 	(void)printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
    307  1.23    simonb 	    seminfo->semopm);
    308  1.35  christos 	(void)printf("\tsemume: %6d\t(max # of undo entries per process)\n",
    309  1.23    simonb 	    seminfo->semume);
    310  1.35  christos 	(void)printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
    311  1.23    simonb 	    seminfo->semusz);
    312  1.35  christos 	(void)printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
    313  1.23    simonb 	    seminfo->semvmx);
    314  1.35  christos 	(void)printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
    315  1.23    simonb 	    seminfo->semaem);
    316  1.23    simonb }
    317  1.23    simonb 
    318  1.35  christos static void
    319  1.23    simonb show_msginfo_hdr(void)
    320  1.23    simonb {
    321  1.35  christos 	(void)printf("Message Queues:\n");
    322  1.35  christos 	(void)printf("T        ID     KEY        MODE       OWNER    GROUP");
    323  1.23    simonb 	if (option & CREATOR)
    324  1.35  christos 		(void)printf("  CREATOR   CGROUP");
    325  1.23    simonb 	if (option & OUTSTANDING)
    326  1.35  christos 		(void)printf(" CBYTES  QNUM");
    327  1.23    simonb 	if (option & BIGGEST)
    328  1.35  christos 		(void)printf(" QBYTES");
    329  1.23    simonb 	if (option & PID)
    330  1.35  christos 		(void)printf(" LSPID LRPID");
    331  1.23    simonb 	if (option & TIME)
    332  1.35  christos 		(void)printf("    STIME    RTIME    CTIME");
    333  1.35  christos 	(void)printf("\n");
    334  1.23    simonb }
    335  1.23    simonb 
    336  1.35  christos static void
    337  1.35  christos show_msginfo(time_t s_time, time_t r_time, time_t c_time, int ipcid,
    338  1.35  christos     u_int64_t key,
    339  1.23    simonb     mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid,
    340  1.23    simonb     u_int64_t cbytes, u_int64_t qnum, u_int64_t qbytes, pid_t lspid,
    341  1.23    simonb     pid_t lrpid)
    342  1.23    simonb {
    343  1.35  christos 	char s_time_buf[100], r_time_buf[100], c_time_buf[100];
    344  1.23    simonb 
    345  1.23    simonb 	if (option & TIME) {
    346  1.35  christos 		cvt_time(s_time, s_time_buf, sizeof(s_time_buf));
    347  1.35  christos 		cvt_time(r_time, r_time_buf, sizeof(r_time_buf));
    348  1.35  christos 		cvt_time(c_time, c_time_buf, sizeof(c_time_buf));
    349  1.23    simonb 	}
    350  1.23    simonb 
    351  1.35  christos 	(void)printf("q %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode),
    352  1.23    simonb 	    user_from_uid(uid, 0), group_from_gid(gid, 0));
    353  1.23    simonb 
    354  1.23    simonb 	if (option & CREATOR)
    355  1.35  christos 		(void)printf(" %8s %8s", user_from_uid(cuid, 0),
    356  1.23    simonb 		    group_from_gid(cgid, 0));
    357  1.23    simonb 
    358  1.23    simonb 	if (option & OUTSTANDING)
    359  1.35  christos 		(void)printf(" %6lld %5lld", (long long)cbytes, (long long)qnum);
    360  1.23    simonb 
    361  1.23    simonb 	if (option & BIGGEST)
    362  1.35  christos 		(void)printf(" %6lld", (long long)qbytes);
    363  1.23    simonb 
    364  1.23    simonb 	if (option & PID)
    365  1.35  christos 		(void)printf(" %5d %5d", lspid, lrpid);
    366  1.23    simonb 
    367  1.23    simonb 	if (option & TIME)
    368  1.35  christos 		(void)printf(" %s %s %s", s_time_buf, r_time_buf, c_time_buf);
    369  1.23    simonb 
    370  1.35  christos 	(void)printf("\n");
    371  1.23    simonb }
    372  1.23    simonb 
    373  1.35  christos static void
    374  1.23    simonb show_shminfo_hdr(void)
    375  1.23    simonb {
    376  1.35  christos 	(void)printf("Shared Memory:\n");
    377  1.35  christos 	(void)printf("T        ID     KEY        MODE       OWNER    GROUP");
    378  1.23    simonb 	if (option & CREATOR)
    379  1.35  christos 		(void)printf("  CREATOR   CGROUP");
    380  1.23    simonb 	if (option & OUTSTANDING)
    381  1.35  christos 		(void)printf(" NATTCH");
    382  1.23    simonb 	if (option & BIGGEST)
    383  1.35  christos 		(void)printf("   SEGSZ");
    384  1.23    simonb 	if (option & PID)
    385  1.35  christos 		(void)printf("  CPID  LPID");
    386  1.23    simonb 	if (option & TIME)
    387  1.35  christos 		(void)printf("    ATIME    DTIME    CTIME");
    388  1.35  christos 	(void)printf("\n");
    389  1.23    simonb }
    390  1.23    simonb 
    391  1.35  christos static void
    392  1.35  christos show_shminfo(time_t atime, time_t dtime, time_t c_time, int ipcid, u_int64_t key,
    393  1.23    simonb     mode_t mode, uid_t uid, gid_t gid, uid_t cuid, gid_t cgid,
    394  1.23    simonb     u_int32_t nattch, u_int64_t segsz, pid_t cpid, pid_t lpid)
    395  1.23    simonb {
    396  1.35  christos 	char atime_buf[100], dtime_buf[100], c_time_buf[100];
    397  1.23    simonb 
    398  1.23    simonb 	if (option & TIME) {
    399  1.23    simonb 		cvt_time(atime, atime_buf, sizeof(atime_buf));
    400  1.23    simonb 		cvt_time(dtime, dtime_buf, sizeof(dtime_buf));
    401  1.35  christos 		cvt_time(c_time, c_time_buf, sizeof(c_time_buf));
    402  1.23    simonb 	}
    403  1.23    simonb 
    404  1.35  christos 	(void)printf("m %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode),
    405  1.23    simonb 	    user_from_uid(uid, 0), group_from_gid(gid, 0));
    406  1.23    simonb 
    407  1.23    simonb 	if (option & CREATOR)
    408  1.35  christos 		(void)printf(" %8s %8s", user_from_uid(cuid, 0),
    409  1.23    simonb 		    group_from_gid(cgid, 0));
    410  1.23    simonb 
    411  1.23    simonb 	if (option & OUTSTANDING)
    412  1.35  christos 		(void)printf(" %6d", nattch);
    413  1.23    simonb 
    414  1.23    simonb 	if (option & BIGGEST)
    415  1.35  christos 		(void)printf(" %7llu", (long long)segsz);
    416  1.23    simonb 
    417  1.23    simonb 	if (option & PID)
    418  1.35  christos 		(void)printf(" %5d %5d", cpid, lpid);
    419  1.23    simonb 
    420  1.23    simonb 	if (option & TIME)
    421  1.35  christos 		(void)printf(" %s %s %s",
    422  1.23    simonb 		    atime_buf,
    423  1.23    simonb 		    dtime_buf,
    424  1.35  christos 		    c_time_buf);
    425  1.23    simonb 
    426  1.35  christos 	(void)printf("\n");
    427  1.23    simonb }
    428  1.23    simonb 
    429  1.35  christos static void
    430  1.23    simonb show_seminfo_hdr(void)
    431  1.23    simonb {
    432  1.35  christos 	(void)printf("Semaphores:\n");
    433  1.35  christos 	(void)printf("T        ID     KEY        MODE       OWNER    GROUP");
    434  1.23    simonb 	if (option & CREATOR)
    435  1.35  christos 		(void)printf("  CREATOR   CGROUP");
    436  1.23    simonb 	if (option & BIGGEST)
    437  1.35  christos 		(void)printf(" NSEMS");
    438  1.23    simonb 	if (option & TIME)
    439  1.35  christos 		(void)printf("    OTIME    CTIME");
    440  1.35  christos 	(void)printf("\n");
    441  1.23    simonb }
    442  1.23    simonb 
    443  1.35  christos static void
    444  1.35  christos show_seminfo(time_t otime, time_t c_time, int ipcid, u_int64_t key, mode_t mode,
    445  1.23    simonb     uid_t uid, gid_t gid, uid_t cuid, gid_t cgid, int16_t nsems)
    446  1.23    simonb {
    447  1.35  christos 	char c_time_buf[100], otime_buf[100];
    448  1.23    simonb 
    449  1.23    simonb 	if (option & TIME) {
    450  1.23    simonb 		cvt_time(otime, otime_buf, sizeof(otime_buf));
    451  1.35  christos 		cvt_time(c_time, c_time_buf, sizeof(c_time_buf));
    452  1.23    simonb 	}
    453  1.23    simonb 
    454  1.35  christos 	(void)printf("s %9d %10lld %s %8s %8s", ipcid, (long long)key, fmt_perm(mode),
    455  1.23    simonb 	    user_from_uid(uid, 0), group_from_gid(gid, 0));
    456  1.23    simonb 
    457  1.23    simonb 	if (option & CREATOR)
    458  1.35  christos 		(void)printf(" %8s %8s", user_from_uid(cuid, 0),
    459  1.23    simonb 		    group_from_gid(cgid, 0));
    460  1.23    simonb 
    461  1.23    simonb 	if (option & BIGGEST)
    462  1.35  christos 		(void)printf(" %5d", nsems);
    463  1.23    simonb 
    464  1.23    simonb 	if (option & TIME)
    465  1.35  christos 		(void)printf(" %s %s", otime_buf, c_time_buf);
    466  1.23    simonb 
    467  1.35  christos 	(void)printf("\n");
    468  1.23    simonb }
    469  1.23    simonb 
    470  1.35  christos static void
    471  1.23    simonb msg_sysctl(void)
    472  1.23    simonb {
    473  1.23    simonb 	struct msg_sysctl_info *msgsi;
    474  1.35  christos 	void *buf;
    475  1.37  christos 	int mib[4];
    476  1.23    simonb 	size_t len;
    477  1.23    simonb 	int i, valid;
    478  1.23    simonb 
    479  1.23    simonb 	mib[0] = CTL_KERN;
    480  1.37  christos 	mib[1] = KERN_SYSVIPC;
    481  1.37  christos 	mib[2] = KERN_SYSVIPC_MSG;
    482  1.23    simonb 	len = sizeof(valid);
    483  1.37  christos 	if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) {
    484  1.37  christos 		warn("sysctl(KERN_SYSVIPC_MSG)");
    485  1.23    simonb 		return;
    486  1.23    simonb 	}
    487  1.23    simonb 	if (!valid) {
    488  1.35  christos 		unconfmsg();
    489  1.23    simonb 		return;
    490  1.23    simonb 	}
    491  1.23    simonb 
    492  1.23    simonb 	mib[0] = CTL_KERN;
    493  1.37  christos 	mib[1] = KERN_SYSVIPC;
    494  1.37  christos 	mib[2] = KERN_SYSVIPC_INFO;
    495  1.37  christos 	mib[3] = KERN_SYSVIPC_MSG_INFO;
    496  1.23    simonb 
    497  1.23    simonb 	if (!(display & MSGINFO)) {
    498  1.23    simonb 		/* totals only */
    499  1.23    simonb 		len = sizeof(struct msginfo);
    500  1.23    simonb 	} else {
    501  1.37  christos 		if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) {
    502  1.35  christos 			warn("sysctl(KERN_SYSVIPC_MSG_INFO)");
    503  1.23    simonb 			return;
    504  1.23    simonb 		}
    505  1.23    simonb 	}
    506  1.23    simonb 
    507  1.23    simonb 	if ((buf = malloc(len)) == NULL)
    508  1.23    simonb 		err(1, "malloc");
    509  1.23    simonb 	msgsi = (struct msg_sysctl_info *)buf;
    510  1.37  christos 	if (sysctl(mib, 4, msgsi, &len, NULL, 0) < 0) {
    511  1.35  christos 		warn("sysctl(KERN_SYSVIPC_MSG_INFO)");
    512  1.35  christos 		goto done;
    513  1.23    simonb 	}
    514  1.23    simonb 
    515  1.23    simonb 	if (display & MSGTOTAL)
    516  1.23    simonb 		show_msgtotal(&msgsi->msginfo);
    517  1.23    simonb 
    518  1.23    simonb 	if (display & MSGINFO) {
    519  1.23    simonb 		show_msginfo_hdr();
    520  1.23    simonb 		for (i = 0; i < msgsi->msginfo.msgmni; i++) {
    521  1.23    simonb 			struct msgid_ds_sysctl *msqptr = &msgsi->msgids[i];
    522  1.23    simonb 			if (msqptr->msg_qbytes != 0)
    523  1.23    simonb 				show_msginfo(msqptr->msg_stime,
    524  1.23    simonb 				    msqptr->msg_rtime,
    525  1.23    simonb 				    msqptr->msg_ctime,
    526  1.23    simonb 				    IXSEQ_TO_IPCID(i, msqptr->msg_perm),
    527  1.23    simonb 				    msqptr->msg_perm._key,
    528  1.23    simonb 				    msqptr->msg_perm.mode,
    529  1.23    simonb 				    msqptr->msg_perm.uid,
    530  1.23    simonb 				    msqptr->msg_perm.gid,
    531  1.23    simonb 				    msqptr->msg_perm.cuid,
    532  1.23    simonb 				    msqptr->msg_perm.cgid,
    533  1.23    simonb 				    msqptr->_msg_cbytes,
    534  1.23    simonb 				    msqptr->msg_qnum,
    535  1.23    simonb 				    msqptr->msg_qbytes,
    536  1.23    simonb 				    msqptr->msg_lspid,
    537  1.23    simonb 				    msqptr->msg_lrpid);
    538  1.23    simonb 		}
    539  1.35  christos 		(void)printf("\n");
    540  1.23    simonb 	}
    541  1.35  christos done:
    542  1.35  christos 	free(buf);
    543  1.23    simonb }
    544  1.23    simonb 
    545  1.35  christos static void
    546  1.23    simonb shm_sysctl(void)
    547  1.23    simonb {
    548  1.23    simonb 	struct shm_sysctl_info *shmsi;
    549  1.35  christos 	void *buf;
    550  1.37  christos 	int mib[4];
    551  1.23    simonb 	size_t len;
    552  1.23    simonb 	int i /*, valid */;
    553  1.23    simonb 	long valid;
    554  1.23    simonb 
    555  1.23    simonb 	mib[0] = CTL_KERN;
    556  1.37  christos 	mib[1] = KERN_SYSVIPC;
    557  1.37  christos 	mib[2] = KERN_SYSVIPC_SHM;
    558  1.23    simonb 	len = sizeof(valid);
    559  1.37  christos 	if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) {
    560  1.37  christos 		warn("sysctl(KERN_SYSVIPC_SHM)");
    561  1.23    simonb 		return;
    562  1.23    simonb 	}
    563  1.23    simonb 	if (!valid) {
    564  1.35  christos 		unconfshm();
    565  1.23    simonb 		return;
    566  1.23    simonb 	}
    567  1.23    simonb 
    568  1.23    simonb 	mib[0] = CTL_KERN;
    569  1.37  christos 	mib[1] = KERN_SYSVIPC;
    570  1.37  christos 	mib[2] = KERN_SYSVIPC_INFO;
    571  1.37  christos 	mib[3] = KERN_SYSVIPC_SHM_INFO;
    572  1.23    simonb 
    573  1.23    simonb 	if (!(display & SHMINFO)) {
    574  1.23    simonb 		/* totals only */
    575  1.23    simonb 		len = sizeof(struct shminfo);
    576  1.23    simonb 	} else {
    577  1.37  christos 		if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) {
    578  1.35  christos 			warn("sysctl(KERN_SYSVIPC_SHM_INFO)");
    579  1.23    simonb 			return;
    580  1.23    simonb 		}
    581  1.23    simonb 	}
    582  1.23    simonb 
    583  1.23    simonb 	if ((buf = malloc(len)) == NULL)
    584  1.23    simonb 		err(1, "malloc");
    585  1.23    simonb 	shmsi = (struct shm_sysctl_info *)buf;
    586  1.37  christos 	if (sysctl(mib, 4, shmsi, &len, NULL, 0) < 0) {
    587  1.35  christos 		warn("sysctl(KERN_SYSVIPC_SHM_INFO)");
    588  1.35  christos 		goto done;
    589  1.23    simonb 	}
    590  1.23    simonb 
    591  1.23    simonb 	if (display & SHMTOTAL)
    592  1.23    simonb 		show_shmtotal(&shmsi->shminfo);
    593  1.23    simonb 
    594  1.23    simonb 	if (display & SHMINFO) {
    595  1.23    simonb 		show_shminfo_hdr();
    596  1.23    simonb 		for (i = 0; i < shmsi->shminfo.shmmni; i++) {
    597  1.23    simonb 			struct shmid_ds_sysctl *shmptr = &shmsi->shmids[i];
    598  1.23    simonb 			if (shmptr->shm_perm.mode & 0x0800)
    599  1.23    simonb 				show_shminfo(shmptr->shm_atime,
    600  1.23    simonb 				    shmptr->shm_dtime,
    601  1.23    simonb 				    shmptr->shm_ctime,
    602  1.23    simonb 				    IXSEQ_TO_IPCID(i, shmptr->shm_perm),
    603  1.23    simonb 				    shmptr->shm_perm._key,
    604  1.23    simonb 				    shmptr->shm_perm.mode,
    605  1.23    simonb 				    shmptr->shm_perm.uid,
    606  1.23    simonb 				    shmptr->shm_perm.gid,
    607  1.23    simonb 				    shmptr->shm_perm.cuid,
    608  1.23    simonb 				    shmptr->shm_perm.cgid,
    609  1.23    simonb 				    shmptr->shm_nattch,
    610  1.23    simonb 				    shmptr->shm_segsz,
    611  1.23    simonb 				    shmptr->shm_cpid,
    612  1.23    simonb 				    shmptr->shm_lpid);
    613  1.23    simonb 		}
    614  1.35  christos 		(void)printf("\n");
    615  1.23    simonb 	}
    616  1.35  christos done:
    617  1.35  christos 	free(buf);
    618  1.23    simonb }
    619  1.23    simonb 
    620  1.35  christos static void
    621  1.23    simonb sem_sysctl(void)
    622  1.23    simonb {
    623  1.23    simonb 	struct sem_sysctl_info *semsi;
    624  1.35  christos 	void *buf;
    625  1.37  christos 	int mib[4];
    626  1.23    simonb 	size_t len;
    627  1.23    simonb 	int i, valid;
    628  1.23    simonb 
    629  1.23    simonb 	mib[0] = CTL_KERN;
    630  1.37  christos 	mib[1] = KERN_SYSVIPC;
    631  1.37  christos 	mib[2] = KERN_SYSVIPC_SEM;
    632  1.23    simonb 	len = sizeof(valid);
    633  1.37  christos 	if (sysctl(mib, 3, &valid, &len, NULL, 0) < 0) {
    634  1.37  christos 		warn("sysctl(KERN_SYSVIPC_SEM)");
    635  1.23    simonb 		return;
    636  1.23    simonb 	}
    637  1.23    simonb 	if (!valid) {
    638  1.35  christos 		unconfsem();
    639  1.23    simonb 		return;
    640  1.23    simonb 	}
    641  1.23    simonb 
    642  1.23    simonb 	mib[0] = CTL_KERN;
    643  1.37  christos 	mib[1] = KERN_SYSVIPC;
    644  1.37  christos 	mib[2] = KERN_SYSVIPC_INFO;
    645  1.37  christos 	mib[3] = KERN_SYSVIPC_SEM_INFO;
    646  1.23    simonb 
    647  1.23    simonb 	if (!(display & SEMINFO)) {
    648  1.23    simonb 		/* totals only */
    649  1.23    simonb 		len = sizeof(struct seminfo);
    650  1.23    simonb 	} else {
    651  1.37  christos 		if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) {
    652  1.35  christos 			warn("sysctl(KERN_SYSVIPC_SEM_INFO)");
    653  1.23    simonb 			return;
    654  1.23    simonb 		}
    655  1.23    simonb 	}
    656  1.23    simonb 
    657  1.23    simonb 	if ((buf = malloc(len)) == NULL)
    658  1.23    simonb 		err(1, "malloc");
    659  1.23    simonb 	semsi = (struct sem_sysctl_info *)buf;
    660  1.37  christos 	if (sysctl(mib, 4, semsi, &len, NULL, 0) < 0) {
    661  1.35  christos 		warn("sysctl(KERN_SYSVIPC_SEM_INFO)");
    662  1.35  christos 		goto done;
    663  1.23    simonb 	}
    664  1.23    simonb 
    665  1.23    simonb 	if (display & SEMTOTAL)
    666  1.23    simonb 		show_semtotal(&semsi->seminfo);
    667  1.23    simonb 
    668  1.23    simonb 	if (display & SEMINFO) {
    669  1.23    simonb 		show_seminfo_hdr();
    670  1.23    simonb 		for (i = 0; i < semsi->seminfo.semmni; i++) {
    671  1.23    simonb 			struct semid_ds_sysctl *semaptr = &semsi->semids[i];
    672  1.23    simonb 			if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0)
    673  1.23    simonb 				show_seminfo(semaptr->sem_otime,
    674  1.23    simonb 				    semaptr->sem_ctime,
    675  1.23    simonb 				    IXSEQ_TO_IPCID(i, semaptr->sem_perm),
    676  1.23    simonb 				    semaptr->sem_perm._key,
    677  1.23    simonb 				    semaptr->sem_perm.mode,
    678  1.23    simonb 				    semaptr->sem_perm.uid,
    679  1.23    simonb 				    semaptr->sem_perm.gid,
    680  1.23    simonb 				    semaptr->sem_perm.cuid,
    681  1.23    simonb 				    semaptr->sem_perm.cgid,
    682  1.23    simonb 				    semaptr->sem_nsems);
    683  1.23    simonb 		}
    684  1.35  christos 		(void)printf("\n");
    685  1.23    simonb 	}
    686  1.35  christos done:
    687  1.35  christos 	free(buf);
    688  1.23    simonb }
    689  1.23    simonb 
    690  1.36  christos static struct nlist symbols[] = {
    691  1.36  christos 	{ .n_name = "_sema" },
    692  1.36  christos #define X_SEMA		0
    693  1.36  christos 	{ .n_name = "_seminfo" },
    694  1.36  christos #define X_SEMINFO	1
    695  1.36  christos 	{ .n_name = "_semu" },
    696  1.36  christos #define X_SEMU		2
    697  1.36  christos 	{ .n_name = "_msginfo" },
    698  1.36  christos #define X_MSGINFO	3
    699  1.36  christos 	{ .n_name = "_msqids" },
    700  1.36  christos #define X_MSQIDS	4
    701  1.36  christos 	{ .n_name = "_shminfo" },
    702  1.36  christos #define X_SHMINFO	5
    703  1.36  christos 	{ .n_name = "_shmsegs" },
    704  1.36  christos #define X_SHMSEGS	6
    705  1.36  christos 	{ .n_name = NULL }
    706  1.36  christos };
    707  1.36  christos 
    708  1.35  christos static void
    709  1.23    simonb ipcs_kvm(void)
    710  1.23    simonb {
    711  1.23    simonb 	struct msginfo msginfo;
    712  1.23    simonb 	struct msqid_ds *msqids;
    713  1.23    simonb 	struct seminfo seminfo;
    714  1.23    simonb 	struct semid_ds *sema;
    715  1.23    simonb 	struct shminfo shminfo;
    716  1.23    simonb 	struct shmid_ds *shmsegs;
    717  1.23    simonb 	kvm_t *kd;
    718  1.23    simonb 	char errbuf[_POSIX2_LINE_MAX];
    719  1.23    simonb 	int i;
    720  1.11   thorpej 
    721  1.11   thorpej 	if ((kd = kvm_openfiles(namelist, core, NULL, O_RDONLY,
    722  1.11   thorpej 	    errbuf)) == NULL)
    723  1.11   thorpej 		errx(1, "can't open kvm: %s", errbuf);
    724  1.16       mrg 
    725   1.1       cgd 
    726   1.4       cgd 	switch (kvm_nlist(kd, symbols)) {
    727   1.1       cgd 	case 0:
    728   1.1       cgd 		break;
    729   1.1       cgd 	case -1:
    730  1.11   thorpej 		errx(1, "%s: unable to read symbol table.",
    731  1.11   thorpej 		    namelist == NULL ? _PATH_UNIX : namelist);
    732  1.23    simonb 		/* NOTREACHED */
    733   1.1       cgd 	default:
    734   1.5       cgd #ifdef notdef		/* they'll be told more civilly later */
    735   1.5       cgd 		warnx("nlist failed");
    736   1.5       cgd 		for (i = 0; symbols[i].n_name != NULL; i++)
    737   1.5       cgd 			if (symbols[i].n_value == 0)
    738   1.5       cgd 				warnx("symbol %s not found",
    739   1.5       cgd 				    symbols[i].n_name);
    740  1.23    simonb #endif
    741   1.1       cgd 		break;
    742   1.1       cgd 	}
    743   1.1       cgd 
    744   1.4       cgd 	if ((display & (MSGINFO | MSGTOTAL)) &&
    745  1.11   thorpej 	    (kvm_read(kd, symbols[X_MSGINFO].n_value,
    746  1.11   thorpej 	     &msginfo, sizeof(msginfo)) == sizeof(msginfo))) {
    747   1.1       cgd 
    748  1.23    simonb 		if (display & MSGTOTAL)
    749  1.23    simonb 			show_msgtotal(&msginfo);
    750  1.23    simonb 
    751   1.4       cgd 		if (display & MSGINFO) {
    752   1.4       cgd 			struct msqid_ds *xmsqids;
    753   1.1       cgd 
    754  1.11   thorpej 			if (kvm_read(kd, symbols[X_MSQIDS].n_value,
    755  1.11   thorpej 			    &msqids, sizeof(msqids)) != sizeof(msqids))
    756  1.11   thorpej 				errx(1, "kvm_read (%s): %s",
    757  1.11   thorpej 				    symbols[X_MSQIDS].n_name, kvm_geterr(kd));
    758  1.11   thorpej 
    759  1.11   thorpej 			xmsqids = malloc(sizeof(struct msqid_ds) *
    760  1.11   thorpej 			    msginfo.msgmni);
    761  1.11   thorpej 
    762  1.11   thorpej 			if (kvm_read(kd, (u_long)msqids, xmsqids,
    763  1.11   thorpej 			    sizeof(struct msqid_ds) * msginfo.msgmni) !=
    764  1.11   thorpej 			    sizeof(struct msqid_ds) * msginfo.msgmni)
    765  1.11   thorpej 				errx(1, "kvm_read (msqids): %s",
    766  1.11   thorpej 				    kvm_geterr(kd));
    767   1.4       cgd 
    768  1.23    simonb 			show_msginfo_hdr();
    769  1.23    simonb 			for (i = 0; i < msginfo.msgmni; i++) {
    770  1.23    simonb 				struct msqid_ds *msqptr = &xmsqids[i];
    771  1.23    simonb 				if (msqptr->msg_qbytes != 0)
    772  1.23    simonb 					show_msginfo(msqptr->msg_stime,
    773  1.23    simonb 					    msqptr->msg_rtime,
    774  1.23    simonb 					    msqptr->msg_ctime,
    775   1.4       cgd 					    IXSEQ_TO_IPCID(i, msqptr->msg_perm),
    776  1.35  christos 					    (u_int64_t)msqptr->msg_perm._key,
    777  1.23    simonb 					    msqptr->msg_perm.mode,
    778  1.23    simonb 					    msqptr->msg_perm.uid,
    779  1.23    simonb 					    msqptr->msg_perm.gid,
    780  1.23    simonb 					    msqptr->msg_perm.cuid,
    781  1.23    simonb 					    msqptr->msg_perm.cgid,
    782  1.35  christos 					    (u_int64_t)msqptr->_msg_cbytes,
    783  1.35  christos 					    (u_int64_t)msqptr->msg_qnum,
    784  1.35  christos 					    (u_int64_t)msqptr->msg_qbytes,
    785  1.23    simonb 					    msqptr->msg_lspid,
    786  1.23    simonb 					    msqptr->msg_lrpid);
    787   1.4       cgd 			}
    788  1.35  christos 			(void)printf("\n");
    789  1.35  christos 			free(xmsqids);
    790   1.4       cgd 		}
    791   1.4       cgd 	} else
    792  1.35  christos 		if (display & (MSGINFO | MSGTOTAL))
    793  1.35  christos 			unconfmsg();
    794   1.4       cgd 	if ((display & (SHMINFO | SHMTOTAL)) &&
    795  1.11   thorpej 	    (kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo,
    796  1.11   thorpej 	     sizeof(shminfo)) == sizeof(shminfo))) {
    797  1.11   thorpej 
    798  1.23    simonb 		if (display & SHMTOTAL)
    799  1.23    simonb 			show_shmtotal(&shminfo);
    800  1.23    simonb 
    801   1.4       cgd 		if (display & SHMINFO) {
    802   1.4       cgd 			struct shmid_ds *xshmids;
    803   1.1       cgd 
    804  1.11   thorpej 			if (kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs,
    805  1.11   thorpej 			    sizeof(shmsegs)) != sizeof(shmsegs))
    806  1.11   thorpej 				errx(1, "kvm_read (%s): %s",
    807  1.11   thorpej 				    symbols[X_SHMSEGS].n_name, kvm_geterr(kd));
    808  1.11   thorpej 
    809  1.11   thorpej 			xshmids = malloc(sizeof(struct shmid_ds) *
    810  1.12  explorer 			    shminfo.shmmni);
    811  1.11   thorpej 
    812  1.11   thorpej 			if (kvm_read(kd, (u_long)shmsegs, xshmids,
    813  1.11   thorpej 			    sizeof(struct shmid_ds) * shminfo.shmmni) !=
    814  1.11   thorpej 			    sizeof(struct shmid_ds) * shminfo.shmmni)
    815  1.11   thorpej 				errx(1, "kvm_read (shmsegs): %s",
    816  1.11   thorpej 				    kvm_geterr(kd));
    817   1.4       cgd 
    818  1.23    simonb 			show_shminfo_hdr();
    819  1.23    simonb 			for (i = 0; i < shminfo.shmmni; i++) {
    820  1.23    simonb 				struct shmid_ds *shmptr = &xshmids[i];
    821  1.23    simonb 				if (shmptr->shm_perm.mode & 0x0800)
    822  1.23    simonb 					show_shminfo(shmptr->shm_atime,
    823  1.23    simonb 					    shmptr->shm_dtime,
    824  1.23    simonb 					    shmptr->shm_ctime,
    825   1.4       cgd 					    IXSEQ_TO_IPCID(i, shmptr->shm_perm),
    826  1.35  christos 					    (u_int64_t)shmptr->shm_perm._key,
    827  1.23    simonb 					    shmptr->shm_perm.mode,
    828  1.23    simonb 					    shmptr->shm_perm.uid,
    829  1.23    simonb 					    shmptr->shm_perm.gid,
    830  1.23    simonb 					    shmptr->shm_perm.cuid,
    831  1.23    simonb 					    shmptr->shm_perm.cgid,
    832  1.23    simonb 					    shmptr->shm_nattch,
    833  1.35  christos 					    (u_int64_t)shmptr->shm_segsz,
    834  1.23    simonb 					    shmptr->shm_cpid,
    835  1.23    simonb 					    shmptr->shm_lpid);
    836   1.1       cgd 			}
    837  1.35  christos 			(void)printf("\n");
    838  1.35  christos 			free(xshmids);
    839   1.4       cgd 		}
    840   1.4       cgd 	} else
    841  1.35  christos 		if (display & (SHMINFO | SHMTOTAL))
    842  1.35  christos 			unconfshm();
    843   1.4       cgd 	if ((display & (SEMINFO | SEMTOTAL)) &&
    844  1.11   thorpej 	    (kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo,
    845  1.11   thorpej 	     sizeof(seminfo)) == sizeof(seminfo))) {
    846   1.4       cgd 		struct semid_ds *xsema;
    847   1.1       cgd 
    848  1.23    simonb 		if (display & SEMTOTAL)
    849  1.23    simonb 			show_semtotal(&seminfo);
    850  1.23    simonb 
    851   1.4       cgd 		if (display & SEMINFO) {
    852  1.11   thorpej 			if (kvm_read(kd, symbols[X_SEMA].n_value, &sema,
    853  1.11   thorpej 			    sizeof(sema)) != sizeof(sema))
    854  1.11   thorpej 				errx(1, "kvm_read (%s): %s",
    855  1.11   thorpej 				    symbols[X_SEMA].n_name, kvm_geterr(kd));
    856  1.11   thorpej 
    857  1.11   thorpej 			xsema = malloc(sizeof(struct semid_ds) *
    858  1.11   thorpej 			    seminfo.semmni);
    859  1.11   thorpej 
    860  1.11   thorpej 			if (kvm_read(kd, (u_long)sema, xsema,
    861  1.11   thorpej 			    sizeof(struct semid_ds) * seminfo.semmni) !=
    862  1.11   thorpej 			    sizeof(struct semid_ds) * seminfo.semmni)
    863  1.11   thorpej 				errx(1, "kvm_read (sema): %s",
    864  1.11   thorpej 				    kvm_geterr(kd));
    865   1.4       cgd 
    866  1.23    simonb 			show_seminfo_hdr();
    867  1.23    simonb 			for (i = 0; i < seminfo.semmni; i++) {
    868  1.23    simonb 				struct semid_ds *semaptr = &xsema[i];
    869  1.23    simonb 				if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0)
    870  1.23    simonb 					show_seminfo(semaptr->sem_otime,
    871  1.23    simonb 					    semaptr->sem_ctime,
    872   1.4       cgd 					    IXSEQ_TO_IPCID(i, semaptr->sem_perm),
    873  1.35  christos 					    (u_int64_t)semaptr->sem_perm._key,
    874  1.23    simonb 					    semaptr->sem_perm.mode,
    875  1.23    simonb 					    semaptr->sem_perm.uid,
    876  1.23    simonb 					    semaptr->sem_perm.gid,
    877  1.23    simonb 					    semaptr->sem_perm.cuid,
    878  1.23    simonb 					    semaptr->sem_perm.cgid,
    879  1.23    simonb 					    semaptr->sem_nsems);
    880   1.4       cgd 			}
    881   1.1       cgd 
    882  1.35  christos 			(void)printf("\n");
    883  1.35  christos 			free(xsema);
    884   1.4       cgd 		}
    885   1.4       cgd 	} else
    886  1.35  christos 		if (display & (SEMINFO | SEMTOTAL))
    887  1.35  christos 			unconfsem();
    888  1.35  christos 	(void)kvm_close(kd);
    889   1.5       cgd }
    890   1.5       cgd 
    891  1.35  christos static void
    892  1.23    simonb usage(void)
    893   1.5       cgd {
    894   1.5       cgd 
    895  1.35  christos 	(void)fprintf(stderr,
    896  1.35  christos 	    "Usage: %s [-abcmopqstMQST] [-C corefile] [-N namelist]\n",
    897  1.26       cgd 	    getprogname());
    898   1.5       cgd 	exit(1);
    899   1.1       cgd }
    900