xref: /titanic_53/usr/src/cmd/ipcs/ipcs.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  * ipcs - IPC status
35*7c478bd9Sstevel@tonic-gate  *
36*7c478bd9Sstevel@tonic-gate  * Examine and print certain things about
37*7c478bd9Sstevel@tonic-gate  * message queues, semaphores and shared memory.
38*7c478bd9Sstevel@tonic-gate  *
39*7c478bd9Sstevel@tonic-gate  * IPC information is obtained via msgctl64, semctl64 and shmctl64.
40*7c478bd9Sstevel@tonic-gate  * As of SunOS 5.8, the IPC identifiers are obtained from msgids(),
41*7c478bd9Sstevel@tonic-gate  * semids(), and shmids() rather than reading them from /dev/kmem.
42*7c478bd9Sstevel@tonic-gate  * This ensures that the information in each msgid_ds, semid_ds or
43*7c478bd9Sstevel@tonic-gate  * shmid_ds data structure that we obtain is complete and consistent,
44*7c478bd9Sstevel@tonic-gate  * and allows us not to be a setgid-sys isaexec process.
45*7c478bd9Sstevel@tonic-gate  */
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/ipc.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/ipc_impl.h>
50*7c478bd9Sstevel@tonic-gate #include <sys/msg.h>
51*7c478bd9Sstevel@tonic-gate #include <sys/sem.h>
52*7c478bd9Sstevel@tonic-gate #include <sys/shm.h>
53*7c478bd9Sstevel@tonic-gate #include <errno.h>
54*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
55*7c478bd9Sstevel@tonic-gate #include <time.h>
56*7c478bd9Sstevel@tonic-gate #include <grp.h>
57*7c478bd9Sstevel@tonic-gate #include <pwd.h>
58*7c478bd9Sstevel@tonic-gate #include <stdio.h>
59*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
60*7c478bd9Sstevel@tonic-gate #include <ctype.h>
61*7c478bd9Sstevel@tonic-gate #include <unistd.h>
62*7c478bd9Sstevel@tonic-gate #include <locale.h>
63*7c478bd9Sstevel@tonic-gate #include <langinfo.h>
64*7c478bd9Sstevel@tonic-gate #include <string.h>
65*7c478bd9Sstevel@tonic-gate #include <limits.h>
66*7c478bd9Sstevel@tonic-gate #include <project.h>
67*7c478bd9Sstevel@tonic-gate #include <zone.h>
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate #define	USAGE	\
70*7c478bd9Sstevel@tonic-gate 	"usage: ipcs [-AabciJmopqstZ] [-D mtype] [-z zone]\n"
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate static char chdr[] = "T         ID      KEY        MODE        OWNER    GROUP";
73*7c478bd9Sstevel@tonic-gate 						/* common header format */
74*7c478bd9Sstevel@tonic-gate static char chdr2[] = "  CREATOR   CGROUP";	/* c option header format */
75*7c478bd9Sstevel@tonic-gate static char chdr3[] = "         PROJECT";	/* J option header format */
76*7c478bd9Sstevel@tonic-gate static char opts[] = "AabciJmopqstD:z:Z";	/* getopt options */
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate static long	mtype;		/* -D: user-supplied message type */
79*7c478bd9Sstevel@tonic-gate static zoneid_t	zoneid;		/* -z: user-supplied zone id */
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate static int	bflg,		/* biggest size: */
82*7c478bd9Sstevel@tonic-gate 				/*	segsz on m; qbytes on q; nsems on s */
83*7c478bd9Sstevel@tonic-gate 		cflg,		/* creator's login and group names */
84*7c478bd9Sstevel@tonic-gate 		Dflg,		/* dump contents of message queues */
85*7c478bd9Sstevel@tonic-gate 		iflg,		/* ISM attaches */
86*7c478bd9Sstevel@tonic-gate 		Jflg,		/* dump project name */
87*7c478bd9Sstevel@tonic-gate 		mflg,		/* shared memory status */
88*7c478bd9Sstevel@tonic-gate 		oflg,		/* outstanding data: */
89*7c478bd9Sstevel@tonic-gate 				/*	nattch on m; cbytes, qnum on q */
90*7c478bd9Sstevel@tonic-gate 		pflg,		/* process id's: lrpid, lspid on q; */
91*7c478bd9Sstevel@tonic-gate 				/*	cpid, lpid on m */
92*7c478bd9Sstevel@tonic-gate 		qflg,		/* message queue status */
93*7c478bd9Sstevel@tonic-gate 		sflg,		/* semaphore status */
94*7c478bd9Sstevel@tonic-gate 		tflg,		/* times: atime, ctime, dtime on m;	*/
95*7c478bd9Sstevel@tonic-gate 				/*	ctime, rtime, stime on q;	*/
96*7c478bd9Sstevel@tonic-gate 				/*	ctime, otime on s */
97*7c478bd9Sstevel@tonic-gate 		zflg,		/* show only objects from specified zone */
98*7c478bd9Sstevel@tonic-gate 		Zflg,		/* display zone name */
99*7c478bd9Sstevel@tonic-gate 		err;		/* option error count */
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate static void hp(char, char *, struct ipc_perm64 *, int);
102*7c478bd9Sstevel@tonic-gate static void jp(struct ipc_perm64 *);
103*7c478bd9Sstevel@tonic-gate static void tp(ipc_time_t);
104*7c478bd9Sstevel@tonic-gate static void dumpmsgq(int);
105*7c478bd9Sstevel@tonic-gate static void dumpmsg(long, char *, size_t);
106*7c478bd9Sstevel@tonic-gate static zoneid_t getzone(char *);
107*7c478bd9Sstevel@tonic-gate static void printzone(zoneid_t);
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate int
110*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
111*7c478bd9Sstevel@tonic-gate {
112*7c478bd9Sstevel@tonic-gate 	static	int	*ids;	/* array of IPC identifiers from *ids() */
113*7c478bd9Sstevel@tonic-gate 	static	uint_t	nids;	/* number of entries in ids */
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	int	o;	/* option flag */
116*7c478bd9Sstevel@tonic-gate 	int	id;	/* IPC identifier */
117*7c478bd9Sstevel@tonic-gate 	int	i;
118*7c478bd9Sstevel@tonic-gate 	uint_t	n;	/* table size */
119*7c478bd9Sstevel@tonic-gate 	time_t	now;	/* date */
120*7c478bd9Sstevel@tonic-gate 	char	tbuf[BUFSIZ];
121*7c478bd9Sstevel@tonic-gate 	char	*dfmt;  /* date format pointer */
122*7c478bd9Sstevel@tonic-gate 	char	*endptr;	/* terminator for strtol() */
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
125*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate 	(void) memset(tbuf, 0, sizeof (tbuf));
128*7c478bd9Sstevel@tonic-gate 	dfmt = nl_langinfo(_DATE_FMT);
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 	zoneid = getzoneid();	/* default zone id if -z and -Z not used */
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate 	/* Go through the options and set flags. */
133*7c478bd9Sstevel@tonic-gate 	while ((o = getopt(argc, argv, opts)) != EOF) {
134*7c478bd9Sstevel@tonic-gate 		switch (o) {
135*7c478bd9Sstevel@tonic-gate 		case 'A':
136*7c478bd9Sstevel@tonic-gate 			bflg = cflg = iflg = oflg = pflg = tflg = Jflg = 1;
137*7c478bd9Sstevel@tonic-gate 			break;
138*7c478bd9Sstevel@tonic-gate 		case 'a':
139*7c478bd9Sstevel@tonic-gate 			bflg = cflg = oflg = pflg = tflg = 1;
140*7c478bd9Sstevel@tonic-gate 			break;
141*7c478bd9Sstevel@tonic-gate 		case 'b':
142*7c478bd9Sstevel@tonic-gate 			bflg = 1;
143*7c478bd9Sstevel@tonic-gate 			break;
144*7c478bd9Sstevel@tonic-gate 		case 'c':
145*7c478bd9Sstevel@tonic-gate 			cflg = 1;
146*7c478bd9Sstevel@tonic-gate 			break;
147*7c478bd9Sstevel@tonic-gate 		case 'D':
148*7c478bd9Sstevel@tonic-gate 			mtype = strtol(optarg, &endptr, 0);
149*7c478bd9Sstevel@tonic-gate 			if (endptr == optarg || *endptr != '\0') {
150*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
151*7c478bd9Sstevel@tonic-gate 				    gettext("ipcs: invalid message type: %s\n"),
152*7c478bd9Sstevel@tonic-gate 				    optarg);
153*7c478bd9Sstevel@tonic-gate 				err++;
154*7c478bd9Sstevel@tonic-gate 				break;
155*7c478bd9Sstevel@tonic-gate 			}
156*7c478bd9Sstevel@tonic-gate 			Dflg = 1;
157*7c478bd9Sstevel@tonic-gate 			break;
158*7c478bd9Sstevel@tonic-gate 		case 'i':
159*7c478bd9Sstevel@tonic-gate 			iflg = 1;
160*7c478bd9Sstevel@tonic-gate 			break;
161*7c478bd9Sstevel@tonic-gate 		case 'J':
162*7c478bd9Sstevel@tonic-gate 			Jflg = 1;
163*7c478bd9Sstevel@tonic-gate 			break;
164*7c478bd9Sstevel@tonic-gate 		case 'm':
165*7c478bd9Sstevel@tonic-gate 			mflg = 1;
166*7c478bd9Sstevel@tonic-gate 			break;
167*7c478bd9Sstevel@tonic-gate 		case 'o':
168*7c478bd9Sstevel@tonic-gate 			oflg = 1;
169*7c478bd9Sstevel@tonic-gate 			break;
170*7c478bd9Sstevel@tonic-gate 		case 'p':
171*7c478bd9Sstevel@tonic-gate 			pflg = 1;
172*7c478bd9Sstevel@tonic-gate 			break;
173*7c478bd9Sstevel@tonic-gate 		case 'q':
174*7c478bd9Sstevel@tonic-gate 			qflg = 1;
175*7c478bd9Sstevel@tonic-gate 			break;
176*7c478bd9Sstevel@tonic-gate 		case 's':
177*7c478bd9Sstevel@tonic-gate 			sflg = 1;
178*7c478bd9Sstevel@tonic-gate 			break;
179*7c478bd9Sstevel@tonic-gate 		case 't':
180*7c478bd9Sstevel@tonic-gate 			tflg = 1;
181*7c478bd9Sstevel@tonic-gate 			break;
182*7c478bd9Sstevel@tonic-gate 		case 'z':
183*7c478bd9Sstevel@tonic-gate 			zflg = 1;
184*7c478bd9Sstevel@tonic-gate 			zoneid = getzone(optarg);
185*7c478bd9Sstevel@tonic-gate 			break;
186*7c478bd9Sstevel@tonic-gate 		case 'Z':
187*7c478bd9Sstevel@tonic-gate 			Zflg = 1;
188*7c478bd9Sstevel@tonic-gate 			break;
189*7c478bd9Sstevel@tonic-gate 		case '?':
190*7c478bd9Sstevel@tonic-gate 			err++;
191*7c478bd9Sstevel@tonic-gate 			break;
192*7c478bd9Sstevel@tonic-gate 		}
193*7c478bd9Sstevel@tonic-gate 	}
194*7c478bd9Sstevel@tonic-gate 	if (err || (optind < argc)) {
195*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(USAGE));
196*7c478bd9Sstevel@tonic-gate 		exit(1);
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	if ((mflg + qflg + sflg) == 0)
200*7c478bd9Sstevel@tonic-gate 		mflg = qflg = sflg = 1;
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	now = time(NULL);
203*7c478bd9Sstevel@tonic-gate 	(void) strftime(tbuf, sizeof (tbuf), dfmt, localtime(&now));
204*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("IPC status from <running system> as of %s\n"),
205*7c478bd9Sstevel@tonic-gate 	    tbuf);
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate 	/*
208*7c478bd9Sstevel@tonic-gate 	 * Print Message Queue status report.
209*7c478bd9Sstevel@tonic-gate 	 */
210*7c478bd9Sstevel@tonic-gate 	if (qflg) {
211*7c478bd9Sstevel@tonic-gate 		struct msqid_ds64 qds;
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate 		for (;;) {
214*7c478bd9Sstevel@tonic-gate 			if (msgids(ids, nids, &n) != 0) {
215*7c478bd9Sstevel@tonic-gate 				perror("msgids");
216*7c478bd9Sstevel@tonic-gate 				exit(1);
217*7c478bd9Sstevel@tonic-gate 			}
218*7c478bd9Sstevel@tonic-gate 			if (n <= nids)
219*7c478bd9Sstevel@tonic-gate 				break;
220*7c478bd9Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
221*7c478bd9Sstevel@tonic-gate 		}
222*7c478bd9Sstevel@tonic-gate 
223*7c478bd9Sstevel@tonic-gate 		(void) printf("%s%s%s%s%s%s%s%s\n", chdr,
224*7c478bd9Sstevel@tonic-gate 		    cflg ? chdr2 : "",
225*7c478bd9Sstevel@tonic-gate 		    oflg ? " CBYTES  QNUM" : "",
226*7c478bd9Sstevel@tonic-gate 		    bflg ? " QBYTES" : "",
227*7c478bd9Sstevel@tonic-gate 		    pflg ? " LSPID LRPID" : "",
228*7c478bd9Sstevel@tonic-gate 		    tflg ? "   STIME    RTIME    CTIME " : "",
229*7c478bd9Sstevel@tonic-gate 		    Jflg ? chdr3 : "",
230*7c478bd9Sstevel@tonic-gate 		    Zflg ? "     ZONE" : "");
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Message Queues:\n"));
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
235*7c478bd9Sstevel@tonic-gate 			id = ids[i];
236*7c478bd9Sstevel@tonic-gate 			if (msgctl64(id, IPC_STAT64, &qds) < 0)
237*7c478bd9Sstevel@tonic-gate 				continue;
238*7c478bd9Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
239*7c478bd9Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
240*7c478bd9Sstevel@tonic-gate 			    qds.msgx_perm.ipcx_zoneid != zoneid)
241*7c478bd9Sstevel@tonic-gate 				continue;
242*7c478bd9Sstevel@tonic-gate 			hp('q', "SRrw-rw-rw-", &qds.msgx_perm, id);
243*7c478bd9Sstevel@tonic-gate 			if (oflg)
244*7c478bd9Sstevel@tonic-gate 				(void) printf(" %6llu %5llu",
245*7c478bd9Sstevel@tonic-gate 				    qds.msgx_cbytes, qds.msgx_qnum);
246*7c478bd9Sstevel@tonic-gate 			if (bflg)
247*7c478bd9Sstevel@tonic-gate 				(void) printf(" %6llu", qds.msgx_qbytes);
248*7c478bd9Sstevel@tonic-gate 			if (pflg)
249*7c478bd9Sstevel@tonic-gate 				(void) printf(" %5d %5d",
250*7c478bd9Sstevel@tonic-gate 				    (int)qds.msgx_lspid, (int)qds.msgx_lrpid);
251*7c478bd9Sstevel@tonic-gate 			if (tflg) {
252*7c478bd9Sstevel@tonic-gate 				tp(qds.msgx_stime);
253*7c478bd9Sstevel@tonic-gate 				tp(qds.msgx_rtime);
254*7c478bd9Sstevel@tonic-gate 				tp(qds.msgx_ctime);
255*7c478bd9Sstevel@tonic-gate 			}
256*7c478bd9Sstevel@tonic-gate 			if (Jflg)
257*7c478bd9Sstevel@tonic-gate 				jp(&qds.msgx_perm);
258*7c478bd9Sstevel@tonic-gate 			if (Zflg)
259*7c478bd9Sstevel@tonic-gate 				printzone(qds.msgx_perm.ipcx_zoneid);
260*7c478bd9Sstevel@tonic-gate 			(void) printf("\n");
261*7c478bd9Sstevel@tonic-gate 			if (Dflg)
262*7c478bd9Sstevel@tonic-gate 				dumpmsgq(id);
263*7c478bd9Sstevel@tonic-gate 		}
264*7c478bd9Sstevel@tonic-gate 	}
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	/*
267*7c478bd9Sstevel@tonic-gate 	 * Print Shared Memory status report.
268*7c478bd9Sstevel@tonic-gate 	 */
269*7c478bd9Sstevel@tonic-gate 	if (mflg) {
270*7c478bd9Sstevel@tonic-gate 		struct shmid_ds64 mds;
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 		for (;;) {
273*7c478bd9Sstevel@tonic-gate 			if (shmids(ids, nids, &n) != 0) {
274*7c478bd9Sstevel@tonic-gate 				perror("shmids");
275*7c478bd9Sstevel@tonic-gate 				exit(1);
276*7c478bd9Sstevel@tonic-gate 			}
277*7c478bd9Sstevel@tonic-gate 			if (n <= nids)
278*7c478bd9Sstevel@tonic-gate 				break;
279*7c478bd9Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
280*7c478bd9Sstevel@tonic-gate 		}
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate 		if (!qflg || oflg || bflg || pflg || tflg || iflg)
283*7c478bd9Sstevel@tonic-gate 			(void) printf("%s%s%s%s%s%s%s%s%s\n", chdr,
284*7c478bd9Sstevel@tonic-gate 			    cflg ? chdr2 : "",
285*7c478bd9Sstevel@tonic-gate 			    oflg ? " NATTCH" : "",
286*7c478bd9Sstevel@tonic-gate 			    bflg ? "      SEGSZ" : "",
287*7c478bd9Sstevel@tonic-gate 			    pflg ? "  CPID  LPID" : "",
288*7c478bd9Sstevel@tonic-gate 			    tflg ? "   ATIME    DTIME    CTIME " : "",
289*7c478bd9Sstevel@tonic-gate 			    iflg ? " ISMATTCH" : "",
290*7c478bd9Sstevel@tonic-gate 			    Jflg ? chdr3 : "",
291*7c478bd9Sstevel@tonic-gate 			    Zflg ? "     ZONE" : "");
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Shared Memory:\n"));
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
296*7c478bd9Sstevel@tonic-gate 			id = ids[i];
297*7c478bd9Sstevel@tonic-gate 			if (shmctl64(id, IPC_STAT64, &mds) < 0)
298*7c478bd9Sstevel@tonic-gate 				continue;
299*7c478bd9Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
300*7c478bd9Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
301*7c478bd9Sstevel@tonic-gate 			    mds.shmx_perm.ipcx_zoneid != zoneid)
302*7c478bd9Sstevel@tonic-gate 				continue;
303*7c478bd9Sstevel@tonic-gate 			hp('m', "--rw-rw-rw-", &mds.shmx_perm, id);
304*7c478bd9Sstevel@tonic-gate 			if (oflg)
305*7c478bd9Sstevel@tonic-gate 				(void) printf(" %6llu", mds.shmx_nattch);
306*7c478bd9Sstevel@tonic-gate 			if (bflg)
307*7c478bd9Sstevel@tonic-gate 				(void) printf(" %10llu", mds.shmx_segsz);
308*7c478bd9Sstevel@tonic-gate 			if (pflg)
309*7c478bd9Sstevel@tonic-gate 				(void) printf(" %5d %5d",
310*7c478bd9Sstevel@tonic-gate 				    (int)mds.shmx_cpid, (int)mds.shmx_lpid);
311*7c478bd9Sstevel@tonic-gate 			if (tflg) {
312*7c478bd9Sstevel@tonic-gate 				tp(mds.shmx_atime);
313*7c478bd9Sstevel@tonic-gate 				tp(mds.shmx_dtime);
314*7c478bd9Sstevel@tonic-gate 				tp(mds.shmx_ctime);
315*7c478bd9Sstevel@tonic-gate 			}
316*7c478bd9Sstevel@tonic-gate 			if (iflg)
317*7c478bd9Sstevel@tonic-gate 				(void) printf(" %8llu", mds.shmx_cnattch);
318*7c478bd9Sstevel@tonic-gate 			if (Jflg)
319*7c478bd9Sstevel@tonic-gate 				jp(&mds.shmx_perm);
320*7c478bd9Sstevel@tonic-gate 			if (Zflg)
321*7c478bd9Sstevel@tonic-gate 				printzone(mds.shmx_perm.ipcx_zoneid);
322*7c478bd9Sstevel@tonic-gate 			(void) printf("\n");
323*7c478bd9Sstevel@tonic-gate 		}
324*7c478bd9Sstevel@tonic-gate 	}
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 	/*
327*7c478bd9Sstevel@tonic-gate 	 * Print Semaphore facility status.
328*7c478bd9Sstevel@tonic-gate 	 */
329*7c478bd9Sstevel@tonic-gate 	if (sflg) {
330*7c478bd9Sstevel@tonic-gate 		struct semid_ds64 sds;
331*7c478bd9Sstevel@tonic-gate 		union semun {
332*7c478bd9Sstevel@tonic-gate 			int val;
333*7c478bd9Sstevel@tonic-gate 			struct semid_ds64 *buf;
334*7c478bd9Sstevel@tonic-gate 			ushort_t *array;
335*7c478bd9Sstevel@tonic-gate 		} semarg;
336*7c478bd9Sstevel@tonic-gate 		semarg.buf = &sds;
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate 		for (;;) {
339*7c478bd9Sstevel@tonic-gate 			if (semids(ids, nids, &n) != 0) {
340*7c478bd9Sstevel@tonic-gate 				perror("semids");
341*7c478bd9Sstevel@tonic-gate 				exit(1);
342*7c478bd9Sstevel@tonic-gate 			}
343*7c478bd9Sstevel@tonic-gate 			if (n <= nids)
344*7c478bd9Sstevel@tonic-gate 				break;
345*7c478bd9Sstevel@tonic-gate 			ids = realloc(ids, (nids = n) * sizeof (int));
346*7c478bd9Sstevel@tonic-gate 		}
347*7c478bd9Sstevel@tonic-gate 
348*7c478bd9Sstevel@tonic-gate 		if (bflg || tflg || (!qflg && !mflg))
349*7c478bd9Sstevel@tonic-gate 			(void) printf("%s%s%s%s%s%s\n", chdr,
350*7c478bd9Sstevel@tonic-gate 			    cflg ? chdr2 : "",
351*7c478bd9Sstevel@tonic-gate 			    bflg ? " NSEMS" : "",
352*7c478bd9Sstevel@tonic-gate 			    tflg ? "   OTIME    CTIME " : "",
353*7c478bd9Sstevel@tonic-gate 			    Jflg ? chdr3 : "",
354*7c478bd9Sstevel@tonic-gate 			    Zflg ? "     ZONE" : "");
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Semaphores:\n"));
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < n; i++) {
359*7c478bd9Sstevel@tonic-gate 			id = ids[i];
360*7c478bd9Sstevel@tonic-gate 			if (semctl64(id, 0, IPC_STAT64, semarg) < 0)
361*7c478bd9Sstevel@tonic-gate 				continue;
362*7c478bd9Sstevel@tonic-gate 			/* ignore zone if -Z was used and -z wasn't */
363*7c478bd9Sstevel@tonic-gate 			if ((zflg || !Zflg) &&
364*7c478bd9Sstevel@tonic-gate 			    sds.semx_perm.ipcx_zoneid != zoneid)
365*7c478bd9Sstevel@tonic-gate 				continue;
366*7c478bd9Sstevel@tonic-gate 			hp('s', "--ra-ra-ra-", &sds.semx_perm, id);
367*7c478bd9Sstevel@tonic-gate 			if (bflg)
368*7c478bd9Sstevel@tonic-gate 				(void) printf(" %5u", sds.semx_nsems);
369*7c478bd9Sstevel@tonic-gate 			if (tflg) {
370*7c478bd9Sstevel@tonic-gate 				tp(sds.semx_otime);
371*7c478bd9Sstevel@tonic-gate 				tp(sds.semx_ctime);
372*7c478bd9Sstevel@tonic-gate 			}
373*7c478bd9Sstevel@tonic-gate 			if (Jflg)
374*7c478bd9Sstevel@tonic-gate 				jp(&sds.semx_perm);
375*7c478bd9Sstevel@tonic-gate 			if (Zflg)
376*7c478bd9Sstevel@tonic-gate 				printzone(sds.semx_perm.ipcx_zoneid);
377*7c478bd9Sstevel@tonic-gate 			(void) printf("\n");
378*7c478bd9Sstevel@tonic-gate 		}
379*7c478bd9Sstevel@tonic-gate 	}
380*7c478bd9Sstevel@tonic-gate 
381*7c478bd9Sstevel@tonic-gate 	return (0);
382*7c478bd9Sstevel@tonic-gate }
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate /*
385*7c478bd9Sstevel@tonic-gate  * hp - common header print
386*7c478bd9Sstevel@tonic-gate  */
387*7c478bd9Sstevel@tonic-gate static void
388*7c478bd9Sstevel@tonic-gate hp(char type, char *modesp, struct ipc_perm64 *permp, int slot)
389*7c478bd9Sstevel@tonic-gate {
390*7c478bd9Sstevel@tonic-gate 	int		i;	/* loop control */
391*7c478bd9Sstevel@tonic-gate 	struct group	*g;	/* ptr to group group entry */
392*7c478bd9Sstevel@tonic-gate 	struct passwd	*u;	/* ptr to user passwd entry */
393*7c478bd9Sstevel@tonic-gate 	char		keyfield[16];
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate 	(void) snprintf(keyfield, sizeof (keyfield), "  %#x", permp->ipcx_key);
396*7c478bd9Sstevel@tonic-gate 	(void) printf("%c %10d %-13s", type, slot, keyfield);
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	for (i = 02000; i; modesp++, i >>= 1)
399*7c478bd9Sstevel@tonic-gate 		(void) printf("%c", (permp->ipcx_mode & i) ? *modesp : '-');
400*7c478bd9Sstevel@tonic-gate 	if ((u = getpwuid(permp->ipcx_uid)) == NULL)
401*7c478bd9Sstevel@tonic-gate 		(void) printf("%9d", (int)permp->ipcx_uid);
402*7c478bd9Sstevel@tonic-gate 	else
403*7c478bd9Sstevel@tonic-gate 		(void) printf("%9.8s", u->pw_name);
404*7c478bd9Sstevel@tonic-gate 	if ((g = getgrgid(permp->ipcx_gid)) == NULL)
405*7c478bd9Sstevel@tonic-gate 		(void) printf("%9d", (int)permp->ipcx_gid);
406*7c478bd9Sstevel@tonic-gate 	else
407*7c478bd9Sstevel@tonic-gate 		(void) printf("%9.8s", g->gr_name);
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 	if (cflg) {
410*7c478bd9Sstevel@tonic-gate 		if ((u = getpwuid(permp->ipcx_cuid)) == NULL)
411*7c478bd9Sstevel@tonic-gate 			(void) printf("%9d", (int)permp->ipcx_cuid);
412*7c478bd9Sstevel@tonic-gate 		else
413*7c478bd9Sstevel@tonic-gate 			(void) printf("%9.8s", u->pw_name);
414*7c478bd9Sstevel@tonic-gate 		if ((g = getgrgid(permp->ipcx_cgid)) == NULL)
415*7c478bd9Sstevel@tonic-gate 			(void) printf("%9d", (int)permp->ipcx_cgid);
416*7c478bd9Sstevel@tonic-gate 		else
417*7c478bd9Sstevel@tonic-gate 			(void) printf("%9.8s", g->gr_name);
418*7c478bd9Sstevel@tonic-gate 	}
419*7c478bd9Sstevel@tonic-gate }
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate /*
422*7c478bd9Sstevel@tonic-gate  * jp - project header print
423*7c478bd9Sstevel@tonic-gate  */
424*7c478bd9Sstevel@tonic-gate static void
425*7c478bd9Sstevel@tonic-gate jp(struct ipc_perm64 *permp)
426*7c478bd9Sstevel@tonic-gate {
427*7c478bd9Sstevel@tonic-gate 	struct project	proj;
428*7c478bd9Sstevel@tonic-gate 	char		buf[PROJECT_BUFSZ];
429*7c478bd9Sstevel@tonic-gate 
430*7c478bd9Sstevel@tonic-gate 	if ((getprojbyid(permp->ipcx_projid, &proj, buf,
431*7c478bd9Sstevel@tonic-gate 	    PROJECT_BUFSZ)) == NULL)
432*7c478bd9Sstevel@tonic-gate 		(void) printf("%16ld", permp->ipcx_projid);
433*7c478bd9Sstevel@tonic-gate 	else
434*7c478bd9Sstevel@tonic-gate 		(void) printf("%16.15s", proj.pj_name);
435*7c478bd9Sstevel@tonic-gate }
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate /*
438*7c478bd9Sstevel@tonic-gate  * tp - time entry printer
439*7c478bd9Sstevel@tonic-gate  */
440*7c478bd9Sstevel@tonic-gate void
441*7c478bd9Sstevel@tonic-gate tp(ipc_time_t gmt64)
442*7c478bd9Sstevel@tonic-gate {
443*7c478bd9Sstevel@tonic-gate 	struct tm *t;	/* ptr to converted time */
444*7c478bd9Sstevel@tonic-gate 	time_t gmt = (time_t)gmt64;
445*7c478bd9Sstevel@tonic-gate 
446*7c478bd9Sstevel@tonic-gate 	if (gmt && gmt64 <= UINT_MAX) {
447*7c478bd9Sstevel@tonic-gate 		t = localtime(&gmt);
448*7c478bd9Sstevel@tonic-gate 		(void) printf(" %2d:%2.2d:%2.2d",
449*7c478bd9Sstevel@tonic-gate 		    t->tm_hour, t->tm_min, t->tm_sec);
450*7c478bd9Sstevel@tonic-gate 	} else {
451*7c478bd9Sstevel@tonic-gate 		(void) printf("%9s", gettext(" no-entry"));
452*7c478bd9Sstevel@tonic-gate 	}
453*7c478bd9Sstevel@tonic-gate }
454*7c478bd9Sstevel@tonic-gate 
455*7c478bd9Sstevel@tonic-gate /* Round up to a sizeof (size_t) boundary */
456*7c478bd9Sstevel@tonic-gate #define	SZROUND(x)	(((x) + sizeof (size_t) - 1) & ~(sizeof (size_t) - 1))
457*7c478bd9Sstevel@tonic-gate 
458*7c478bd9Sstevel@tonic-gate /*
459*7c478bd9Sstevel@tonic-gate  * dumpmsgq - dump all messages on a message queue
460*7c478bd9Sstevel@tonic-gate  */
461*7c478bd9Sstevel@tonic-gate void
462*7c478bd9Sstevel@tonic-gate dumpmsgq(int msqid)
463*7c478bd9Sstevel@tonic-gate {
464*7c478bd9Sstevel@tonic-gate 	static struct msgsnap_head *buf = NULL;
465*7c478bd9Sstevel@tonic-gate 	static size_t bufsize;
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 	struct msgsnap_mhead *mhead;
468*7c478bd9Sstevel@tonic-gate 	size_t i;
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 	/* allocate the minimum required buffer size on first time through */
471*7c478bd9Sstevel@tonic-gate 	if (buf == NULL)
472*7c478bd9Sstevel@tonic-gate 		buf = malloc(bufsize = sizeof (struct msgsnap_head));
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate 	/*
475*7c478bd9Sstevel@tonic-gate 	 * Fetch all messages specified by mtype from
476*7c478bd9Sstevel@tonic-gate 	 * the queue while leaving the queue intact.
477*7c478bd9Sstevel@tonic-gate 	 */
478*7c478bd9Sstevel@tonic-gate 	for (;;) {
479*7c478bd9Sstevel@tonic-gate 		if (msgsnap(msqid, buf, bufsize, mtype) != 0) {
480*7c478bd9Sstevel@tonic-gate 			/*
481*7c478bd9Sstevel@tonic-gate 			 * Don't complain; either the user does not have
482*7c478bd9Sstevel@tonic-gate 			 * read permission on msqid or msqid was deleted.
483*7c478bd9Sstevel@tonic-gate 			 */
484*7c478bd9Sstevel@tonic-gate 			return;
485*7c478bd9Sstevel@tonic-gate 		}
486*7c478bd9Sstevel@tonic-gate 		if (bufsize >= buf->msgsnap_size) {
487*7c478bd9Sstevel@tonic-gate 			/* we collected all of the messages */
488*7c478bd9Sstevel@tonic-gate 			break;
489*7c478bd9Sstevel@tonic-gate 		}
490*7c478bd9Sstevel@tonic-gate 		/* The buffer is too small; allocate a bigger buffer */
491*7c478bd9Sstevel@tonic-gate 		buf = realloc(buf, bufsize = buf->msgsnap_size);
492*7c478bd9Sstevel@tonic-gate 	}
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate 	/*
495*7c478bd9Sstevel@tonic-gate 	 * Process each message in the queue (there may be none).
496*7c478bd9Sstevel@tonic-gate 	 * The first message header starts just after the buffer header.
497*7c478bd9Sstevel@tonic-gate 	 */
498*7c478bd9Sstevel@tonic-gate 	mhead = (struct msgsnap_mhead *)(buf + 1);
499*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < buf->msgsnap_nmsg; i++) {
500*7c478bd9Sstevel@tonic-gate 		size_t mlen = mhead->msgsnap_mlen;
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate 		dumpmsg(mhead->msgsnap_mtype, (char *)(mhead + 1), mlen);
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 		/* advance to next message header */
505*7c478bd9Sstevel@tonic-gate 		/* LINTED alignment */
506*7c478bd9Sstevel@tonic-gate 		mhead = (struct msgsnap_mhead *)
507*7c478bd9Sstevel@tonic-gate 			((caddr_t)(mhead + 1) + SZROUND(mlen));
508*7c478bd9Sstevel@tonic-gate 	}
509*7c478bd9Sstevel@tonic-gate }
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate /*
512*7c478bd9Sstevel@tonic-gate  * dumpmsg - dump one message from a message queue.
513*7c478bd9Sstevel@tonic-gate  */
514*7c478bd9Sstevel@tonic-gate void
515*7c478bd9Sstevel@tonic-gate dumpmsg(long type, char *msg, size_t msgsize)
516*7c478bd9Sstevel@tonic-gate {
517*7c478bd9Sstevel@tonic-gate 	size_t i, j, k;
518*7c478bd9Sstevel@tonic-gate 	int c;
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("  message type %ld, size %lu\n"),
521*7c478bd9Sstevel@tonic-gate 		type, (ulong_t)msgsize);
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < msgsize; i += 16) {
524*7c478bd9Sstevel@tonic-gate 		/* first in hex */
525*7c478bd9Sstevel@tonic-gate 		(void) printf(" %5ld:  ", (ulong_t)i);
526*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < 16; j++) {
527*7c478bd9Sstevel@tonic-gate 			if ((k = i + j) < msgsize)
528*7c478bd9Sstevel@tonic-gate 				(void) printf("%2.2x ", msg[k] & 0xff);
529*7c478bd9Sstevel@tonic-gate 			else
530*7c478bd9Sstevel@tonic-gate 				(void) printf("   ");
531*7c478bd9Sstevel@tonic-gate 		}
532*7c478bd9Sstevel@tonic-gate 		/* then in ascii */
533*7c478bd9Sstevel@tonic-gate 		(void) printf("   ");
534*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < 16; j++) {
535*7c478bd9Sstevel@tonic-gate 			if ((k = i + j) >= msgsize)
536*7c478bd9Sstevel@tonic-gate 				break;
537*7c478bd9Sstevel@tonic-gate 			c = msg[k] & 0xff;
538*7c478bd9Sstevel@tonic-gate 			if (isascii(c) && isprint(c))
539*7c478bd9Sstevel@tonic-gate 				(void) printf("%c", c);
540*7c478bd9Sstevel@tonic-gate 			else
541*7c478bd9Sstevel@tonic-gate 				(void) printf(".");
542*7c478bd9Sstevel@tonic-gate 		}
543*7c478bd9Sstevel@tonic-gate 		(void) printf("\n");
544*7c478bd9Sstevel@tonic-gate 	}
545*7c478bd9Sstevel@tonic-gate }
546*7c478bd9Sstevel@tonic-gate 
547*7c478bd9Sstevel@tonic-gate /* convert string containing zone name or id to a numeric id */
548*7c478bd9Sstevel@tonic-gate static zoneid_t
549*7c478bd9Sstevel@tonic-gate getzone(char *arg)
550*7c478bd9Sstevel@tonic-gate {
551*7c478bd9Sstevel@tonic-gate 	zoneid_t zoneid;
552*7c478bd9Sstevel@tonic-gate 
553*7c478bd9Sstevel@tonic-gate 	if (zone_get_id(arg, &zoneid) != 0) {
554*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
555*7c478bd9Sstevel@tonic-gate 		    gettext("ipcs: unknown zone: %s\n"), arg);
556*7c478bd9Sstevel@tonic-gate 		exit(1);
557*7c478bd9Sstevel@tonic-gate 	}
558*7c478bd9Sstevel@tonic-gate 	return (zoneid);
559*7c478bd9Sstevel@tonic-gate }
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate static void
562*7c478bd9Sstevel@tonic-gate printzone(zoneid_t id)
563*7c478bd9Sstevel@tonic-gate {
564*7c478bd9Sstevel@tonic-gate 	char zone_name[ZONENAME_MAX];
565*7c478bd9Sstevel@tonic-gate 
566*7c478bd9Sstevel@tonic-gate 	if (getzonenamebyid(id, zone_name, sizeof (zone_name)) < 0)
567*7c478bd9Sstevel@tonic-gate 		(void) printf("%9d", (int)id);
568*7c478bd9Sstevel@tonic-gate 	else
569*7c478bd9Sstevel@tonic-gate 		(void) printf("%9.8s", zone_name);
570*7c478bd9Sstevel@tonic-gate }
571