Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.bin / ipcrm / ipcrm.c
blobca1b1180f9415ebc2c15e0fa3b9a04ac1328b37e
1 /* $NetBSD: ipcrm.c,v 1.15 2008/08/18 02:12:35 dholland Exp $ */
3 /*
4 * Copyright (c) 1994 Adam Glass
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Adam Glass.
18 * 4. The name of the Author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL Adam Glass BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #include <sys/types.h>
35 #include <sys/ipc.h>
36 #include <sys/msg.h>
37 #include <sys/sem.h>
38 #include <sys/shm.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <ctype.h>
45 #include <err.h>
46 #include <signal.h>
47 #include <sys/sysctl.h>
49 #define IPC_TO_STR(x) (x == 'Q' ? "msq" : (x == 'M' ? "shm" : "sem"))
50 #define IPC_TO_STRING(x) (x == 'Q' ? "message queue" : \
51 (x == 'M' ? "shared memory segment" : "semaphore"))
53 static sig_atomic_t signaled;
55 static void usage(void) __dead;
56 static int msgrm(key_t, int);
57 static int shmrm(key_t, int);
58 static int semrm(key_t, int);
59 static int msgrmall(void);
60 static int shmrmall(void);
61 static int semrmall(void);
62 static void not_configured(int);
64 static void
65 usage(void)
67 (void)fprintf(stderr, "Usage: %s [-M shmkey] [-m shmid] [-Q msgkey]\n",
68 getprogname());
69 (void)fprintf(stderr, "\t[-q msqid] [-S semkey] [-s semid] ...\n");
70 exit(1);
73 static int
74 msgrm(key_t key, int id)
76 if (key) {
77 id = msgget(key, 0);
78 if (id == -1)
79 return -1;
81 return msgctl(id, IPC_RMID, NULL);
84 static int
85 shmrm(key_t key, int id)
87 if (key) {
88 id = shmget(key, 0, 0);
89 if (id == -1)
90 return -1;
92 return shmctl(id, IPC_RMID, NULL);
95 static int
96 semrm(key_t key, int id)
99 if (key) {
100 id = semget(key, 0, 0);
101 if (id == -1)
102 return -1;
104 return semctl(id, 0, IPC_RMID, NULL);
107 static int
108 msgrmall(void)
110 int mib[4];
111 struct msg_sysctl_info *msgsi;
112 int32_t i;
113 size_t len;
114 int result = 0;
116 mib[0] = CTL_KERN;
117 mib[1] = KERN_SYSVIPC;
118 mib[2] = KERN_SYSVIPC_INFO;
119 mib[3] = KERN_SYSVIPC_MSG_INFO;
121 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
122 err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");
124 if ((msgsi = malloc(len)) == NULL)
125 err(1, "malloc");
126 if (sysctl(mib, 4, msgsi, &len, NULL, 0) == -1) {
127 free(msgsi);
128 err(1, "sysctl(KERN_SYSVIPC_MSG_INFO)");
131 for (i = 0; i < msgsi->msginfo.msgmni; i++) {
132 struct msgid_ds_sysctl *msgptr = &msgsi->msgids[i];
133 if (msgptr->msg_qbytes != 0)
134 result -= msgrm((key_t)0,
135 (int)IXSEQ_TO_IPCID(i, msgptr->msg_perm));
137 free(msgsi);
138 return result;
141 static int
142 shmrmall(void)
144 int mib[4];
145 struct shm_sysctl_info *shmsi;
146 size_t i, len;
147 int result = 0;
149 mib[0] = CTL_KERN;
150 mib[1] = KERN_SYSVIPC;
151 mib[2] = KERN_SYSVIPC_INFO;
152 mib[3] = KERN_SYSVIPC_SHM_INFO;
154 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
155 err(1, "sysctl(KERN_SYSVIPC_SHM_INFO)");
157 if ((shmsi = malloc(len)) == NULL)
158 err(1, "malloc");
159 if (sysctl(mib, 4, shmsi, &len, NULL, 0) == -1) {
160 free(shmsi);
161 err(1, "sysctl(KERN_SYSVIPC_SHM_INFO)");
164 for (i = 0; i < shmsi->shminfo.shmmni; i++) {
165 struct shmid_ds_sysctl *shmptr = &shmsi->shmids[i];
166 if (shmptr->shm_perm.mode & 0x0800)
167 result -= shmrm((key_t)0,
168 (int)IXSEQ_TO_IPCID(i, shmptr->shm_perm));
170 free(shmsi);
171 return result;
174 static int
175 semrmall(void)
177 int mib[4];
178 struct sem_sysctl_info *semsi;
179 size_t len;
180 int32_t i;
181 int result = 0;
183 mib[0] = CTL_KERN;
184 mib[1] = KERN_SYSVIPC;
185 mib[2] = KERN_SYSVIPC_INFO;
186 mib[3] = KERN_SYSVIPC_SEM_INFO;
188 if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1)
189 err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");
191 if ((semsi = malloc(len)) == NULL)
192 err(1, "malloc");
193 if (sysctl(mib, 4, semsi, &len, NULL, 0) == -1) {
194 free(semsi);
195 err(1, "sysctl(KERN_SYSVIPC_SEM_INFO)");
198 for (i = 0; i < semsi->seminfo.semmni; i++) {
199 struct semid_ds_sysctl *semptr = &semsi->semids[i];
200 if ((semptr->sem_perm.mode & SEM_ALLOC) != 0)
201 result -= semrm((key_t)0,
202 (int)IXSEQ_TO_IPCID(i, semptr->sem_perm));
204 free(semsi);
205 return result;
208 static void
209 /*ARGSUSED*/
210 not_configured(int n)
212 signaled++;
215 int
216 main(int argc, char *argv[])
218 int c, result, errflg, target_id;
219 key_t target_key;
221 setprogname(argv[0]);
222 errflg = 0;
223 (void)signal(SIGSYS, not_configured);
224 while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
225 signaled = 0;
226 target_id = 0;
227 target_key = 0;
228 result = 0;
230 if (optarg != NULL && strcmp(optarg, "all") == 0) {
231 switch (c) {
232 case 'm':
233 case 'M':
234 result = shmrmall();
235 break;
236 case 'q':
237 case 'Q':
238 result = msgrmall();
239 break;
240 case 's':
241 case 'S':
242 result = semrmall();
243 break;
244 default:
245 usage();
247 } else {
248 switch (c) {
249 case 'q':
250 case 'm':
251 case 's':
252 target_id = atoi(optarg);
253 break;
254 case 'Q':
255 case 'M':
256 case 'S':
257 target_key = atol(optarg);
258 if (target_key == IPC_PRIVATE) {
259 warnx("can't remove private %ss",
260 IPC_TO_STRING(c));
261 continue;
263 break;
264 default:
265 usage();
267 switch (c) {
268 case 'q':
269 result = msgrm((key_t)0, target_id);
270 break;
271 case 'm':
272 result = shmrm((key_t)0, target_id);
273 break;
274 case 's':
275 result = semrm((key_t)0, target_id);
276 break;
277 case 'Q':
278 result = msgrm(target_key, 0);
279 break;
280 case 'M':
281 result = shmrm(target_key, 0);
282 break;
283 case 'S':
284 result = semrm(target_key, 0);
285 break;
288 if (result < 0) {
289 if (!signaled) {
290 if (target_id) {
291 warn("%sid(%d): ",
292 IPC_TO_STR(toupper(c)), target_id);
293 errflg++;
294 } else if (target_key) {
295 warn("%skey(%ld): ", IPC_TO_STR(c),
296 (long)target_key);
297 errflg++;
299 } else {
300 errflg++;
301 warnx("%ss are not configured in "
302 "the running kernel",
303 IPC_TO_STRING(toupper(c)));
308 if (optind != argc) {
309 warnx("Unknown argument: %s", argv[optind]);
310 usage();
312 return errflg;