Import NetBSD ipcrm(1)
A few MINIX3-specific changes are necessary due to the fact that we are missing the System V IPC message queue system calls. Change-Id: Idd252984be9df69618cef79bcf6c676cbf915d85
This commit is contained in:
parent
7b09d0426a
commit
0502421f1b
@ -147,6 +147,7 @@
|
||||
./usr/man/man1/infokey.1 minix-man
|
||||
./usr/man/man1/install-info.1 minix-man
|
||||
./usr/man/man1/install.1 minix-man
|
||||
./usr/man/man1/ipcrm.1 minix-man
|
||||
./usr/man/man1/ipcs.1 minix-man
|
||||
./usr/man/man1/isodir.1 minix-man
|
||||
./usr/man/man1/isoinfo.1 minix-man
|
||||
|
@ -12,7 +12,7 @@ SUBDIR= add_route arp at backup \
|
||||
fix format fsck.mfs \
|
||||
gcov-pull host \
|
||||
hostaddr ifconfig ifdef \
|
||||
intr ipcrm irdpd isoread \
|
||||
intr irdpd isoread \
|
||||
loadkeys loadramdisk logger look lp \
|
||||
lpd lspci mail MAKEDEV \
|
||||
mount mt netconf \
|
||||
|
@ -1,4 +0,0 @@
|
||||
PROG= ipcrm
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,282 +0,0 @@
|
||||
/*
|
||||
* krishna balasubramanian 1993
|
||||
*
|
||||
* 1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL>
|
||||
* - added Native Language Support
|
||||
*
|
||||
* 1999-04-02 frank zago
|
||||
* - can now remove several id's in the same call
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
|
||||
/* for getopt */
|
||||
#include <unistd.h>
|
||||
/* for tolower and isupper */
|
||||
#include <ctype.h>
|
||||
|
||||
#define _(a) a
|
||||
|
||||
#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
|
||||
/* union semun is defined by including <sys/sem.h> */
|
||||
#else
|
||||
/* according to X/OPEN we have to define it ourselves */
|
||||
union semun {
|
||||
int val;
|
||||
struct semid_ds *buf;
|
||||
unsigned short int *array;
|
||||
struct seminfo *__buf;
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usage(char *);
|
||||
|
||||
char *execname;
|
||||
|
||||
typedef enum type_id {
|
||||
SHM,
|
||||
SEM,
|
||||
MSG
|
||||
} type_id;
|
||||
|
||||
static int
|
||||
remove_ids(type_id type, int argc, char **argv) {
|
||||
int id;
|
||||
int ret = 0; /* for gcc */
|
||||
char *end;
|
||||
int nb_errors = 0;
|
||||
union semun arg;
|
||||
|
||||
arg.val = 0;
|
||||
|
||||
while(argc) {
|
||||
|
||||
id = strtoul(argv[0], &end, 10);
|
||||
|
||||
if (*end != 0) {
|
||||
printf (_("invalid id: %s\n"), argv[0]);
|
||||
nb_errors ++;
|
||||
} else {
|
||||
switch(type) {
|
||||
case SEM:
|
||||
#if 0
|
||||
ret = semctl (id, 0, IPC_RMID, arg);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MSG:
|
||||
#if 0
|
||||
ret = msgctl (id, IPC_RMID, NULL);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SHM:
|
||||
ret = shmctl (id, IPC_RMID, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
printf (_("cannot remove id %s (%s)\n"),
|
||||
argv[0], strerror(errno));
|
||||
nb_errors ++;
|
||||
}
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
return(nb_errors);
|
||||
}
|
||||
|
||||
static void deprecate_display_usage(void)
|
||||
{
|
||||
usage(execname);
|
||||
printf (_("deprecated usage: %s {shm | msg | sem} id ...\n"),
|
||||
execname);
|
||||
}
|
||||
|
||||
static int deprecated_main(int argc, char **argv)
|
||||
{
|
||||
execname = argv[0];
|
||||
|
||||
if (argc < 3) {
|
||||
deprecate_display_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "shm")) {
|
||||
if (remove_ids(SHM, argc-2, &argv[2]))
|
||||
exit(1);
|
||||
}
|
||||
else if (!strcmp(argv[1], "msg")) {
|
||||
if (remove_ids(MSG, argc-2, &argv[2]))
|
||||
exit(1);
|
||||
}
|
||||
else if (!strcmp(argv[1], "sem")) {
|
||||
if (remove_ids(SEM, argc-2, &argv[2]))
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
deprecate_display_usage();
|
||||
printf (_("unknown resource type: %s\n"), argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf (_("resource(s) deleted\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* print the new usage */
|
||||
static void
|
||||
usage(char *progname)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("usage: %s [ [-q msqid] [-m shmid] [-s semid]\n"
|
||||
" [-Q msgkey] [-M shmkey] [-S semkey] ... ]\n"),
|
||||
progname);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int error = 0;
|
||||
char *prog = argv[0];
|
||||
|
||||
/* if the command is executed without parameters, do nothing */
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
/* check to see if the command is being invoked in the old way if so
|
||||
then run the old code */
|
||||
if (strcmp(argv[1], "shm") == 0 ||
|
||||
strcmp(argv[1], "msg") == 0 ||
|
||||
strcmp(argv[1], "sem") == 0)
|
||||
return deprecated_main(argc, argv);
|
||||
|
||||
/* process new syntax to conform with SYSV ipcrm */
|
||||
while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
|
||||
int result;
|
||||
int id = 0;
|
||||
int iskey = isupper(c);
|
||||
|
||||
/* needed to delete semaphores */
|
||||
union semun arg;
|
||||
arg.val = 0;
|
||||
|
||||
/* we don't need case information any more */
|
||||
c = tolower(c);
|
||||
|
||||
/* make sure the option is in range */
|
||||
if (c != 'q' && c != 'm' && c != 's') {
|
||||
fprintf(stderr, _("%s: illegal option -- %c\n"),
|
||||
prog, c);
|
||||
usage(prog);
|
||||
error++;
|
||||
return error;
|
||||
}
|
||||
|
||||
if (iskey) {
|
||||
/* keys are in hex or decimal */
|
||||
key_t key = strtoul(optarg, NULL, 0);
|
||||
if (key == IPC_PRIVATE) {
|
||||
error++;
|
||||
fprintf(stderr, _("%s: illegal key (%s)\n"),
|
||||
prog, optarg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* convert key to id */
|
||||
#if 0
|
||||
id = ((c == 'q') ? msgget(key, 0) :
|
||||
(c == 'm') ? shmget(key, 0, 0) :
|
||||
semget(key, 0, 0));
|
||||
#endif
|
||||
id = (c == 'm') ? shmget(key, 0, 0) :
|
||||
((c == 's') ? semget(key, 0, 0) : -1);
|
||||
|
||||
if (id < 0) {
|
||||
char *errmsg;
|
||||
error++;
|
||||
switch(errno) {
|
||||
case EACCES:
|
||||
errmsg = _("permission denied for key");
|
||||
break;
|
||||
case EIDRM:
|
||||
errmsg = _("already removed key");
|
||||
break;
|
||||
case ENOENT:
|
||||
errmsg = _("invalid key");
|
||||
break;
|
||||
default:
|
||||
errmsg = _("unknown error in key");
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "%s: %s (%s)\n",
|
||||
prog, errmsg, optarg);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* ids are in decimal */
|
||||
id = strtoul(optarg, NULL, 10);
|
||||
}
|
||||
|
||||
#if 0
|
||||
result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
|
||||
(c == 'm') ? shmctl(id, IPC_RMID, NULL) :
|
||||
semctl(id, 0, IPC_RMID, arg));
|
||||
#endif
|
||||
result = (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
|
||||
((c == 's') ? semctl(id, 0, IPC_RMID) : -1);
|
||||
|
||||
if (result < 0) {
|
||||
char *errmsg;
|
||||
error++;
|
||||
switch(errno) {
|
||||
case EACCES:
|
||||
case EPERM:
|
||||
errmsg = iskey
|
||||
? _("permission denied for key")
|
||||
: _("permission denied for id");
|
||||
break;
|
||||
case EINVAL:
|
||||
errmsg = iskey
|
||||
? _("invalid key")
|
||||
: _("invalid id");
|
||||
break;
|
||||
case EIDRM:
|
||||
errmsg = iskey
|
||||
? _("already removed key")
|
||||
: _("already removed id");
|
||||
break;
|
||||
default:
|
||||
errmsg = iskey
|
||||
? _("unknown error in key")
|
||||
: _("unknown error in id");
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, _("%s: %s (%s)\n"),
|
||||
prog, errmsg, optarg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* print usage if we still have some arguments left over */
|
||||
if (optind != argc) {
|
||||
fprintf(stderr, _("%s: unknown argument: %s\n"),
|
||||
prog, argv[optind]);
|
||||
usage(prog);
|
||||
}
|
||||
|
||||
/* exit value reflects the number of errors encountered */
|
||||
return error;
|
||||
}
|
@ -13,7 +13,7 @@ SUBDIR= asa \
|
||||
false find finger flock fold fpr from \
|
||||
fsplit ftp genassym \
|
||||
getopt \
|
||||
head hexdump id indent infocmp ipcs join jot \
|
||||
head hexdump id indent infocmp ipcrm ipcs join jot \
|
||||
lam last ldd leave \
|
||||
lock login logname lorder m4 \
|
||||
machine make man menuc mesg \
|
||||
|
5
usr.bin/ipcrm/Makefile
Normal file
5
usr.bin/ipcrm/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $NetBSD: Makefile,v 1.10 2009/04/14 22:15:21 lukem Exp $
|
||||
|
||||
PROG= ipcrm
|
||||
|
||||
.include <bsd.prog.mk>
|
97
usr.bin/ipcrm/ipcrm.1
Normal file
97
usr.bin/ipcrm/ipcrm.1
Normal file
@ -0,0 +1,97 @@
|
||||
.\" $NetBSD: ipcrm.1,v 1.11 2008/06/01 10:25:29 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1994 Adam Glass
|
||||
.\" 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. 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 BY Adam Glass ``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 Adam Glass 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.
|
||||
.\"
|
||||
.\" $NetBSD: ipcrm.1,v 1.11 2008/06/01 10:25:29 wiz Exp $
|
||||
.\"
|
||||
.Dd May 31, 2008
|
||||
.Dt IPCRM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ipcrm
|
||||
.Nd remove the specified message queues, semaphore sets, and shared memory segments
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl M Ar shmkey
|
||||
.Op Fl m Ar shmid
|
||||
.Op Fl Q Ar msgkey
|
||||
.Op Fl q Ar msqid
|
||||
.Op Fl S Ar semkey
|
||||
.Op Fl s Ar semid
|
||||
.Ar ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
removes the specified message queues, semaphores, and shared memory
|
||||
segments.
|
||||
These System V IPC objects can be specified by their
|
||||
creation ID or any associated key.
|
||||
.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
|
||||
.It Fl M Ar shmkey
|
||||
Mark the shared memory segment associated with key
|
||||
.Ar shmkey
|
||||
for removal.
|
||||
This marked segment will be destroyed after the last detach.
|
||||
.It Fl m Ar shmid
|
||||
Mark the shared memory segment associated with ID
|
||||
.Ar shmid
|
||||
for removal.
|
||||
This marked segment will be destroyed after the last detach.
|
||||
.It Fl Q Ar msgkey
|
||||
Remove the message queue associated with key
|
||||
.Ar msgkey
|
||||
from the system.
|
||||
.It Fl q Ar msqid
|
||||
Remove the message queue associated with the ID
|
||||
.Ar msqid
|
||||
from the system.
|
||||
.It Fl S Ar semkey
|
||||
Remove the semaphore set associated with key
|
||||
.Ar semkey
|
||||
from the system.
|
||||
.It Fl s Ar semid
|
||||
Removes the semaphore set associated with ID
|
||||
.Ar semid
|
||||
from the system.
|
||||
.El
|
||||
.Pp
|
||||
If the
|
||||
.Ar id
|
||||
or
|
||||
.Ar key
|
||||
argument is
|
||||
.Dq all
|
||||
then all entries of the appropriate type are removed.
|
||||
.Pp
|
||||
The identifiers and keys associated with these System V IPC objects can be
|
||||
determined by using
|
||||
.Xr ipcs 1 .
|
||||
.Sh SEE ALSO
|
||||
.Xr ipcs 1 ,
|
||||
.Xr shmat 2 ,
|
||||
.Xr shmctl 2 ,
|
||||
.Xr shmdt 2 ,
|
||||
.Xr shmget 2
|
322
usr.bin/ipcrm/ipcrm.c
Normal file
322
usr.bin/ipcrm/ipcrm.c
Normal file
@ -0,0 +1,322 @@
|
||||
/* $NetBSD: ipcrm.c,v 1.16 2009/01/18 01:06:42 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Adam Glass
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. 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 BY Adam Glass ``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 Adam Glass 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#ifdef __minix
|
||||
#include <errno.h>
|
||||
#endif /* __minix */
|
||||
|
||||
#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"))
|
||||
|
||||
static sig_atomic_t signaled;
|
||||
|
||||
static void usage(void) __dead;
|
||||
static int msgrm(key_t, int);
|
||||
static int shmrm(key_t, int);
|
||||
static int semrm(key_t, int);
|
||||
static int msgrmall(void);
|
||||
static int shmrmall(void);
|
||||
static int semrmall(void);
|
||||
static void not_configured(int);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "Usage: %s [-M shmkey] [-m shmid] [-Q msgkey]\n",
|
||||
getprogname());
|
||||
(void)fprintf(stderr, "\t[-q msqid] [-S semkey] [-s semid] ...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int
|
||||
msgrm(key_t key, int id)
|
||||
{
|
||||
#ifndef __minix
|
||||
if (key) {
|
||||
id = msgget(key, 0);
|
||||
if (id == -1)
|
||||
return -1;
|
||||
}
|
||||
return msgctl(id, IPC_RMID, NULL);
|
||||
#else /* __minix */
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif /* __minix */
|
||||
}
|
||||
|
||||
static int
|
||||
shmrm(key_t key, int id)
|
||||
{
|
||||
if (key) {
|
||||
id = shmget(key, 0, 0);
|
||||
if (id == -1)
|
||||
return -1;
|
||||
}
|
||||
return shmctl(id, IPC_RMID, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
semrm(key_t key, int id)
|
||||
{
|
||||
|
||||
if (key) {
|
||||
id = semget(key, 0, 0);
|
||||
if (id == -1)
|
||||
return -1;
|
||||
}
|
||||
return semctl(id, 0, IPC_RMID, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
msgrmall(void)
|
||||
{
|
||||
int mib[4];
|
||||
struct msg_sysctl_info *msgsi;
|
||||
int32_t i;
|
||||
size_t len;
|
||||
int result = 0;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_SYSVIPC;
|
||||
mib[2] = KERN_SYSVIPC_INFO;
|
||||
mib[3] = KERN_SYSVIPC_MSG_INFO;
|
||||
|
||||
if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
|
||||
err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");
|
||||
|
||||
if ((msgsi = malloc(len)) == NULL)
|
||||
err(1, "malloc");
|
||||
if (sysctl(mib, 4, msgsi, &len, NULL, 0) == -1) {
|
||||
free(msgsi);
|
||||
err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");
|
||||
}
|
||||
|
||||
for (i = 0; i < msgsi->msginfo.msgmni; i++) {
|
||||
struct msgid_ds_sysctl *msgptr = &msgsi->msgids[i];
|
||||
if (msgptr->msg_qbytes != 0)
|
||||
result -= msgrm((key_t)0,
|
||||
(int)IXSEQ_TO_IPCID(i, msgptr->msg_perm));
|
||||
}
|
||||
free(msgsi);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
shmrmall(void)
|
||||
{
|
||||
int mib[4];
|
||||
struct shm_sysctl_info *shmsi;
|
||||
size_t i, len;
|
||||
int result = 0;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_SYSVIPC;
|
||||
mib[2] = KERN_SYSVIPC_INFO;
|
||||
mib[3] = KERN_SYSVIPC_SHM_INFO;
|
||||
|
||||
if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
|
||||
err(1, "sysctl(KERN_SYSVIPC_SHM_INFO)");
|
||||
|
||||
if ((shmsi = malloc(len)) == NULL)
|
||||
err(1, "malloc");
|
||||
if (sysctl(mib, 4, shmsi, &len, NULL, 0) == -1) {
|
||||
free(shmsi);
|
||||
err(1, "sysctl(KERN_SYSVIPC_SHM_INFO)");
|
||||
}
|
||||
|
||||
for (i = 0; i < shmsi->shminfo.shmmni; i++) {
|
||||
struct shmid_ds_sysctl *shmptr = &shmsi->shmids[i];
|
||||
if (shmptr->shm_perm.mode & 0x0800)
|
||||
result -= shmrm((key_t)0,
|
||||
(int)IXSEQ_TO_IPCID(i, shmptr->shm_perm));
|
||||
}
|
||||
free(shmsi);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
semrmall(void)
|
||||
{
|
||||
int mib[4];
|
||||
struct sem_sysctl_info *semsi;
|
||||
size_t len;
|
||||
int32_t i;
|
||||
int result = 0;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_SYSVIPC;
|
||||
mib[2] = KERN_SYSVIPC_INFO;
|
||||
mib[3] = KERN_SYSVIPC_SEM_INFO;
|
||||
|
||||
if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
|
||||
err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");
|
||||
|
||||
if ((semsi = malloc(len)) == NULL)
|
||||
err(1, "malloc");
|
||||
if (sysctl(mib, 4, semsi, &len, NULL, 0) == -1) {
|
||||
free(semsi);
|
||||
err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");
|
||||
}
|
||||
|
||||
for (i = 0; i < semsi->seminfo.semmni; i++) {
|
||||
struct semid_ds_sysctl *semptr = &semsi->semids[i];
|
||||
if ((semptr->sem_perm.mode & SEM_ALLOC) != 0)
|
||||
result -= semrm((key_t)0,
|
||||
(int)IXSEQ_TO_IPCID(i, semptr->sem_perm));
|
||||
}
|
||||
free(semsi);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
/*ARGSUSED*/
|
||||
not_configured(int n)
|
||||
{
|
||||
signaled++;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, result, errflg, target_id;
|
||||
key_t target_key;
|
||||
|
||||
setprogname(argv[0]);
|
||||
errflg = 0;
|
||||
(void)signal(SIGSYS, not_configured);
|
||||
while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
|
||||
signaled = 0;
|
||||
target_id = 0;
|
||||
target_key = 0;
|
||||
result = 0;
|
||||
|
||||
if (optarg != NULL && strcmp(optarg, "all") == 0) {
|
||||
switch (c) {
|
||||
case 'm':
|
||||
case 'M':
|
||||
result = shmrmall();
|
||||
break;
|
||||
case 'q':
|
||||
case 'Q':
|
||||
result = msgrmall();
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
result = semrmall();
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
} else {
|
||||
switch (c) {
|
||||
case 'q':
|
||||
case 'm':
|
||||
case 's':
|
||||
target_id = atoi(optarg);
|
||||
break;
|
||||
case 'Q':
|
||||
case 'M':
|
||||
case 'S':
|
||||
target_key = atol(optarg);
|
||||
if (target_key == IPC_PRIVATE) {
|
||||
warnx("can't remove private %ss",
|
||||
IPC_TO_STRING(c));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
switch (c) {
|
||||
case 'q':
|
||||
result = msgrm((key_t)0, target_id);
|
||||
break;
|
||||
case 'm':
|
||||
result = shmrm((key_t)0, target_id);
|
||||
break;
|
||||
case 's':
|
||||
result = semrm((key_t)0, target_id);
|
||||
break;
|
||||
case 'Q':
|
||||
result = msgrm(target_key, 0);
|
||||
break;
|
||||
case 'M':
|
||||
result = shmrm(target_key, 0);
|
||||
break;
|
||||
case 'S':
|
||||
result = semrm(target_key, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result < 0) {
|
||||
if (!signaled) {
|
||||
if (target_id) {
|
||||
warn("%sid(%d): ",
|
||||
IPC_TO_STR(toupper(c)), target_id);
|
||||
errflg++;
|
||||
} else if (target_key) {
|
||||
warn("%skey(%ld): ", IPC_TO_STR(c),
|
||||
(long)target_key);
|
||||
errflg++;
|
||||
}
|
||||
} else {
|
||||
errflg++;
|
||||
warnx("%ss are not configured in "
|
||||
"the running kernel",
|
||||
IPC_TO_STRING(toupper(c)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (optind != argc) {
|
||||
warnx("Unknown argument: %s", argv[optind]);
|
||||
usage();
|
||||
}
|
||||
return errflg;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user