ipcrm.c revision 174750
180609Sdd/*
280609Sdd * Copyright (c) 1994 Adam Glass
380609Sdd * All rights reserved.
480609Sdd *
580609Sdd * Redistribution and use in source and binary forms, with or without
680609Sdd * modification, are permitted provided that the following conditions
780609Sdd * are met:
880609Sdd * 1. Redistributions of source code must retain the above copyright
980609Sdd *    notice, this list of conditions and the following disclaimer.
1080609Sdd * 2. Redistributions in binary form must reproduce the above copyright
1180609Sdd *    notice, this list of conditions and the following disclaimer in the
1280609Sdd *    documentation and/or other materials provided with the distribution.
1380609Sdd * 3. All advertising materials mentioning features or use of this software
1480609Sdd *    must display the following acknowledgement:
1580609Sdd *	This product includes software developed by Adam Glass.
1680609Sdd * 4. The name of the Author may not be used to endorse or promote products
1780609Sdd *    derived from this software without specific prior written permission.
1880609Sdd *
1980609Sdd * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
2080609Sdd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2180609Sdd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2280609Sdd * ARE DISCLAIMED.  IN NO EVENT SHALL Adam Glass BE LIABLE
2380609Sdd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2480609Sdd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2580609Sdd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2680609Sdd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2780609Sdd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2880609Sdd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2980609Sdd * SUCH DAMAGE.
3080609Sdd */
3180609Sdd
3280609Sdd#include <sys/cdefs.h>
3380609Sdd__FBSDID("$FreeBSD: head/usr.bin/ipcrm/ipcrm.c 174750 2007-12-18 09:39:47Z edwin $");
3480609Sdd
3582094Sdd#include <sys/types.h>
3680609Sdd#include <sys/ipc.h>
3780609Sdd#include <sys/msg.h>
3880609Sdd#include <sys/sem.h>
3980609Sdd#include <sys/shm.h>
4080609Sdd
4180609Sdd#include <ctype.h>
4280609Sdd#include <err.h>
4380609Sdd#include <signal.h>
4480609Sdd#include <stdio.h>
4580609Sdd#include <stdlib.h>
4681343Sdd#include <unistd.h>
4780609Sdd
4880609Sdd#define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
4981343Sdd#define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
5081343Sdd	(x == 'M' ? "shared memory segment" : "semaphore"))
5180609Sdd
5280609Sddint signaled;
5380609Sdd
5480609Sddvoid usage(void);
5580609Sddint msgrm(key_t, int);
5680609Sddint shmrm(key_t, int);
5780609Sddint semrm(key_t, int);
5880609Sddvoid not_configured(int);
5980609Sdd
6080609Sddvoid
6180609Sddusage(void)
6280609Sdd{
6380609Sdd
6480609Sdd	fprintf(stderr,
6580609Sdd	    "usage: ipcrm [-q msqid] [-m shmid] [-s semid]\n"
6680609Sdd	    "             [-Q msgkey] [-M shmkey] [-S semkey] ...\n");
6780609Sdd	exit(1);
6880609Sdd}
6980609Sdd
7080609Sddint
7180609Sddmsgrm(key_t key, int id)
7280609Sdd{
73189092Sed
7480609Sdd	if (key) {
75189092Sed		id = msgget(key, 0);
7680609Sdd		if (id == -1)
77189092Sed			return -1;
7880609Sdd	}
7980609Sdd	return msgctl(id, IPC_RMID, NULL);
8080609Sdd}
8180609Sdd
8280609Sddint
8381343Sddshmrm(key_t key, int id)
84189092Sed{
8580609Sdd
8681343Sdd	if (key) {
87189092Sed		id = shmget(key, 0, 0);
8880609Sdd		if (id == -1)
8981343Sdd			return -1;
90189092Sed	}
9180609Sdd	return shmctl(id, IPC_RMID, NULL);
9280609Sdd}
93189092Sed
9480609Sddint
95189092Sedsemrm(key_t key, int id)
9680609Sdd{
9780609Sdd	union semun arg;
9880609Sdd
9981343Sdd	if (key) {
100189092Sed		id = semget(key, 0, 0);
10180609Sdd		if (id == -1)
10280609Sdd			return -1;
10380609Sdd	}
10481343Sdd	return semctl(id, 0, IPC_RMID, arg);
10580609Sdd}
10680609Sdd
107189092Sedvoid
10880609Sddnot_configured(int signo __unused)
109189092Sed{
11080609Sdd
111189092Sed	signaled++;
11280609Sdd}
113189092Sed
11480609Sddint
11580609Sddmain(int argc, char *argv[])
11680609Sdd{
11780609Sdd	int c, result, errflg, target_id;
11881343Sdd	key_t target_key;
11980609Sdd
12080609Sdd	errflg = 0;
12180609Sdd	signal(SIGSYS, not_configured);
12280609Sdd	while ((c = getopt(argc, argv, ":q:m:s:Q:M:S:")) != -1) {
123189092Sed
12480609Sdd		signaled = 0;
12580609Sdd		switch (c) {
126189092Sed		case 'q':
12780609Sdd		case 'm':
12880609Sdd		case 's':
129189092Sed			target_id = atoi(optarg);
13080609Sdd			if (c == 'q')
131189092Sed				result = msgrm(0, target_id);
132189092Sed			else if (c == 'm')
13380609Sdd				result = shmrm(0, target_id);
134189092Sed			else
13580609Sdd				result = semrm(0, target_id);
13680609Sdd			if (result < 0) {
13780609Sdd				errflg++;
13880609Sdd				if (!signaled)
13980609Sdd					warn("%sid(%d): ",
14080609Sdd					    IPC_TO_STR(toupper(c)), target_id);
14180609Sdd				else
14280609Sdd					warnx(
14380609Sdd					    "%ss are not configured "
144189092Sed					    "in the running kernel",
14580609Sdd					    IPC_TO_STRING(toupper(c)));
14680609Sdd			}
147189092Sed			break;
14880609Sdd		case 'Q':
149189092Sed		case 'M':
15080609Sdd		case 'S':
15180609Sdd			target_key = atol(optarg);
15280609Sdd			if (target_key == IPC_PRIVATE) {
15380609Sdd				warnx("can't remove private %ss",
15480609Sdd				    IPC_TO_STRING(c));
15580609Sdd				continue;
15680609Sdd			}
15780609Sdd			if (c == 'Q')
15880609Sdd				result = msgrm(target_key, 0);
159189092Sed			else if (c == 'M')
16080609Sdd				result = shmrm(target_key, 0);
161189092Sed			else
16280609Sdd				result = semrm(target_key, 0);
16380609Sdd			if (result < 0) {
16480609Sdd				errflg++;
16580609Sdd				if (!signaled)
16680609Sdd					warn("%ss(%ld): ",
16780609Sdd					    IPC_TO_STR(c), target_key);
16880609Sdd				else
16980609Sdd					warnx("%ss are not configured "
17080609Sdd					    "in the running kernel",
17180609Sdd					    IPC_TO_STRING(c));
17280609Sdd			}
17380609Sdd			break;
174189092Sed		case ':':
17580609Sdd			fprintf(stderr,
17680609Sdd			    "option -%c requires an argument\n", optopt);
177189092Sed			usage();
17880609Sdd		case '?':
179189092Sed			fprintf(stderr, "unrecognized option: -%c\n", optopt);
18080609Sdd			usage();
18180609Sdd		}
18280609Sdd	}
18380609Sdd
18480609Sdd	if (optind != argc) {
18580609Sdd		fprintf(stderr, "unknown argument: %s\n", argv[optind]);
18680609Sdd		usage();
18780609Sdd	}
188189092Sed	exit(errflg);
18980609Sdd}
19080609Sdd