ipcs.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ipcs - IPC status
*
* Examine and print certain things about
* message queues, semaphores and shared memory.
*
* IPC information is obtained via msgctl64, semctl64 and shmctl64.
* As of SunOS 5.8, the IPC identifiers are obtained from msgids(),
* This ensures that the information in each msgid_ds, semid_ds or
* shmid_ds data structure that we obtain is complete and consistent,
* and allows us not to be a setgid-sys isaexec process.
*/
#include <sys/ipc_impl.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <locale.h>
#include <langinfo.h>
#include <string.h>
#include <limits.h>
#include <project.h>
#include <zone.h>
#define USAGE \
"usage: ipcs [-AabciJmopqstZ] [-D mtype] [-z zone]\n"
static char chdr[] = "T ID KEY MODE OWNER GROUP";
/* common header format */
static long mtype; /* -D: user-supplied message type */
static int bflg, /* biggest size: */
/* segsz on m; qbytes on q; nsems on s */
cflg, /* creator's login and group names */
Dflg, /* dump contents of message queues */
iflg, /* ISM attaches */
Jflg, /* dump project name */
mflg, /* shared memory status */
oflg, /* outstanding data: */
/* nattch on m; cbytes, qnum on q */
pflg, /* process id's: lrpid, lspid on q; */
/* cpid, lpid on m */
qflg, /* message queue status */
sflg, /* semaphore status */
tflg, /* times: atime, ctime, dtime on m; */
/* ctime, rtime, stime on q; */
/* ctime, otime on s */
zflg, /* show only objects from specified zone */
Zflg, /* display zone name */
err; /* option error count */
static void hp(char, char *, struct ipc_perm64 *, int);
static void jp(struct ipc_perm64 *);
static void tp(ipc_time_t);
static void dumpmsgq(int);
int
{
static int *ids; /* array of IPC identifiers from *ids() */
int o; /* option flag */
int id; /* IPC identifier */
int i;
uint_t n; /* table size */
char *dfmt; /* date format pointer */
char *endptr; /* terminator for strtol() */
(void) textdomain(TEXT_DOMAIN);
/* Go through the options and set flags. */
switch (o) {
case 'A':
break;
case 'a':
break;
case 'b':
bflg = 1;
break;
case 'c':
cflg = 1;
break;
case 'D':
gettext("ipcs: invalid message type: %s\n"),
optarg);
err++;
break;
}
Dflg = 1;
break;
case 'i':
iflg = 1;
break;
case 'J':
Jflg = 1;
break;
case 'm':
mflg = 1;
break;
case 'o':
oflg = 1;
break;
case 'p':
pflg = 1;
break;
case 'q':
qflg = 1;
break;
case 's':
sflg = 1;
break;
case 't':
tflg = 1;
break;
case 'z':
zflg = 1;
break;
case 'Z':
Zflg = 1;
break;
case '?':
err++;
break;
}
}
exit(1);
}
tbuf);
/*
* Print Message Queue status report.
*/
if (qflg) {
struct msqid_ds64 qds;
for (;;) {
perror("msgids");
exit(1);
}
if (n <= nids)
break;
}
for (i = 0; i < n; i++) {
continue;
/* ignore zone if -Z was used and -z wasn't */
continue;
if (oflg)
(void) printf(" %6llu %5llu",
if (bflg)
if (pflg)
(void) printf(" %5d %5d",
if (tflg) {
}
if (Jflg)
if (Zflg)
(void) printf("\n");
if (Dflg)
}
}
/*
* Print Shared Memory status report.
*/
if (mflg) {
struct shmid_ds64 mds;
for (;;) {
perror("shmids");
exit(1);
}
if (n <= nids)
break;
}
for (i = 0; i < n; i++) {
continue;
/* ignore zone if -Z was used and -z wasn't */
continue;
if (oflg)
if (bflg)
if (pflg)
(void) printf(" %5d %5d",
if (tflg) {
}
if (iflg)
if (Jflg)
if (Zflg)
(void) printf("\n");
}
}
/*
* Print Semaphore facility status.
*/
if (sflg) {
struct semid_ds64 sds;
union semun {
int val;
struct semid_ds64 *buf;
} semarg;
for (;;) {
perror("semids");
exit(1);
}
if (n <= nids)
break;
}
for (i = 0; i < n; i++) {
continue;
/* ignore zone if -Z was used and -z wasn't */
continue;
if (bflg)
if (tflg) {
}
if (Jflg)
if (Zflg)
(void) printf("\n");
}
}
return (0);
}
/*
* hp - common header print
*/
static void
{
int i; /* loop control */
struct group *g; /* ptr to group group entry */
struct passwd *u; /* ptr to user passwd entry */
char keyfield[16];
else
else
if (cflg) {
else
else
}
}
/*
* jp - project header print
*/
static void
{
char buf[PROJECT_BUFSZ];
PROJECT_BUFSZ)) == NULL)
else
}
/*
* tp - time entry printer
*/
void
{
struct tm *t; /* ptr to converted time */
(void) printf(" %2d:%2.2d:%2.2d",
} else {
}
}
/* Round up to a sizeof (size_t) boundary */
/*
* dumpmsgq - dump all messages on a message queue
*/
void
{
struct msgsnap_mhead *mhead;
size_t i;
/* allocate the minimum required buffer size on first time through */
/*
* Fetch all messages specified by mtype from
* the queue while leaving the queue intact.
*/
for (;;) {
/*
* Don't complain; either the user does not have
* read permission on msqid or msqid was deleted.
*/
return;
}
/* we collected all of the messages */
break;
}
/* The buffer is too small; allocate a bigger buffer */
}
/*
* Process each message in the queue (there may be none).
* The first message header starts just after the buffer header.
*/
for (i = 0; i < buf->msgsnap_nmsg; i++) {
/* advance to next message header */
/* LINTED alignment */
mhead = (struct msgsnap_mhead *)
}
}
/*
* dumpmsg - dump one message from a message queue.
*/
void
{
size_t i, j, k;
int c;
for (i = 0; i < msgsize; i += 16) {
/* first in hex */
for (j = 0; j < 16; j++) {
if ((k = i + j) < msgsize)
else
(void) printf(" ");
}
/* then in ascii */
(void) printf(" ");
for (j = 0; j < 16; j++) {
if ((k = i + j) >= msgsize)
break;
c = msg[k] & 0xff;
(void) printf("%c", c);
else
(void) printf(".");
}
(void) printf("\n");
}
}
/* convert string containing zone name or id to a numeric id */
static zoneid_t
{
exit(1);
}
return (zoneid);
}
static void
{
char zone_name[ZONENAME_MAX];
else
}