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:
David van Moolenbroek 2015-12-17 13:14:08 +00:00 committed by Lionel Sambuc
parent 7b09d0426a
commit 0502421f1b
8 changed files with 427 additions and 288 deletions

View File

@ -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

View File

@ -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 \

View File

@ -1,4 +0,0 @@
PROG= ipcrm
MAN=
.include <bsd.prog.mk>

View File

@ -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;
}

View File

@ -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
View 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
View 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
View 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;
}