1
0
Files
irix-657m-src/eoe/cmd/ipc/ipcs.c
2022-09-29 17:59:04 +03:00

447 lines
9.7 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* #ident "@(#)ipc:/ipcs.c 1.9" */
#ident "$Revision: 1.25 $"
/*
** ipcs - IPC status
** Examine and print certain things about message queues, semaphores,
** and shared memory.
*/
#include "sys/types.h"
#include "sys/ipc.h"
#include "sys/msg.h"
#include "sys/sem.h"
#include "sys/shm.h"
#include <unistd.h>
#include "errno.h"
#include "nlist.h"
#include "fcntl.h"
#include "time.h"
#include "grp.h"
#include "pwd.h"
#include "getopt.h"
#include "stdio.h"
#include "stdlib.h"
#include "sys/sysmp.h"
#include "sys/sysget.h"
#include "sys.s"
extern int syscall(int, ...);
#define MSG 0
#define MSGINFO 2
void hp(char, char *, struct ipc_perm *, int, int);
void tp(time_t);
static void lseeke(int, off_t, int);
static void reade(int fildes, void *buf, size_t nbyte);
void print_shmstat(void);
void print_semstat(void);
#if (_MIPS_SZLONG == 64)
#define NLIST nlist64
#else
#define NLIST nlist
#endif /* if 64bit */
struct NLIST nl[] = { /* name list entries for IPC facilities */
{"msgque", 0, 0, 0},
{"msginfo", 0, 0, 0},
{NULL}
};
char chdr[] = "T ID KEY MODE OWNER GROUP",
/* common header format */
chdr2[] = " CREATOR CGROUP",
/* c option header format */
*name = "/unix", /* name list file */
*mem = "/dev/kmem", /* memory file */
opts[] = "abcemopqstC:N:";/* allowable options for getopt */
extern char *optarg; /* arg pointer for getopt */
int bflg, /* biggest size:
segsz on m; qbytes on q; nsems on s */
cflg, /* creator's login and group names */
eflg, /* shared memory extentions */
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 */
err; /* option error count */
int Nflg; /* specified -N */
main(
int argc, /* arg count */
char **argv) /* arg vector */
{
register int i, /* loop control */
md, /* memory file file descriptor */
o; /* option flag */
time_t curtime;/* date in memory file */
struct msqid_ds *qds; /* message queue data structure */
struct msginfo msginfo; /* message information structure */
struct msqid_ds *qp;
sgt_cookie_t ck;
/* Go through the options and set flags. */
while((o = getopt(argc, argv, opts)) != EOF)
switch(o) {
case 'a':
bflg = cflg = oflg = pflg = tflg = 1;
break;
case 'b':
bflg = 1;
break;
case 'c':
cflg = 1;
break;
case 'C':
mem = optarg;
break;
case 'e':
eflg = 1;
break;
case 'm':
mflg = 1;
break;
case 'N':
name = optarg;
Nflg++;
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 '?':
err++;
break;
}
if(err || (optind < argc)) {
fprintf(stderr,
"usage: ipcs [-abcemopqst] [-C corefile] [-N namelist]\n");
exit(1);
}
if((mflg + qflg + sflg) == 0)
mflg = qflg = sflg = 1;
/* Check out namelist and memory files. */
if (Nflg) {
NLIST(name, nl);
if(!nl[MSG].n_value) {
fprintf(stderr, "ipcs: no namelist\n");
exit(1);
}
}
if(Nflg && ((md = open(mem, O_RDONLY)) < 0)) {
fprintf(stderr, "ipcs: no memory file\n");
exit(1);
}
if (Nflg && (qflg || sflg)) {
/* msgque is a struct msqid_ds **, so we have
* to step through the indirection. But only if
* Nflg is set - otherwise sysmp returns the
* correct value.
*/
lseeke(md, nl[MSG].n_value, 0);
reade(md, &nl[MSG].n_value, sizeof(nl[MSG].n_value));
}
curtime = time(NULL);
printf("IPC status from %s as of %s", mem, ctime(&curtime));
/* Print Message Queue status report. */
if(qflg) {
if (Nflg) {
lseeke(md, (long)nl[MSGINFO].n_value, 0);
reade(md, &msginfo, sizeof(msginfo));
lseeke(md, (long)nl[MSG].n_value, 0);
}
else {
SGT_COOKIE_INIT(&ck);
SGT_COOKIE_SET_KSYM(&ck, KSYM_MSGINFO);
if (sysget(SGT_KSYM, (char *)&msginfo, sizeof(msginfo),
SGT_READ, &ck) < 0) {
perror("SGT_READ msginfo");
exit(1);
}
}
printf("%s%s%s%s%s%s\nMessage Queues:\n", chdr,
cflg ? chdr2 : "",
oflg ? " CBYTES QNUM" : "",
bflg ? " QBYTES" : "",
pflg ? " LSPID LRPID" : "",
tflg ? " STIME RTIME CTIME " : "");
qds = (struct msqid_ds *)calloc(msginfo.msgmni,
sizeof(struct msqid_ds));
if (!qds) {
fprintf(stderr, "no memory for message queue\n");
exit(1);
}
if (!Nflg) {
SGT_COOKIE_INIT(&ck);
if (sysget(SGT_MSGQUEUE, (char *)qds, msginfo.msgmni *
sizeof(struct msqid_ds), SGT_READ,
&ck) < 0) {
perror("SGT_READ msgqueue");
exit(1);
}
}
for (i = 0; i < msginfo.msgmni; i++) {
if (Nflg) {
lseeke(md, (long)nl[MSG].n_value +
(i*sizeof(int *)), 0);
reade(md, &qp, sizeof(qp));
if (qp == NULL) {
continue;
}
lseeke(md, (off_t)qp, 0);
reade(md, &qds[i], sizeof(struct msqid_ds));
}
if(!(qds[i].msg_perm.mode & IPC_ALLOC)) {
continue;
}
hp('q', "SRrw-rw-rw-", &qds[i].msg_perm, i,
msginfo.msgmni);
if(oflg)
printf("%7u%6u", qds[i].msg_cbytes,
qds[i].msg_qnum);
if(bflg)
printf("%7u", qds[i].msg_qbytes);
if(pflg)
printf("%6u%6u", qds[i].msg_lspid,
qds[i].msg_lrpid);
if(tflg) {
tp(qds[i].msg_stime);
tp(qds[i].msg_rtime);
tp(qds[i].msg_ctime);
}
printf("\n");
}
}
/* Print Shared Memory status report. */
if (mflg)
print_shmstat();
/* Print Semaphore facility status. */
if (sflg)
print_semstat();
exit(0);
/* NOTREACHED */
}
extern int __semstatus(struct semstat *);
void
print_semstat(void)
{
struct semstat semstat;
int rv;
if (bflg || tflg || !qflg && !mflg)
printf("%s%s%s%s\n", chdr,
cflg ? chdr2 : "",
bflg ? " NSEMS" : "",
tflg ? " OTIME CTIME " : "");
printf("Semaphores:\n");
semstat.sm_id = 0;
semstat.sm_location = -1LL;
while (((rv = __semstatus(&semstat)) == 0) || (errno == EACCES)) {
struct semid_ds *semds;
if (!rv && (errno == EACCES))
continue;
semds = &semstat.sm_semds;
hp('s', "--ra-ra-ra-", &semds->sem_perm, semstat.sm_id, 0);
if(bflg)
printf("%6u", semds->sem_nsems);
if(tflg) {
tp(semds->sem_otime);
tp(semds->sem_ctime);
}
printf("\n");
}
}
extern int __shmstatus(struct shmstat *);
void
print_shmstat(void)
{
struct shmstat shmstat;
int rv;
if (oflg || bflg || tflg || !qflg || eflg)
printf("%s%s%s%s%s%s%s\n", chdr,
cflg ? chdr2 : "",
oflg ? " NATTCH " : "",
bflg ? " SEGSZ " : "",
pflg ? " CPID LPID" : "",
tflg ? " ATIME DTIME CTIME " : "",
eflg ? " EXTENSIONS" : "");
printf("Shared Memory:\n");
shmstat.sh_id = 0;
shmstat.sh_location = -1LL;
while (((rv = __shmstatus(&shmstat)) == 0) || (errno == EACCES)) {
struct shmid_ds *shmds;
shmds = &shmstat.sh_shmds;
if (!rv && (errno == EACCES)) {
if (shmds->shm_cpid == NOPID)
continue;
/* Special case: We created this segments, but we
didn't give ourselves read access. MP_SHMSTAT
fills in just the cpid/cgid/cuid fields. We'll
overwrite the uid and gid fields with cuid/cgid
just to make it more obvious who should do
something about this situation.
*/
shmds->shm_perm.uid = shmds->shm_perm.cuid;
shmds->shm_perm.gid = shmds->shm_perm.cgid;
}
hp('m', "DCrw-rw-rw-", &shmds->shm_perm,
shmstat.sh_id,
0);
if(oflg)
printf("%7u ", shmds->shm_nattch);
if(bflg)
printf("%9ld ", shmds->shm_segsz);
if(pflg)
printf("%6u%6u", shmds->shm_cpid,
shmds->shm_lpid);
if(tflg) {
tp(shmds->shm_atime);
tp(shmds->shm_dtime);
tp(shmds->shm_ctime);
}
if (eflg) {
printf(" %c", shmds->shm_perm.mode & IPC_AUTORMID ? 'A' : ' ');
}
printf("\n");
}
}
/*
** lseeke - lseek with error exit
*/
static void
lseeke(
int fd,
off_t offset,
int whence)
{
#if _MIPS_SZPTR == 64
offset &= 0x7fffffffffffffff;
#else
offset &= 0x7fffffff;
#endif
if (lseek(fd, offset, whence) == -1) {
perror("ipcs: seek error");
exit(1);
}
}
/*
** reade - read with error exit
*/
static void
reade(
int fd,
void *bufaddr,
size_t size)
{
if (read(fd, bufaddr, size) != size) {
perror("ipcs: read error");
exit(1);
}
}
/*
** hp - common header print
*/
void
hp(
char type, /* facility type */
char *modesp,/* ptr to mode replacement characters */
struct ipc_perm *permp, /* ptr to permission structure */
int slot, /* facility slot number */
int slots) /* # of facility slots */
{
register int i, /* loop control */
j; /* loop control */
register struct group *g; /* ptr to group group entry */
register struct passwd *u; /* ptr to user passwd entry */
printf("%c%11d%s%#8.8x ", type, slot + slots * permp->seq,
permp->key ? " " : " 0x", permp->key);
for(i = 02000;i;modesp++, i >>= 1)
printf("%c", (permp->mode & i) ? *modesp : '-');
if((u = getpwuid(permp->uid)) == NULL)
printf("%9d", permp->uid);
else
printf("%9.8s", u->pw_name);
if((g = getgrgid(permp->gid)) == NULL)
printf("%9d", permp->gid);
else
printf("%9.8s", g->gr_name);
if(cflg) {
if((u = getpwuid(permp->cuid)) == NULL)
printf("%9d", permp->cuid);
else
printf("%9.8s", u->pw_name);
if((g = getgrgid(permp->cgid)) == NULL)
printf("%9d", permp->cgid);
else
printf("%9.8s", g->gr_name);
}
}
/*
** tp - time entry printer
*/
void
tp(
time_t time) /* time to be displayed */
{
register struct tm *t; /* ptr to converted time */
if(time) {
t = localtime(&time);
printf(" %2d:%2.2d:%2.2d", t->tm_hour, t->tm_min, t->tm_sec);
} else
printf(" no-entry");
}