summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ipcrm/Makefile5
-rw-r--r--usr.bin/ipcrm/ipcrm.137
-rw-r--r--usr.bin/ipcrm/ipcrm.c147
-rw-r--r--usr.bin/ipcs/Makefile1
-rw-r--r--usr.bin/ipcs/ipc.c207
-rw-r--r--usr.bin/ipcs/ipc.h71
-rw-r--r--usr.bin/ipcs/ipcs.c214
7 files changed, 468 insertions, 214 deletions
diff --git a/usr.bin/ipcrm/Makefile b/usr.bin/ipcrm/Makefile
index 9c0e45c..47e4ccc 100644
--- a/usr.bin/ipcrm/Makefile
+++ b/usr.bin/ipcrm/Makefile
@@ -1,5 +1,10 @@
# $FreeBSD$
PROG= ipcrm
+SRCS= ipcrm.c ipc.c
+DPADD= ${LIBKVM}
+LDADD= -lkvm
+CFLAGS+=-I${.CURDIR}/../ipcs
+.PATH: ${.CURDIR}/../ipcs
.include <bsd.prog.mk>
diff --git a/usr.bin/ipcrm/ipcrm.1 b/usr.bin/ipcrm/ipcrm.1
index 9e2a470..30378f2 100644
--- a/usr.bin/ipcrm/ipcrm.1
+++ b/usr.bin/ipcrm/ipcrm.1
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\""
-.Dd August 8, 1994
+.Dd December 12, 2007
.Dt IPCRM 1
.Os
.Sh NAME
@@ -31,6 +31,8 @@
.Nd "remove the specified message queues, semaphore sets, and shared segments"
.Sh SYNOPSIS
.Nm
+.Op Fl W
+.Op Fl v
.Op Fl q Ar msqid
.Op Fl m Ar shmid
.Op Fl s Ar semid
@@ -46,6 +48,31 @@ segments.
These System V IPC objects can be specified by their
creation ID or any associated key.
.Pp
+The following options are generic:
+.Bl -tag -width indent
+.It Fl v
+If specified once with -W or with -1 for an object, it will show
+all removed objects.
+If specified twice with -W or with -1 for an objects, it will show
+all removed objects and all failed removals.
+.It Fl W
+Try to wipe all specified message queues, semaphores and shared
+memory segments.
+.It Fl y
+Use the
+.Xr kvm 3
+interface instead of the
+.Xr sysctl 3
+interface to extract the required information.
+If
+.Nm
+is to operate on the running system,
+using
+.Xr kvm 3
+will require read privileges to
+.Pa /dev/kmem .
+.El
+.Pp
The following options are used to specify which IPC objects will be removed.
Any number and combination of these options can be used:
.Bl -tag -width indent
@@ -80,5 +107,13 @@ from the system.
The identifiers and keys associated with these System V IPC objects can be
determined by using
.Xr ipcs 1 .
+If the identifier or the key is -1, it will remove all these objects.
.Sh SEE ALSO
.Xr ipcs 1
+.Sh HISTORY
+The wiping of all System V IPC objects was first implemented in
+.Fx 6.4 and 7.1.
+.Sh AUTHORS
+The original author was Adam Glass.
+The wiping of all System V IPC objects was thought up by Callum
+Gibson and extended and implemented by Edwin Groothuis.
diff --git a/usr.bin/ipcrm/ipcrm.c b/usr.bin/ipcrm/ipcrm.c
index 1ced896..32887e0 100644
--- a/usr.bin/ipcrm/ipcrm.c
+++ b/usr.bin/ipcrm/ipcrm.c
@@ -27,42 +27,47 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/msg.h>
+#include <sys/param.h>
+#define _KERNEL
#include <sys/sem.h>
#include <sys/shm.h>
+#include <sys/msg.h>
+#undef _KERNEL
#include <ctype.h>
#include <err.h>
-#include <signal.h>
+#include <grp.h>
+#include <kvm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
-#define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
- (x == 'M' ? "shared memory segment" : "semaphore"))
+#include "ipc.h"
+
+int signaled;
+int errflg;
+int rmverbose = 0;
-int signaled;
+void usage(void);
-void usage(void);
-int msgrm(key_t, int);
-int shmrm(key_t, int);
-int semrm(key_t, int);
-void not_configured(int);
+int msgrm(key_t, int);
+int shmrm(key_t, int);
+int semrm(key_t, int);
+void not_configured(int);
void
usage(void)
{
fprintf(stderr,
- "usage: ipcrm [-q msqid] [-m shmid] [-s semid]\n"
+ "usage: ipcrm [-W] [-v[v]]\n"
+ " [-q msqid] [-m shmid] [-s semid]\n"
" [-Q msgkey] [-M shmkey] [-S semkey] ...\n");
exit(1);
}
@@ -71,11 +76,40 @@ int
msgrm(key_t key, int id)
{
+ if (key == -1 || id == -1) {
+ struct msqid_kernel *kxmsqids;
+ size_t kxmsqids_len;
+ int num;
+
+ kget(X_MSGINFO, &msginfo, sizeof(msginfo));
+ kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni;
+ kxmsqids = malloc(kxmsqids_len);
+ kget(X_MSQIDS, kxmsqids, kxmsqids_len);
+ num = msginfo.msgmni;
+ while (num-- && !signaled)
+ if (kxmsqids[num].u.msg_qbytes != 0) {
+ id = IXSEQ_TO_IPCID(num,
+ kxmsqids[num].u.msg_perm);
+ if (msgctl(id, IPC_RMID, NULL) < 0) {
+ if (rmverbose > 1)
+ warn("msqid(%d): ", id);
+ errflg++;
+ } else
+ if (rmverbose)
+ printf(
+ "Removed %s %d\n",
+ IPC_TO_STRING('Q'),
+ id);
+ }
+ return signaled ? -1 : 0; /* errors maybe handled above */
+ }
+
if (key) {
id = msgget(key, 0);
if (id == -1)
return -1;
}
+
return msgctl(id, IPC_RMID, NULL);
}
@@ -83,11 +117,40 @@ int
shmrm(key_t key, int id)
{
+ if (key == -1 || id == -1) {
+ struct shmid_kernel *kxshmids;
+ size_t kxshmids_len;
+ int num;
+
+ kget(X_SHMINFO, &shminfo, sizeof(shminfo));
+ kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni;
+ kxshmids = malloc(kxshmids_len);
+ kget(X_SHMSEGS, kxshmids, kxshmids_len);
+ num = shminfo.shmmni;
+ while (num-- && !signaled)
+ if (kxshmids[num].u.shm_perm.mode & 0x0800) {
+ id = IXSEQ_TO_IPCID(num,
+ kxshmids[num].u.shm_perm);
+ if (shmctl(id, IPC_RMID, NULL) < 0) {
+ if (rmverbose > 1)
+ warn("shmid(%d): ", id);
+ errflg++;
+ } else
+ if (rmverbose)
+ printf(
+ "Removed %s %d\n",
+ IPC_TO_STRING('M'),
+ id);
+ }
+ return signaled ? -1 : 0; /* errors maybe handled above */
+ }
+
if (key) {
id = shmget(key, 0, 0);
if (id == -1)
return -1;
}
+
return shmctl(id, IPC_RMID, NULL);
}
@@ -96,11 +159,40 @@ semrm(key_t key, int id)
{
union semun arg;
+ if (key == -1 || id == -1) {
+ struct semid_kernel *kxsema;
+ size_t kxsema_len;
+ int num;
+
+ kget(X_SEMINFO, &seminfo, sizeof(seminfo));
+ kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni;
+ kxsema = malloc(kxsema_len);
+ kget(X_SEMA, kxsema, kxsema_len);
+ num = seminfo.semmni;
+ while (num-- && !signaled)
+ if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) {
+ id = IXSEQ_TO_IPCID(num,
+ kxsema[num].u.sem_perm);
+ if (semctl(id, IPC_RMID, NULL) < 0) {
+ if (rmverbose > 1)
+ warn("semid(%d): ", id);
+ errflg++;
+ } else
+ if (rmverbose)
+ printf(
+ "Removed %s %d\n",
+ IPC_TO_STRING('S'),
+ id);
+ }
+ return signaled ? -1 : 0; /* errors maybe handled above */
+ }
+
if (key) {
id = semget(key, 0, 0);
if (id == -1)
return -1;
}
+
return semctl(id, 0, IPC_RMID, arg);
}
@@ -114,12 +206,26 @@ not_configured(int signo __unused)
int
main(int argc, char *argv[])
{
- int c, result, errflg, target_id;
+ int c, result, target_id;
key_t target_key;
+ while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
+
+ signaled = 0;
+ switch (c) {
+ case 'v':
+ rmverbose++;
+ break;
+ case 'y':
+ use_sysctl = 0;
+ break;
+ }
+ }
+
+ optind = 1;
errflg = 0;
signal(SIGSYS, not_configured);
- while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:")) != -1) {
+ while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
signaled = 0;
switch (c) {
@@ -171,6 +277,15 @@ main(int argc, char *argv[])
IPC_TO_STRING(c));
}
break;
+ case 'v':
+ case 'y':
+ /* Handled in other getopt() loop */
+ break;
+ case 'W':
+ msgrm(-1, 0);
+ shmrm(-1, 0);
+ semrm(-1, 0);
+ break;
case ':':
fprintf(stderr,
"option -%c requires an argument\n", optopt);
diff --git a/usr.bin/ipcs/Makefile b/usr.bin/ipcs/Makefile
index af76777..8ee1d43 100644
--- a/usr.bin/ipcs/Makefile
+++ b/usr.bin/ipcs/Makefile
@@ -1,6 +1,7 @@
# $FreeBSD$
PROG= ipcs
+SRCS= ipcs.c ipc.c
DPADD= ${LIBKVM}
LDADD= -lkvm
diff --git a/usr.bin/ipcs/ipc.c b/usr.bin/ipcs/ipc.c
new file mode 100644
index 0000000..dfb4bae
--- /dev/null
+++ b/usr.bin/ipcs/ipc.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The split of ipcs.c into ipcs.c and ipc.c to accomodate the
+ * changes in ipcrm.c was done by Edwin Groothuis <edwin@FreeBSD.org>
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#define _KERNEL
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/msg.h>
+#undef _KERNEL
+
+#include <assert.h>
+#include <err.h>
+#include <kvm.h>
+#include <nlist.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#include "ipc.h"
+
+int use_sysctl = 1;
+struct semid_kernel *sema;
+struct seminfo seminfo;
+struct msginfo msginfo;
+struct msqid_kernel *msqids;
+struct shminfo shminfo;
+struct shmid_kernel *shmsegs;
+void kget(int idx, void *addr, size_t size);
+
+struct nlist symbols[] = {
+ {"sema"},
+ {"seminfo"},
+ {"msginfo"},
+ {"msqids"},
+ {"shminfo"},
+ {"shmsegs"},
+ {NULL}
+};
+
+#define SHMINFO_XVEC X(shmmax, sizeof(u_long)) \
+ X(shmmin, sizeof(u_long)) \
+ X(shmmni, sizeof(u_long)) \
+ X(shmseg, sizeof(u_long)) \
+ X(shmall, sizeof(u_long))
+
+#define SEMINFO_XVEC X(semmap, sizeof(int)) \
+ X(semmni, sizeof(int)) \
+ X(semmns, sizeof(int)) \
+ X(semmnu, sizeof(int)) \
+ X(semmsl, sizeof(int)) \
+ X(semopm, sizeof(int)) \
+ X(semume, sizeof(int)) \
+ X(semusz, sizeof(int)) \
+ X(semvmx, sizeof(int)) \
+ X(semaem, sizeof(int))
+
+#define MSGINFO_XVEC X(msgmax, sizeof(int)) \
+ X(msgmni, sizeof(int)) \
+ X(msgmnb, sizeof(int)) \
+ X(msgtql, sizeof(int)) \
+ X(msgssz, sizeof(int)) \
+ X(msgseg, sizeof(int))
+
+#define X(a, b) { "kern.ipc." #a, offsetof(TYPEC, a), (b) },
+#define TYPEC struct shminfo
+struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } };
+#undef TYPEC
+#define TYPEC struct seminfo
+struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } };
+#undef TYPEC
+#define TYPEC struct msginfo
+struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } };
+#undef TYPEC
+#undef X
+
+kvm_t *kd;
+
+void
+sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr)
+{
+ struct scgs_vector *xp;
+ size_t tsiz;
+ int rv;
+
+ for (xp = vecarr; xp->sysctl != NULL; xp++) {
+ assert(xp->offset <= size);
+ tsiz = xp->size;
+ rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset,
+ &tsiz, NULL, 0);
+ if (rv == -1)
+ err(1, "sysctlbyname: %s", xp->sysctl);
+ if (tsiz != xp->size)
+ errx(1, "%s size mismatch (expected %d, got %d)",
+ xp->sysctl, xp->size, tsiz);
+ }
+}
+
+void
+kget(int idx, void *addr, size_t size)
+{
+ char *symn; /* symbol name */
+ size_t tsiz;
+ int rv;
+ unsigned long kaddr;
+ const char *sym2sysctl[] = { /* symbol to sysctl name table */
+ "kern.ipc.sema",
+ "kern.ipc.seminfo",
+ "kern.ipc.msginfo",
+ "kern.ipc.msqids",
+ "kern.ipc.shminfo",
+ "kern.ipc.shmsegs" };
+
+ assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl));
+ if (!use_sysctl) {
+ symn = symbols[idx].n_name;
+ if (*symn == '_')
+ symn++;
+ if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0)
+ errx(1, "symbol %s undefined", symn);
+ /*
+ * For some symbols, the value we retrieve is
+ * actually a pointer; since we want the actual value,
+ * we have to manually dereference it.
+ */
+ switch (idx) {
+ case X_MSQIDS:
+ tsiz = sizeof(msqids);
+ rv = kvm_read(kd, symbols[idx].n_value,
+ &msqids, tsiz);
+ kaddr = (u_long)msqids;
+ break;
+ case X_SHMSEGS:
+ tsiz = sizeof(shmsegs);
+ rv = kvm_read(kd, symbols[idx].n_value,
+ &shmsegs, tsiz);
+ kaddr = (u_long)shmsegs;
+ break;
+ case X_SEMA:
+ tsiz = sizeof(sema);
+ rv = kvm_read(kd, symbols[idx].n_value,
+ &sema, tsiz);
+ kaddr = (u_long)sema;
+ break;
+ default:
+ rv = tsiz = 0;
+ kaddr = symbols[idx].n_value;
+ break;
+ }
+ if ((unsigned)rv != tsiz)
+ errx(1, "%s: %s", symn, kvm_geterr(kd));
+ if ((unsigned)kvm_read(kd, kaddr, addr, size) != size)
+ errx(1, "%s: %s", symn, kvm_geterr(kd));
+ } else {
+ switch (idx) {
+ case X_SHMINFO:
+ sysctlgatherstruct(addr, size, shminfo_scgsv);
+ break;
+ case X_SEMINFO:
+ sysctlgatherstruct(addr, size, seminfo_scgsv);
+ break;
+ case X_MSGINFO:
+ sysctlgatherstruct(addr, size, msginfo_scgsv);
+ break;
+ default:
+ tsiz = size;
+ rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz,
+ NULL, 0);
+ if (rv == -1)
+ err(1, "sysctlbyname: %s", sym2sysctl[idx]);
+ if (tsiz != size)
+ errx(1, "%s size mismatch "
+ "(expected %d, got %d)",
+ sym2sysctl[idx], size, tsiz);
+ break;
+ }
+ }
+}
diff --git a/usr.bin/ipcs/ipc.h b/usr.bin/ipcs/ipc.h
new file mode 100644
index 0000000..a7a70de
--- /dev/null
+++ b/usr.bin/ipcs/ipc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1994 SigmaSoft, Th. Lockert <tholo@sigmasoft.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The split of ipcs.c into ipcs.c and ipc.c to accomodate the
+ * changes in ipcrm.c was done by Edwin Groothuis <edwin@FreeBSD.org>
+ *
+ * $FreeBSD$
+ */
+
+/* Part of struct nlist symbols[] */
+#define X_SEMA 0
+#define X_SEMINFO 1
+#define X_MSGINFO 2
+#define X_MSQIDS 3
+#define X_SHMINFO 4
+#define X_SHMSEGS 5
+
+#define SHMINFO 1
+#define SHMTOTAL 2
+#define MSGINFO 4
+#define MSGTOTAL 8
+#define SEMINFO 16
+#define SEMTOTAL 32
+
+#define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
+#define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
+ (x == 'M' ? "shared memory segment" : "semaphore"))
+
+/* SysCtlGatherStruct structure. */
+struct scgs_vector {
+ const char *sysctl;
+ off_t offset;
+ size_t size;
+};
+
+void kget(int idx, void *addr, size_t size);
+void sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec);
+
+extern int use_sysctl;
+extern struct nlist symbols[];
+extern kvm_t *kd;
+
+extern struct semid_kernel *sema;
+extern struct seminfo seminfo;
+extern struct msginfo msginfo;
+extern struct msqid_kernel *msqids;
+extern struct shminfo shminfo;
+extern struct shmid_kernel *shmsegs;
diff --git a/usr.bin/ipcs/ipcs.c b/usr.bin/ipcs/ipcs.c
index 322f9a3..eb50ed6 100644
--- a/usr.bin/ipcs/ipcs.c
+++ b/usr.bin/ipcs/ipcs.c
@@ -28,54 +28,32 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
#include <sys/param.h>
-#include <sys/time.h>
#include <sys/proc.h>
-#include <sys/sysctl.h>
#define _KERNEL
-#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#undef _KERNEL
-#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <grp.h>
#include <kvm.h>
#include <limits.h>
-#include <nlist.h>
-#include <paths.h>
#include <pwd.h>
-#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-/* SysCtlGatherStruct structure. */
-struct scgs_vector {
- const char *sysctl;
- off_t offset;
- size_t size;
-};
-
-int use_sysctl = 1;
-struct semid_kernel *sema;
-struct seminfo seminfo;
-struct msginfo msginfo;
-struct msqid_kernel *msqids;
-struct shminfo shminfo;
-struct shmid_kernel *shmsegs;
+#include "ipc.h"
char *fmt_perm(u_short);
void cvt_time(time_t, char *);
-void sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vec);
-void kget(int idx, void *addr, size_t size);
void usage(void);
uid_t user2uid(char *username);
+
void print_kmsqtotal(struct msginfo msginfo);
void print_kmsqheader(int option);
void print_kmsqptr(int i, int option, struct msqid_kernel *kmsqptr);
@@ -86,60 +64,6 @@ void print_ksemtotal(struct seminfo seminfo);
void print_ksemheader(int option);
void print_ksemptr(int i, int option, struct semid_kernel *ksemaptr);
-static struct nlist symbols[] = {
- {"sema"},
-#define X_SEMA 0
- {"seminfo"},
-#define X_SEMINFO 1
- {"msginfo"},
-#define X_MSGINFO 2
- {"msqids"},
-#define X_MSQIDS 3
- {"shminfo"},
-#define X_SHMINFO 4
- {"shmsegs"},
-#define X_SHMSEGS 5
- {NULL}
-};
-
-#define SHMINFO_XVEC X(shmmax, sizeof(u_long)) \
- X(shmmin, sizeof(u_long)) \
- X(shmmni, sizeof(u_long)) \
- X(shmseg, sizeof(u_long)) \
- X(shmall, sizeof(u_long))
-
-#define SEMINFO_XVEC X(semmap, sizeof(int)) \
- X(semmni, sizeof(int)) \
- X(semmns, sizeof(int)) \
- X(semmnu, sizeof(int)) \
- X(semmsl, sizeof(int)) \
- X(semopm, sizeof(int)) \
- X(semume, sizeof(int)) \
- X(semusz, sizeof(int)) \
- X(semvmx, sizeof(int)) \
- X(semaem, sizeof(int))
-
-#define MSGINFO_XVEC X(msgmax, sizeof(int)) \
- X(msgmni, sizeof(int)) \
- X(msgmnb, sizeof(int)) \
- X(msgtql, sizeof(int)) \
- X(msgssz, sizeof(int)) \
- X(msgseg, sizeof(int))
-
-#define X(a, b) { "kern.ipc." #a, offsetof(TYPEC, a), (b) },
-#define TYPEC struct shminfo
-struct scgs_vector shminfo_scgsv[] = { SHMINFO_XVEC { NULL } };
-#undef TYPEC
-#define TYPEC struct seminfo
-struct scgs_vector seminfo_scgsv[] = { SEMINFO_XVEC { NULL } };
-#undef TYPEC
-#define TYPEC struct msginfo
-struct scgs_vector msginfo_scgsv[] = { MSGINFO_XVEC { NULL } };
-#undef TYPEC
-#undef X
-
-static kvm_t *kd;
-
char *
fmt_perm(u_short mode)
{
@@ -173,12 +97,6 @@ cvt_time(time_t t, char *buf)
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
}
-#define SHMINFO 1
-#define SHMTOTAL 2
-#define MSGINFO 4
-#define MSGTOTAL 8
-#define SEMINFO 16
-#define SEMTOTAL 32
#define BIGGEST 1
#define CREATOR 2
@@ -198,9 +116,6 @@ main(int argc, char *argv[])
while ((i = getopt(argc, argv, "MmQqSsabC:cN:optTu:y")) != -1)
switch (i) {
- case 'T':
- display = SHMTOTAL | MSGTOTAL | SEMTOTAL;
- break;
case 'a':
option |= BIGGEST | CREATOR | OUTSTANDING | PID | TIME;
break;
@@ -240,6 +155,9 @@ main(int argc, char *argv[])
case 's':
display = SEMINFO;
break;
+ case 'T':
+ display = SHMTOTAL | MSGTOTAL | SEMTOTAL;
+ break;
case 't':
option |= TIME;
break;
@@ -364,7 +282,8 @@ main(int argc, char *argv[])
print_ksemheader(option);
for (i = 0; i < seminfo.semmni; i += 1) {
- if ((kxsema[i].u.sem_perm.mode & SEM_ALLOC) != 0) {
+ if ((kxsema[i].u.sem_perm.mode & SEM_ALLOC)
+ != 0) {
if (user &&
uid != kxsema[i].u.sem_perm.uid)
continue;
@@ -408,7 +327,8 @@ print_kmsqtotal(struct msginfo msginfo)
msginfo.msgseg);
}
-void print_kmsqheader(int option) {
+void print_kmsqheader(int option)
+{
printf("Message Queues:\n");
printf("T %12s %12s %-11s %-8s %-8s",
@@ -435,7 +355,7 @@ print_kmsqptr(int i, int option, struct msqid_kernel *kmsqptr)
cvt_time(kmsqptr->u.msg_rtime, rtime_buf);
cvt_time(kmsqptr->u.msg_ctime, ctime_buf);
- printf("q %12d %12d %s %8s %8s",
+ printf("q %12d %12d %s %-8s %-8s",
IXSEQ_TO_IPCID(i, kmsqptr->u.msg_perm),
(int)kmsqptr->u.msg_perm.key,
fmt_perm(kmsqptr->u.msg_perm.mode),
@@ -443,7 +363,7 @@ print_kmsqptr(int i, int option, struct msqid_kernel *kmsqptr)
group_from_gid(kmsqptr->u.msg_perm.gid, 0));
if (option & CREATOR)
- printf(" %8s %8s",
+ printf(" %-8s %-8s",
user_from_uid(kmsqptr->u.msg_perm.cuid, 0),
group_from_gid(kmsqptr->u.msg_perm.cgid, 0));
@@ -515,7 +435,7 @@ print_kshmptr(int i, int option, struct shmid_kernel *kshmptr)
cvt_time(kshmptr->u.shm_dtime, dtime_buf);
cvt_time(kshmptr->u.shm_ctime, ctime_buf);
- printf("m %12d %12d %s %8s %8s",
+ printf("m %12d %12d %s %-8s %-8s",
IXSEQ_TO_IPCID(i, kshmptr->u.shm_perm),
(int)kshmptr->u.shm_perm.key,
fmt_perm(kshmptr->u.shm_perm.mode),
@@ -523,7 +443,7 @@ print_kshmptr(int i, int option, struct shmid_kernel *kshmptr)
group_from_gid(kshmptr->u.shm_perm.gid, 0));
if (option & CREATOR)
- printf(" %8s %8s",
+ printf(" %-8s %-8s",
user_from_uid(kshmptr->u.shm_perm.cuid, 0),
group_from_gid(kshmptr->u.shm_perm.cgid, 0));
@@ -577,7 +497,8 @@ print_ksemtotal(struct seminfo seminfo)
}
void
-print_ksemheader(int option) {
+print_ksemheader(int option)
+{
printf("Semaphores:\n");
printf("T %12s %12s %-11s %-8s %-8s",
@@ -599,7 +520,7 @@ print_ksemptr(int i, int option, struct semid_kernel *ksemaptr)
cvt_time(ksemaptr->u.sem_otime, otime_buf);
cvt_time(ksemaptr->u.sem_ctime, ctime_buf);
- printf("s %12d %12d %s %8s %8s",
+ printf("s %12d %12d %s %-8s %-8s",
IXSEQ_TO_IPCID(i, ksemaptr->u.sem_perm),
(int)ksemaptr->u.sem_perm.key,
fmt_perm(ksemaptr->u.sem_perm.mode),
@@ -607,7 +528,7 @@ print_ksemptr(int i, int option, struct semid_kernel *ksemaptr)
group_from_gid(ksemaptr->u.sem_perm.gid, 0));
if (option & CREATOR)
- printf(" %8s %8s",
+ printf(" %-8s %-8s",
user_from_uid(ksemaptr->u.sem_perm.cuid, 0),
group_from_gid(ksemaptr->u.sem_perm.cgid, 0));
@@ -623,107 +544,6 @@ print_ksemptr(int i, int option, struct semid_kernel *ksemaptr)
printf("\n");
}
-void
-sysctlgatherstruct(void *addr, size_t size, struct scgs_vector *vecarr)
-{
- struct scgs_vector *xp;
- size_t tsiz;
- int rv;
-
- for (xp = vecarr; xp->sysctl != NULL; xp++) {
- assert(xp->offset <= size);
- tsiz = xp->size;
- rv = sysctlbyname(xp->sysctl, (char *)addr + xp->offset,
- &tsiz, NULL, 0);
- if (rv == -1)
- err(1, "sysctlbyname: %s", xp->sysctl);
- if (tsiz != xp->size)
- errx(1, "%s size mismatch (expected %d, got %d)",
- xp->sysctl, xp->size, tsiz);
- }
-}
-
-void
-kget(int idx, void *addr, size_t size)
-{
- char *symn; /* symbol name */
- size_t tsiz;
- int rv;
- unsigned long kaddr;
- const char *sym2sysctl[] = { /* symbol to sysctl name table */
- "kern.ipc.sema",
- "kern.ipc.seminfo",
- "kern.ipc.msginfo",
- "kern.ipc.msqids",
- "kern.ipc.shminfo",
- "kern.ipc.shmsegs" };
-
- assert((unsigned)idx <= sizeof(sym2sysctl) / sizeof(*sym2sysctl));
- if (!use_sysctl) {
- symn = symbols[idx].n_name;
- if (*symn == '_')
- symn++;
- if (symbols[idx].n_type == 0 || symbols[idx].n_value == 0)
- errx(1, "symbol %s undefined", symn);
- /*
- * For some symbols, the value we retrieve is
- * actually a pointer; since we want the actual value,
- * we have to manually dereference it.
- */
- switch (idx) {
- case X_MSQIDS:
- tsiz = sizeof(msqids);
- rv = kvm_read(kd, symbols[idx].n_value,
- &msqids, tsiz);
- kaddr = (u_long)msqids;
- break;
- case X_SHMSEGS:
- tsiz = sizeof(shmsegs);
- rv = kvm_read(kd, symbols[idx].n_value,
- &shmsegs, tsiz);
- kaddr = (u_long)shmsegs;
- break;
- case X_SEMA:
- tsiz = sizeof(sema);
- rv = kvm_read(kd, symbols[idx].n_value,
- &sema, tsiz);
- kaddr = (u_long)sema;
- break;
- default:
- rv = tsiz = 0;
- kaddr = symbols[idx].n_value;
- break;
- }
- if ((unsigned)rv != tsiz)
- errx(1, "%s: %s", symn, kvm_geterr(kd));
- if ((unsigned)kvm_read(kd, kaddr, addr, size) != size)
- errx(1, "%s: %s", symn, kvm_geterr(kd));
- } else {
- switch (idx) {
- case X_SHMINFO:
- sysctlgatherstruct(addr, size, shminfo_scgsv);
- break;
- case X_SEMINFO:
- sysctlgatherstruct(addr, size, seminfo_scgsv);
- break;
- case X_MSGINFO:
- sysctlgatherstruct(addr, size, msginfo_scgsv);
- break;
- default:
- tsiz = size;
- rv = sysctlbyname(sym2sysctl[idx], addr, &tsiz,
- NULL, 0);
- if (rv == -1)
- err(1, "sysctlbyname: %s", sym2sysctl[idx]);
- if (tsiz != size)
- errx(1, "%s size mismatch "
- "(expected %d, got %d)",
- sym2sysctl[idx], size, tsiz);
- break;
- }
- }
-}
-
uid_t
user2uid(char *username)
{
OpenPOWER on IntegriCloud