From 0502421f1bef012dd57007f7e430f331c6bed7a6 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Thu, 17 Dec 2015 13:14:08 +0000 Subject: [PATCH] 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 --- distrib/sets/lists/minix-man/mi | 1 + minix/commands/Makefile | 2 +- minix/commands/ipcrm/Makefile | 4 - minix/commands/ipcrm/ipcrm.c | 282 ---------------------------- usr.bin/Makefile | 2 +- usr.bin/ipcrm/Makefile | 5 + usr.bin/ipcrm/ipcrm.1 | 97 ++++++++++ usr.bin/ipcrm/ipcrm.c | 322 ++++++++++++++++++++++++++++++++ 8 files changed, 427 insertions(+), 288 deletions(-) delete mode 100644 minix/commands/ipcrm/Makefile delete mode 100644 minix/commands/ipcrm/ipcrm.c create mode 100644 usr.bin/ipcrm/Makefile create mode 100644 usr.bin/ipcrm/ipcrm.1 create mode 100644 usr.bin/ipcrm/ipcrm.c diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 3e5286270..cff33f680 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -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 diff --git a/minix/commands/Makefile b/minix/commands/Makefile index 0296baa41..ff23a8d9b 100644 --- a/minix/commands/Makefile +++ b/minix/commands/Makefile @@ -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 \ diff --git a/minix/commands/ipcrm/Makefile b/minix/commands/ipcrm/Makefile deleted file mode 100644 index ceba4d72b..000000000 --- a/minix/commands/ipcrm/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= ipcrm -MAN= - -.include diff --git a/minix/commands/ipcrm/ipcrm.c b/minix/commands/ipcrm/ipcrm.c deleted file mode 100644 index d04df67ab..000000000 --- a/minix/commands/ipcrm/ipcrm.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * krishna balasubramanian 1993 - * - * 1999-02-22 Arkadiusz Mi秌iewicz - * - added Native Language Support - * - * 1999-04-02 frank zago - * - can now remove several id's in the same call - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -/* for getopt */ -#include -/* for tolower and isupper */ -#include - -#define _(a) a - -#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) -/* union semun is defined by including */ -#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; -} diff --git a/usr.bin/Makefile b/usr.bin/Makefile index edb0917b5..ac88cea56 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -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 \ diff --git a/usr.bin/ipcrm/Makefile b/usr.bin/ipcrm/Makefile new file mode 100644 index 000000000..7497e33e5 --- /dev/null +++ b/usr.bin/ipcrm/Makefile @@ -0,0 +1,5 @@ +# $NetBSD: Makefile,v 1.10 2009/04/14 22:15:21 lukem Exp $ + +PROG= ipcrm + +.include diff --git a/usr.bin/ipcrm/ipcrm.1 b/usr.bin/ipcrm/ipcrm.1 new file mode 100644 index 000000000..2e2cad364 --- /dev/null +++ b/usr.bin/ipcrm/ipcrm.1 @@ -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 diff --git a/usr.bin/ipcrm/ipcrm.c b/usr.bin/ipcrm/ipcrm.c new file mode 100644 index 000000000..e964102a7 --- /dev/null +++ b/usr.bin/ipcrm/ipcrm.c @@ -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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __minix +#include +#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; +} -- 2.44.0