]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/ipcrm/ipcrm.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.bin / ipcrm / ipcrm.c
1 /*
2  * Copyright (c) 1994 Adam Glass
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Adam Glass.
16  * 4. The name of the Author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY Adam Glass ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL Adam Glass BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #define _KERNEL
38 #include <sys/sem.h>
39 #include <sys/shm.h>
40 #include <sys/msg.h>
41 #undef _KERNEL
42
43 #include <ctype.h>
44 #include <err.h>
45 #include <grp.h>
46 #include <kvm.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <unistd.h>
50
51 #include "ipc.h"
52
53 int     signaled;
54 int     errflg;
55 int     rmverbose = 0;
56
57 void    usage(void);
58
59 int     msgrm(key_t, int);
60 int     shmrm(key_t, int);
61 int     semrm(key_t, int);
62 void    not_configured(int);
63
64 void
65 usage(void)
66 {
67
68         fprintf(stderr,
69             "usage: ipcrm [-W] [-v[v]]\n"
70             "             [-q msqid] [-m shmid] [-s semid]\n"
71             "             [-Q msgkey] [-M shmkey] [-S semkey] ...\n");
72         exit(1);
73 }
74
75 int
76 msgrm(key_t key, int id)
77 {
78
79         if (key == -1 || id == -1) {
80                 struct msqid_kernel *kxmsqids;
81                 size_t kxmsqids_len;
82                 int num;
83
84                 kget(X_MSGINFO, &msginfo, sizeof(msginfo));
85                 kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni;
86                 kxmsqids = malloc(kxmsqids_len);
87                 kget(X_MSQIDS, kxmsqids, kxmsqids_len);
88                 num = msginfo.msgmni;
89                 while (num-- && !signaled)
90                         if (kxmsqids[num].u.msg_qbytes != 0) {
91                                 id = IXSEQ_TO_IPCID(num,
92                                         kxmsqids[num].u.msg_perm);
93                                 if (msgctl(id, IPC_RMID, NULL) < 0) {
94                                         if (rmverbose > 1)
95                                                 warn("msqid(%d): ", id);
96                                         errflg++;
97                                 } else
98                                         if (rmverbose)
99                                                 printf(
100                                                     "Removed %s %d\n",
101                                                     IPC_TO_STRING('Q'),
102                                                     id);
103                         }
104                 return signaled ? -1 : 0;       /* errors maybe handled above */
105         }
106
107         if (key) {
108                 id = msgget(key, 0);
109                 if (id == -1)
110                         return -1;
111         }
112
113         return msgctl(id, IPC_RMID, NULL);
114 }
115
116 int
117 shmrm(key_t key, int id)
118 {
119
120         if (key == -1 || id == -1) {
121                 struct shmid_kernel *kxshmids;
122                 size_t kxshmids_len;
123                 int num;
124
125                 kget(X_SHMINFO, &shminfo, sizeof(shminfo));
126                 kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni;
127                 kxshmids = malloc(kxshmids_len);
128                 kget(X_SHMSEGS, kxshmids, kxshmids_len);
129                 num = shminfo.shmmni;
130                 while (num-- && !signaled)
131                         if (kxshmids[num].u.shm_perm.mode & 0x0800) {
132                                 id = IXSEQ_TO_IPCID(num,
133                                         kxshmids[num].u.shm_perm);
134                                 if (shmctl(id, IPC_RMID, NULL) < 0) {
135                                         if (rmverbose > 1)
136                                                 warn("shmid(%d): ", id);
137                                         errflg++;
138                                 } else
139                                         if (rmverbose)
140                                                 printf(
141                                                     "Removed %s %d\n",
142                                                     IPC_TO_STRING('M'),
143                                                     id);
144                         }
145                 return signaled ? -1 : 0;       /* errors maybe handled above */
146         }
147
148         if (key) {
149                 id = shmget(key, 0, 0);
150                 if (id == -1)
151                         return -1;
152         }
153
154         return shmctl(id, IPC_RMID, NULL);
155 }
156
157 int
158 semrm(key_t key, int id)
159 {
160         union semun arg;
161
162         if (key == -1 || id == -1) {
163                 struct semid_kernel *kxsema;
164                 size_t kxsema_len;
165                 int num;
166
167                 kget(X_SEMINFO, &seminfo, sizeof(seminfo));
168                 kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni;
169                 kxsema = malloc(kxsema_len);
170                 kget(X_SEMA, kxsema, kxsema_len);
171                 num = seminfo.semmni;
172                 while (num-- && !signaled)
173                         if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) {
174                                 id = IXSEQ_TO_IPCID(num,
175                                         kxsema[num].u.sem_perm);
176                                 if (semctl(id, IPC_RMID, NULL) < 0) {
177                                         if (rmverbose > 1)
178                                                 warn("semid(%d): ", id);
179                                         errflg++;
180                                 } else
181                                         if (rmverbose)
182                                                 printf(
183                                                     "Removed %s %d\n",
184                                                     IPC_TO_STRING('S'),
185                                                     id);
186                         }
187                 return signaled ? -1 : 0;       /* errors maybe handled above */
188         }
189
190         if (key) {
191                 id = semget(key, 0, 0);
192                 if (id == -1)
193                         return -1;
194         }
195
196         return semctl(id, 0, IPC_RMID, arg);
197 }
198
199 void
200 not_configured(int signo __unused)
201 {
202
203         signaled++;
204 }
205
206 int
207 main(int argc, char *argv[])
208 {
209         int c, result, target_id;
210         key_t target_key;
211
212         while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
213
214                 signaled = 0;
215                 switch (c) {
216                 case 'v':
217                         rmverbose++;
218                         break;
219                 case 'y':
220                         use_sysctl = 0;
221                         break;
222                 }
223         }
224
225         optind = 1;
226         errflg = 0;
227         signal(SIGSYS, not_configured);
228         while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
229
230                 signaled = 0;
231                 switch (c) {
232                 case 'q':
233                 case 'm':
234                 case 's':
235                         target_id = atoi(optarg);
236                         if (c == 'q')
237                                 result = msgrm(0, target_id);
238                         else if (c == 'm')
239                                 result = shmrm(0, target_id);
240                         else
241                                 result = semrm(0, target_id);
242                         if (result < 0) {
243                                 errflg++;
244                                 if (!signaled)
245                                         warn("%sid(%d): ",
246                                             IPC_TO_STR(toupper(c)), target_id);
247                                 else
248                                         warnx(
249                                             "%ss are not configured "
250                                             "in the running kernel",
251                                             IPC_TO_STRING(toupper(c)));
252                         }
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;
262                         }
263                         if (c == 'Q')
264                                 result = msgrm(target_key, 0);
265                         else if (c == 'M')
266                                 result = shmrm(target_key, 0);
267                         else
268                                 result = semrm(target_key, 0);
269                         if (result < 0) {
270                                 errflg++;
271                                 if (!signaled)
272                                         warn("%ss(%ld): ",
273                                             IPC_TO_STR(c), target_key);
274                                 else
275                                         warnx("%ss are not configured "
276                                             "in the running kernel",
277                                             IPC_TO_STRING(c));
278                         }
279                         break;
280                 case 'v':
281                 case 'y':
282                         /* Handled in other getopt() loop */
283                         break;
284                 case 'W':
285                         msgrm(-1, 0);
286                         shmrm(-1, 0);
287                         semrm(-1, 0);
288                         break;
289                 case ':':
290                         fprintf(stderr,
291                             "option -%c requires an argument\n", optopt);
292                         usage();
293                 case '?':
294                         fprintf(stderr, "unrecognized option: -%c\n", optopt);
295                         usage();
296                 }
297         }
298
299         if (optind != argc) {
300                 fprintf(stderr, "unknown argument: %s\n", argv[optind]);
301                 usage();
302         }
303         exit(errflg);
304 }