diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ipcrm/Makefile | 5 | ||||
-rw-r--r-- | usr.bin/ipcrm/ipcrm.1 | 37 | ||||
-rw-r--r-- | usr.bin/ipcrm/ipcrm.c | 147 | ||||
-rw-r--r-- | usr.bin/ipcs/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/ipcs/ipc.c | 207 | ||||
-rw-r--r-- | usr.bin/ipcs/ipc.h | 71 | ||||
-rw-r--r-- | usr.bin/ipcs/ipcs.c | 214 |
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) { |