xref: /freebsd/usr.bin/ipcs/ipcs.c (revision 49fbc2ac8732948646fa4eef037a48a409b383a6)
14816f94eSDoug Rabson /*
249fbc2acSDoug Rabson  * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
349fbc2acSDoug Rabson  * All rights reserved.
449fbc2acSDoug Rabson  *
549fbc2acSDoug Rabson  * Redistribution and use in source and binary forms, with or without
649fbc2acSDoug Rabson  * modification, are permitted provided that the following conditions
749fbc2acSDoug Rabson  * are met:
849fbc2acSDoug Rabson  * 1. Redistributions of source code must retain the above copyright
949fbc2acSDoug Rabson  *    notice, this list of conditions and the following disclaimer.
1049fbc2acSDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
1149fbc2acSDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
1249fbc2acSDoug Rabson  *    documentation and/or other materials provided with the distribution.
1349fbc2acSDoug Rabson  * 3. The name of the author may not be used to endorse or promote products
1449fbc2acSDoug Rabson  *    derived from this software without specific prior written permission.
1549fbc2acSDoug Rabson  *
1649fbc2acSDoug Rabson  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1749fbc2acSDoug Rabson  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1849fbc2acSDoug Rabson  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
1949fbc2acSDoug Rabson  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2049fbc2acSDoug Rabson  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2149fbc2acSDoug Rabson  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2249fbc2acSDoug Rabson  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2349fbc2acSDoug Rabson  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2449fbc2acSDoug Rabson  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2549fbc2acSDoug Rabson  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2649fbc2acSDoug Rabson  *
2749fbc2acSDoug Rabson  *	$Id: ipcs.c,v 1.6 1994/06/18 22:05:08 cgd Exp $
284816f94eSDoug Rabson  */
294816f94eSDoug Rabson 
304816f94eSDoug Rabson #include <stdio.h>
314816f94eSDoug Rabson #include <stdlib.h>
324816f94eSDoug Rabson #include <unistd.h>
3349fbc2acSDoug Rabson #include <fcntl.h>
344816f94eSDoug Rabson #include <paths.h>
3549fbc2acSDoug Rabson #include <nlist.h>
3649fbc2acSDoug Rabson #include <kvm.h>
3749fbc2acSDoug Rabson #include <err.h>
384816f94eSDoug Rabson 
394816f94eSDoug Rabson #include <sys/types.h>
404816f94eSDoug Rabson #include <sys/param.h>
4149fbc2acSDoug Rabson #include <sys/time.h>
424816f94eSDoug Rabson #include <sys/proc.h>
434816f94eSDoug Rabson #define KERNEL
444816f94eSDoug Rabson #include <sys/ipc.h>
454816f94eSDoug Rabson #include <sys/sem.h>
464816f94eSDoug Rabson #include <sys/shm.h>
474816f94eSDoug Rabson #include <sys/msg.h>
484816f94eSDoug Rabson 
4949fbc2acSDoug Rabson int	semconfig __P((int,...));
5049fbc2acSDoug Rabson void	usage __P((void));
514816f94eSDoug Rabson 
5249fbc2acSDoug Rabson static struct nlist symbols[] = {
5349fbc2acSDoug Rabson 	{"_sema"},
5449fbc2acSDoug Rabson #define X_SEMA		0
5549fbc2acSDoug Rabson 	{"_seminfo"},
5649fbc2acSDoug Rabson #define X_SEMINFO	1
5749fbc2acSDoug Rabson 	{"_semu"},
5849fbc2acSDoug Rabson #define X_SEMU		2
5949fbc2acSDoug Rabson 	{"_msginfo"},
6049fbc2acSDoug Rabson #define X_MSGINFO	3
6149fbc2acSDoug Rabson 	{"_msqids"},
6249fbc2acSDoug Rabson #define X_MSQIDS	4
6349fbc2acSDoug Rabson 	{"_shminfo"},
6449fbc2acSDoug Rabson #define X_SHMINFO	5
6549fbc2acSDoug Rabson 	{"_shmsegs"},
6649fbc2acSDoug Rabson #define X_SHMSEGS	6
6749fbc2acSDoug Rabson 	{NULL}
6849fbc2acSDoug Rabson };
694816f94eSDoug Rabson 
7049fbc2acSDoug Rabson static kvm_t *kd;
714816f94eSDoug Rabson 
724816f94eSDoug Rabson char   *
7349fbc2acSDoug Rabson fmt_perm(mode)
7449fbc2acSDoug Rabson 	u_short mode;
754816f94eSDoug Rabson {
764816f94eSDoug Rabson 	static char buffer[100];
774816f94eSDoug Rabson 
784816f94eSDoug Rabson 	buffer[0] = '-';
794816f94eSDoug Rabson 	buffer[1] = '-';
804816f94eSDoug Rabson 	buffer[2] = ((mode & 0400) ? 'r' : '-');
814816f94eSDoug Rabson 	buffer[3] = ((mode & 0200) ? 'w' : '-');
824816f94eSDoug Rabson 	buffer[4] = ((mode & 0100) ? 'a' : '-');
834816f94eSDoug Rabson 	buffer[5] = ((mode & 0040) ? 'r' : '-');
844816f94eSDoug Rabson 	buffer[6] = ((mode & 0020) ? 'w' : '-');
854816f94eSDoug Rabson 	buffer[7] = ((mode & 0010) ? 'a' : '-');
864816f94eSDoug Rabson 	buffer[8] = ((mode & 0004) ? 'r' : '-');
874816f94eSDoug Rabson 	buffer[9] = ((mode & 0002) ? 'w' : '-');
884816f94eSDoug Rabson 	buffer[10] = ((mode & 0001) ? 'a' : '-');
894816f94eSDoug Rabson 	buffer[11] = '\0';
904816f94eSDoug Rabson 	return (&buffer[0]);
914816f94eSDoug Rabson }
924816f94eSDoug Rabson 
934816f94eSDoug Rabson void
9449fbc2acSDoug Rabson cvt_time(t, buf)
9549fbc2acSDoug Rabson 	time_t  t;
9649fbc2acSDoug Rabson 	char   *buf;
974816f94eSDoug Rabson {
9849fbc2acSDoug Rabson 	struct tm *tm;
9949fbc2acSDoug Rabson 
1004816f94eSDoug Rabson 	if (t == 0) {
10149fbc2acSDoug Rabson 		strcpy(buf, "no-entry");
1024816f94eSDoug Rabson 	} else {
10349fbc2acSDoug Rabson 		tm = localtime(&t);
10449fbc2acSDoug Rabson 		sprintf(buf, "%2d:%02d:%02d",
10549fbc2acSDoug Rabson 			tm->tm_hour, tm->tm_min, tm->tm_sec);
1064816f94eSDoug Rabson 	}
1074816f94eSDoug Rabson }
10849fbc2acSDoug Rabson #define	SHMINFO		1
10949fbc2acSDoug Rabson #define	SHMTOTAL	2
11049fbc2acSDoug Rabson #define	MSGINFO		4
11149fbc2acSDoug Rabson #define	MSGTOTAL	8
11249fbc2acSDoug Rabson #define	SEMINFO		16
11349fbc2acSDoug Rabson #define	SEMTOTAL	32
1144816f94eSDoug Rabson 
11549fbc2acSDoug Rabson #define BIGGEST		1
11649fbc2acSDoug Rabson #define CREATOR		2
11749fbc2acSDoug Rabson #define OUTSTANDING	4
11849fbc2acSDoug Rabson #define PID		8
11949fbc2acSDoug Rabson #define TIME		16
12049fbc2acSDoug Rabson 
12149fbc2acSDoug Rabson int
12249fbc2acSDoug Rabson main(argc, argv)
12349fbc2acSDoug Rabson 	int     argc;
12449fbc2acSDoug Rabson 	char   *argv[];
1254816f94eSDoug Rabson {
12649fbc2acSDoug Rabson 	int     display = SHMINFO | MSGINFO | SEMINFO;
12749fbc2acSDoug Rabson 	int     option = 0;
12849fbc2acSDoug Rabson 	char   *core = NULL, *namelist = NULL;
1294816f94eSDoug Rabson 	int     i;
1304816f94eSDoug Rabson 
13149fbc2acSDoug Rabson 	while ((i = getopt(argc, argv, "MmQqSsabC:cN:optT")) != EOF)
13249fbc2acSDoug Rabson 		switch (i) {
13349fbc2acSDoug Rabson 		case 'M':
13449fbc2acSDoug Rabson 			display = SHMTOTAL;
13549fbc2acSDoug Rabson 			break;
13649fbc2acSDoug Rabson 		case 'm':
13749fbc2acSDoug Rabson 			display = SHMINFO;
13849fbc2acSDoug Rabson 			break;
13949fbc2acSDoug Rabson 		case 'Q':
14049fbc2acSDoug Rabson 			display = MSGTOTAL;
14149fbc2acSDoug Rabson 			break;
14249fbc2acSDoug Rabson 		case 'q':
14349fbc2acSDoug Rabson 			display = MSGINFO;
14449fbc2acSDoug Rabson 			break;
14549fbc2acSDoug Rabson 		case 'S':
14649fbc2acSDoug Rabson 			display = SEMTOTAL;
14749fbc2acSDoug Rabson 			break;
14849fbc2acSDoug Rabson 		case 's':
14949fbc2acSDoug Rabson 			display = SEMINFO;
15049fbc2acSDoug Rabson 			break;
15149fbc2acSDoug Rabson 		case 'T':
15249fbc2acSDoug Rabson 			display = SHMTOTAL | MSGTOTAL | SEMTOTAL;
15349fbc2acSDoug Rabson 			break;
15449fbc2acSDoug Rabson 		case 'a':
15549fbc2acSDoug Rabson 			option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME;
15649fbc2acSDoug Rabson 			break;
15749fbc2acSDoug Rabson 		case 'b':
15849fbc2acSDoug Rabson 			option |= BIGGEST;
15949fbc2acSDoug Rabson 			break;
16049fbc2acSDoug Rabson 		case 'C':
16149fbc2acSDoug Rabson 			core = optarg;
16249fbc2acSDoug Rabson 			break;
16349fbc2acSDoug Rabson 		case 'c':
16449fbc2acSDoug Rabson 			option |= CREATOR;
16549fbc2acSDoug Rabson 			break;
16649fbc2acSDoug Rabson 		case 'N':
16749fbc2acSDoug Rabson 			namelist = optarg;
16849fbc2acSDoug Rabson 			break;
16949fbc2acSDoug Rabson 		case 'o':
17049fbc2acSDoug Rabson 			option |= OUTSTANDING;
17149fbc2acSDoug Rabson 			break;
17249fbc2acSDoug Rabson 		case 'p':
17349fbc2acSDoug Rabson 			option |= PID;
17449fbc2acSDoug Rabson 			break;
17549fbc2acSDoug Rabson 		case 't':
17649fbc2acSDoug Rabson 			option |= TIME;
17749fbc2acSDoug Rabson 			break;
1784816f94eSDoug Rabson 		default:
17949fbc2acSDoug Rabson 			usage();
1804816f94eSDoug Rabson 		}
18149fbc2acSDoug Rabson 	if ((kd = kvm_open(namelist, core, NULL, O_RDONLY, "ipcs")) == NULL)
18249fbc2acSDoug Rabson 		exit(1);
18349fbc2acSDoug Rabson 
18449fbc2acSDoug Rabson 	switch (kvm_nlist(kd, symbols)) {
18549fbc2acSDoug Rabson 	case 0:
1864816f94eSDoug Rabson 		break;
18749fbc2acSDoug Rabson 	case -1:
18849fbc2acSDoug Rabson 		errx(1, "unable to read kernel symbol table.");
18949fbc2acSDoug Rabson 	default:
19049fbc2acSDoug Rabson #ifdef notdef		/* they'll be told more civilly later */
19149fbc2acSDoug Rabson 		warnx("nlist failed");
19249fbc2acSDoug Rabson 		for (i = 0; symbols[i].n_name != NULL; i++)
19349fbc2acSDoug Rabson 			if (symbols[i].n_value == 0)
19449fbc2acSDoug Rabson 				warnx("symbol %s not found",
19549fbc2acSDoug Rabson 				    symbols[i].n_name);
1964816f94eSDoug Rabson 		break;
19749fbc2acSDoug Rabson #endif
1984816f94eSDoug Rabson 	}
1994816f94eSDoug Rabson 
20049fbc2acSDoug Rabson 	if ((display & (MSGINFO | MSGTOTAL)) &&
20149fbc2acSDoug Rabson 	    kvm_read(kd, symbols[X_MSGINFO].n_value, &msginfo, sizeof(msginfo))) {
2024816f94eSDoug Rabson 
20349fbc2acSDoug Rabson 		if (display & MSGTOTAL) {
20449fbc2acSDoug Rabson 			printf("msginfo:\n");
20549fbc2acSDoug Rabson 			printf("\tmsgmax: %6d\t(max characters in a message)\n",
20649fbc2acSDoug Rabson 			    msginfo.msgmax);
20749fbc2acSDoug Rabson 			printf("\tmsgmni: %6d\t(# of message queues)\n",
20849fbc2acSDoug Rabson 			    msginfo.msgmni);
20949fbc2acSDoug Rabson 			printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",
21049fbc2acSDoug Rabson 			    msginfo.msgmnb);
21149fbc2acSDoug Rabson 			printf("\tmsgtql: %6d\t(max # of messages in system)\n",
21249fbc2acSDoug Rabson 			    msginfo.msgtql);
21349fbc2acSDoug Rabson 			printf("\tmsgssz: %6d\t(size of a message segment)\n",
21449fbc2acSDoug Rabson 			    msginfo.msgssz);
21549fbc2acSDoug Rabson 			printf("\tmsgseg: %6d\t(# of message segments in system)\n\n",
21649fbc2acSDoug Rabson 			    msginfo.msgseg);
2174816f94eSDoug Rabson 		}
21849fbc2acSDoug Rabson 		if (display & MSGINFO) {
2194816f94eSDoug Rabson 			struct msqid_ds *xmsqids;
2204816f94eSDoug Rabson 
22149fbc2acSDoug Rabson 			kvm_read(kd, symbols[X_MSQIDS].n_value, &msqids, sizeof(msqids));
2224816f94eSDoug Rabson 			xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
22349fbc2acSDoug Rabson 			kvm_read(kd, (u_long) msqids, xmsqids, sizeof(struct msqid_ds) * msginfo.msgmni);
2244816f94eSDoug Rabson 
22549fbc2acSDoug Rabson 			printf("Message Queues:\n");
22649fbc2acSDoug Rabson 			printf("T     ID     KEY        MODE       OWNER    GROUP");
22749fbc2acSDoug Rabson 			if (option & CREATOR)
22849fbc2acSDoug Rabson 				printf("  CREATOR   CGROUP");
22949fbc2acSDoug Rabson 			if (option & OUTSTANDING)
23049fbc2acSDoug Rabson 				printf(" CBYTES  QNUM");
23149fbc2acSDoug Rabson 			if (option & BIGGEST)
23249fbc2acSDoug Rabson 				printf(" QBYTES");
23349fbc2acSDoug Rabson 			if (option & PID)
23449fbc2acSDoug Rabson 				printf(" LSPID LRPID");
23549fbc2acSDoug Rabson 			if (option & TIME)
23649fbc2acSDoug Rabson 				printf("   STIME    RTIME    CTIME");
23749fbc2acSDoug Rabson 			printf("\n");
2384816f94eSDoug Rabson 			for (i = 0; i < msginfo.msgmni; i += 1) {
2394816f94eSDoug Rabson 				if (xmsqids[i].msg_qbytes != 0) {
24049fbc2acSDoug Rabson 					char    stime_buf[100], rtime_buf[100],
24149fbc2acSDoug Rabson 					        ctime_buf[100];
2424816f94eSDoug Rabson 					struct msqid_ds *msqptr = &xmsqids[i];
2434816f94eSDoug Rabson 
2444816f94eSDoug Rabson 					cvt_time(msqptr->msg_stime, stime_buf);
2454816f94eSDoug Rabson 					cvt_time(msqptr->msg_rtime, rtime_buf);
2464816f94eSDoug Rabson 					cvt_time(msqptr->msg_ctime, ctime_buf);
2474816f94eSDoug Rabson 
24849fbc2acSDoug Rabson 					printf("q %6d %10d %s %8s %8s",
2494816f94eSDoug Rabson 					    IXSEQ_TO_IPCID(i, msqptr->msg_perm),
25049fbc2acSDoug Rabson 					    msqptr->msg_perm.key,
25149fbc2acSDoug Rabson 					    fmt_perm(msqptr->msg_perm.mode),
25249fbc2acSDoug Rabson 					    user_from_uid(msqptr->msg_perm.uid, 0),
25349fbc2acSDoug Rabson 					    group_from_gid(msqptr->msg_perm.gid, 0));
2544816f94eSDoug Rabson 
25549fbc2acSDoug Rabson 					if (option & CREATOR)
25649fbc2acSDoug Rabson 						printf(" %8s %8s",
25749fbc2acSDoug Rabson 						    user_from_uid(msqptr->msg_perm.cuid, 0),
25849fbc2acSDoug Rabson 						    group_from_gid(msqptr->msg_perm.cgid, 0));
2594816f94eSDoug Rabson 
26049fbc2acSDoug Rabson 					if (option & OUTSTANDING)
26149fbc2acSDoug Rabson 						printf(" %6d %6d",
26249fbc2acSDoug Rabson 						    msqptr->msg_cbytes,
26349fbc2acSDoug Rabson 						    msqptr->msg_qnum);
2644816f94eSDoug Rabson 
26549fbc2acSDoug Rabson 					if (option & BIGGEST)
26649fbc2acSDoug Rabson 						printf(" %6d",
26749fbc2acSDoug Rabson 						    msqptr->msg_qbytes);
2684816f94eSDoug Rabson 
26949fbc2acSDoug Rabson 					if (option & PID)
27049fbc2acSDoug Rabson 						printf(" %6d %6d",
27149fbc2acSDoug Rabson 						    msqptr->msg_lspid,
27249fbc2acSDoug Rabson 						    msqptr->msg_lrpid);
2734816f94eSDoug Rabson 
27449fbc2acSDoug Rabson 					if (option & TIME)
27549fbc2acSDoug Rabson 						printf("%s %s %s",
27649fbc2acSDoug Rabson 						    stime_buf,
27749fbc2acSDoug Rabson 						    rtime_buf,
27849fbc2acSDoug Rabson 						    ctime_buf);
2794816f94eSDoug Rabson 
28049fbc2acSDoug Rabson 					printf("\n");
28149fbc2acSDoug Rabson 				}
28249fbc2acSDoug Rabson 			}
28349fbc2acSDoug Rabson 			printf("\n");
28449fbc2acSDoug Rabson 		}
28549fbc2acSDoug Rabson 	} else
28649fbc2acSDoug Rabson 		if (display & (MSGINFO | MSGTOTAL)) {
28749fbc2acSDoug Rabson 			fprintf(stderr,
28849fbc2acSDoug Rabson 			    "SVID messages facility not configured in the system\n");
28949fbc2acSDoug Rabson 		}
29049fbc2acSDoug Rabson 	if ((display & (SHMINFO | SHMTOTAL)) &&
29149fbc2acSDoug Rabson 	    kvm_read(kd, symbols[X_SHMINFO].n_value, &shminfo, sizeof(shminfo))) {
29249fbc2acSDoug Rabson 		if (display & SHMTOTAL) {
29349fbc2acSDoug Rabson 			printf("shminfo:\n");
29449fbc2acSDoug Rabson 			printf("\tshmmax: %7d\t(max shared memory segment size)\n",
29549fbc2acSDoug Rabson 			    shminfo.shmmax);
29649fbc2acSDoug Rabson 			printf("\tshmmin: %7d\t(min shared memory segment size)\n",
29749fbc2acSDoug Rabson 			    shminfo.shmmin);
29849fbc2acSDoug Rabson 			printf("\tshmmni: %7d\t(max number of shared memory identifiers)\n",
29949fbc2acSDoug Rabson 			    shminfo.shmmni);
30049fbc2acSDoug Rabson 			printf("\tshmseg: %7d\t(max shared memory segments per process)\n",
30149fbc2acSDoug Rabson 			    shminfo.shmseg);
30249fbc2acSDoug Rabson 			printf("\tshmall: %7d\t(max amount of shared memory in pages)\n\n",
30349fbc2acSDoug Rabson 			    shminfo.shmall);
30449fbc2acSDoug Rabson 		}
30549fbc2acSDoug Rabson 		if (display & SHMINFO) {
30649fbc2acSDoug Rabson 			struct shmid_ds *xshmids;
30749fbc2acSDoug Rabson 
30849fbc2acSDoug Rabson 			kvm_read(kd, symbols[X_SHMSEGS].n_value, &shmsegs, sizeof(shmsegs));
30949fbc2acSDoug Rabson 			xshmids = malloc(sizeof(struct shmid_ds) * msginfo.msgmni);
31049fbc2acSDoug Rabson 			kvm_read(kd, (u_long) shmsegs, xshmids, sizeof(struct shmid_ds) *
31149fbc2acSDoug Rabson 			    shminfo.shmmni);
31249fbc2acSDoug Rabson 
31349fbc2acSDoug Rabson 			printf("Shared Memory:\n");
31449fbc2acSDoug Rabson 			printf("T     ID     KEY        MODE       OWNER    GROUP");
31549fbc2acSDoug Rabson 			if (option & CREATOR)
31649fbc2acSDoug Rabson 				printf("  CREATOR   CGROUP");
31749fbc2acSDoug Rabson 			if (option & OUTSTANDING)
31849fbc2acSDoug Rabson 				printf(" NATTCH");
31949fbc2acSDoug Rabson 			if (option & BIGGEST)
32049fbc2acSDoug Rabson 				printf("  SEGSZ");
32149fbc2acSDoug Rabson 			if (option & PID)
32249fbc2acSDoug Rabson 				printf("  CPID  LPID");
32349fbc2acSDoug Rabson 			if (option & TIME)
32449fbc2acSDoug Rabson 				printf("   ATIME    DTIME    CTIME");
32549fbc2acSDoug Rabson 			printf("\n");
32649fbc2acSDoug Rabson 			for (i = 0; i < shminfo.shmmni; i += 1) {
32749fbc2acSDoug Rabson 				if (xshmids[i].shm_perm.mode & 0x0800) {
32849fbc2acSDoug Rabson 					char    atime_buf[100], dtime_buf[100],
32949fbc2acSDoug Rabson 					        ctime_buf[100];
33049fbc2acSDoug Rabson 					struct shmid_ds *shmptr = &xshmids[i];
33149fbc2acSDoug Rabson 
33249fbc2acSDoug Rabson 					cvt_time(shmptr->shm_atime, atime_buf);
33349fbc2acSDoug Rabson 					cvt_time(shmptr->shm_dtime, dtime_buf);
33449fbc2acSDoug Rabson 					cvt_time(shmptr->shm_ctime, ctime_buf);
33549fbc2acSDoug Rabson 
33649fbc2acSDoug Rabson 					printf("m %6d %10d %s %8s %8s",
33749fbc2acSDoug Rabson 					    IXSEQ_TO_IPCID(i, shmptr->shm_perm),
33849fbc2acSDoug Rabson 					    shmptr->shm_perm.key,
33949fbc2acSDoug Rabson 					    fmt_perm(shmptr->shm_perm.mode),
34049fbc2acSDoug Rabson 					    user_from_uid(shmptr->shm_perm.uid, 0),
34149fbc2acSDoug Rabson 					    group_from_gid(shmptr->shm_perm.gid, 0));
34249fbc2acSDoug Rabson 
34349fbc2acSDoug Rabson 					if (option & CREATOR)
34449fbc2acSDoug Rabson 						printf(" %8s %8s",
34549fbc2acSDoug Rabson 						    user_from_uid(shmptr->shm_perm.cuid, 0),
34649fbc2acSDoug Rabson 						    group_from_gid(shmptr->shm_perm.cgid, 0));
34749fbc2acSDoug Rabson 
34849fbc2acSDoug Rabson 					if (option & OUTSTANDING)
34949fbc2acSDoug Rabson 						printf(" %6d",
35049fbc2acSDoug Rabson 						    shmptr->shm_nattch);
35149fbc2acSDoug Rabson 
35249fbc2acSDoug Rabson 					if (option & BIGGEST)
35349fbc2acSDoug Rabson 						printf(" %6d",
35449fbc2acSDoug Rabson 						    shmptr->shm_segsz);
35549fbc2acSDoug Rabson 
35649fbc2acSDoug Rabson 					if (option & PID)
35749fbc2acSDoug Rabson 						printf(" %6d %6d",
35849fbc2acSDoug Rabson 						    shmptr->shm_cpid,
35949fbc2acSDoug Rabson 						    shmptr->shm_lpid);
36049fbc2acSDoug Rabson 
36149fbc2acSDoug Rabson 					if (option & TIME)
36249fbc2acSDoug Rabson 						printf("%s %s %s",
36349fbc2acSDoug Rabson 						    atime_buf,
36449fbc2acSDoug Rabson 						    dtime_buf,
36549fbc2acSDoug Rabson 						    ctime_buf);
36649fbc2acSDoug Rabson 
36749fbc2acSDoug Rabson 					printf("\n");
36849fbc2acSDoug Rabson 				}
36949fbc2acSDoug Rabson 			}
37049fbc2acSDoug Rabson 			printf("\n");
37149fbc2acSDoug Rabson 		}
37249fbc2acSDoug Rabson 	} else
37349fbc2acSDoug Rabson 		if (display & (SHMINFO | SHMTOTAL)) {
37449fbc2acSDoug Rabson 			fprintf(stderr,
37549fbc2acSDoug Rabson 			    "SVID shared memory facility not configured in the system\n");
37649fbc2acSDoug Rabson 		}
37749fbc2acSDoug Rabson 	if ((display & (SEMINFO | SEMTOTAL)) &&
37849fbc2acSDoug Rabson 	    kvm_read(kd, symbols[X_SEMINFO].n_value, &seminfo, sizeof(seminfo))) {
37949fbc2acSDoug Rabson 		struct semid_ds *xsema;
38049fbc2acSDoug Rabson 
38149fbc2acSDoug Rabson 		if (display & SEMTOTAL) {
38249fbc2acSDoug Rabson 			printf("seminfo:\n");
38349fbc2acSDoug Rabson 			printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",
38449fbc2acSDoug Rabson 			    seminfo.semmap);
38549fbc2acSDoug Rabson 			printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",
38649fbc2acSDoug Rabson 			    seminfo.semmni);
38749fbc2acSDoug Rabson 			printf("\tsemmns: %6d\t(# of semaphores in system)\n",
38849fbc2acSDoug Rabson 			    seminfo.semmns);
38949fbc2acSDoug Rabson 			printf("\tsemmnu: %6d\t(# of undo structures in system)\n",
39049fbc2acSDoug Rabson 			    seminfo.semmnu);
39149fbc2acSDoug Rabson 			printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",
39249fbc2acSDoug Rabson 			    seminfo.semmsl);
39349fbc2acSDoug Rabson 			printf("\tsemopm: %6d\t(max # of operations per semop call)\n",
39449fbc2acSDoug Rabson 			    seminfo.semopm);
39549fbc2acSDoug Rabson 			printf("\tsemume: %6d\t(max # of undo entries per process)\n",
39649fbc2acSDoug Rabson 			    seminfo.semume);
39749fbc2acSDoug Rabson 			printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",
39849fbc2acSDoug Rabson 			    seminfo.semusz);
39949fbc2acSDoug Rabson 			printf("\tsemvmx: %6d\t(semaphore maximum value)\n",
40049fbc2acSDoug Rabson 			    seminfo.semvmx);
40149fbc2acSDoug Rabson 			printf("\tsemaem: %6d\t(adjust on exit max value)\n\n",
40249fbc2acSDoug Rabson 			    seminfo.semaem);
40349fbc2acSDoug Rabson 		}
40449fbc2acSDoug Rabson 		if (display & SEMINFO) {
40549fbc2acSDoug Rabson 			if (semconfig(SEM_CONFIG_FREEZE) != 0) {
40649fbc2acSDoug Rabson 				perror("semconfig");
40749fbc2acSDoug Rabson 				fprintf(stderr,
40849fbc2acSDoug Rabson 				    "Can't lock semaphore facility - winging it...\n");
40949fbc2acSDoug Rabson 			}
41049fbc2acSDoug Rabson 			kvm_read(kd, symbols[X_SEMA].n_value, &sema, sizeof(sema));
41149fbc2acSDoug Rabson 			xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
41249fbc2acSDoug Rabson 			kvm_read(kd, (u_long) sema, xsema, sizeof(struct semid_ds) * seminfo.semmni);
41349fbc2acSDoug Rabson 
41449fbc2acSDoug Rabson 			printf("Semaphores:\n");
41549fbc2acSDoug Rabson 			printf("T     ID     KEY        MODE       OWNER    GROUP");
41649fbc2acSDoug Rabson 			if (option & CREATOR)
41749fbc2acSDoug Rabson 				printf("  CREATOR   CGROUP");
41849fbc2acSDoug Rabson 			if (option & BIGGEST)
41949fbc2acSDoug Rabson 				printf(" NSEMS");
42049fbc2acSDoug Rabson 			if (option & TIME)
42149fbc2acSDoug Rabson 				printf("   OTIME    CTIME");
42249fbc2acSDoug Rabson 			printf("\n");
42349fbc2acSDoug Rabson 			for (i = 0; i < seminfo.semmni; i += 1) {
42449fbc2acSDoug Rabson 				if ((xsema[i].sem_perm.mode & SEM_ALLOC) != 0) {
42549fbc2acSDoug Rabson 					char    ctime_buf[100], otime_buf[100];
42649fbc2acSDoug Rabson 					struct semid_ds *semaptr = &xsema[i];
42749fbc2acSDoug Rabson 					int     j, value;
42849fbc2acSDoug Rabson 					union semun junk;
42949fbc2acSDoug Rabson 
43049fbc2acSDoug Rabson 					cvt_time(semaptr->sem_otime, otime_buf);
43149fbc2acSDoug Rabson 					cvt_time(semaptr->sem_ctime, ctime_buf);
43249fbc2acSDoug Rabson 
43349fbc2acSDoug Rabson 					printf("s %6d %10d %s %8s %8s",
43449fbc2acSDoug Rabson 					    IXSEQ_TO_IPCID(i, semaptr->sem_perm),
43549fbc2acSDoug Rabson 					    semaptr->sem_perm.key,
43649fbc2acSDoug Rabson 					    fmt_perm(semaptr->sem_perm.mode),
43749fbc2acSDoug Rabson 					    user_from_uid(semaptr->sem_perm.uid, 0),
43849fbc2acSDoug Rabson 					    group_from_gid(semaptr->sem_perm.gid, 0));
43949fbc2acSDoug Rabson 
44049fbc2acSDoug Rabson 					if (option & CREATOR)
44149fbc2acSDoug Rabson 						printf(" %8s %8s",
44249fbc2acSDoug Rabson 						    user_from_uid(semaptr->sem_perm.cuid, 0),
44349fbc2acSDoug Rabson 						    group_from_gid(semaptr->sem_perm.cgid, 0));
44449fbc2acSDoug Rabson 
44549fbc2acSDoug Rabson 					if (option & BIGGEST)
44649fbc2acSDoug Rabson 						printf(" %6d",
44749fbc2acSDoug Rabson 						    semaptr->sem_nsems);
44849fbc2acSDoug Rabson 
44949fbc2acSDoug Rabson 					if (option & TIME)
45049fbc2acSDoug Rabson 						printf("%s %s",
45149fbc2acSDoug Rabson 						    otime_buf,
45249fbc2acSDoug Rabson 						    ctime_buf);
45349fbc2acSDoug Rabson 
45449fbc2acSDoug Rabson 					printf("\n");
4554816f94eSDoug Rabson 				}
4564816f94eSDoug Rabson 			}
4574816f94eSDoug Rabson 
45849fbc2acSDoug Rabson 			(void) semconfig(SEM_CONFIG_THAW);
45949fbc2acSDoug Rabson 
46049fbc2acSDoug Rabson 			printf("\n");
4614816f94eSDoug Rabson 		}
46249fbc2acSDoug Rabson 	} else
46349fbc2acSDoug Rabson 		if (display & (SEMINFO | SEMTOTAL)) {
46449fbc2acSDoug Rabson 			fprintf(stderr, "SVID semaphores facility not configured in the system\n");
46549fbc2acSDoug Rabson 		}
46649fbc2acSDoug Rabson 	kvm_close(kd);
4674816f94eSDoug Rabson 
4684816f94eSDoug Rabson 	exit(0);
4694816f94eSDoug Rabson }
47049fbc2acSDoug Rabson 
47149fbc2acSDoug Rabson void
47249fbc2acSDoug Rabson usage()
47349fbc2acSDoug Rabson {
47449fbc2acSDoug Rabson 
47549fbc2acSDoug Rabson 	fprintf(stderr,
47649fbc2acSDoug Rabson 	    "usage: ipcs [-abcmopqst] [-C corefile] [-N namelist]\n");
47749fbc2acSDoug Rabson 	exit(1);
47849fbc2acSDoug Rabson }
479