]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/ipcrm/ipcrm.c
Add 'contrib/unifdef/' from commit '0da44885831dc0a43c4ca6ff04a2430993cc0a80'
[FreeBSD/FreeBSD.git] / usr.bin / ipcrm / ipcrm.c
1 /*-
2  * SPDX-License-Identifier: BSD-4-Clause
3  *
4  * Copyright (c) 1994 Adam Glass
5  * All rights reserved.
6  *
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.
20  *
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.
32  *
33  */
34
35 #include <sys/cdefs.h>
36 #include <sys/param.h>
37 #define _WANT_SYSVMSG_INTERNALS
38 #include <sys/msg.h>
39 #define _WANT_SYSVSEM_INTERNALS
40 #define _WANT_SEMUN
41 #include <sys/sem.h>
42 #define _WANT_SYSVSHM_INTERNALS
43 #include <sys/shm.h>
44
45 #include <ctype.h>
46 #include <err.h>
47 #include <grp.h>
48 #include <kvm.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <unistd.h>
52
53 #include "ipc.h"
54
55 static int      signaled;
56 static int      errflg;
57 static int      rmverbose = 0;
58
59 static void
60 usage(void)
61 {
62
63         fprintf(stderr,
64             "usage: ipcrm [-W] [-v[v]]\n"
65             "             [-q msqid] [-m shmid] [-s semid]\n"
66             "             [-Q msgkey] [-M shmkey] [-S semkey] ...\n");
67         exit(1);
68 }
69
70 static int
71 msgrm(key_t key, int id)
72 {
73
74         if (key == -1 || id == -1) {
75                 struct msqid_kernel *kxmsqids;
76                 size_t kxmsqids_len;
77                 int num;
78
79                 kget(X_MSGINFO, &msginfo, sizeof(msginfo));
80                 kxmsqids_len = sizeof(struct msqid_kernel) * msginfo.msgmni;
81                 kxmsqids = malloc(kxmsqids_len);
82                 kget(X_MSQIDS, kxmsqids, kxmsqids_len);
83                 num = msginfo.msgmni;
84                 while (num-- && !signaled)
85                         if (kxmsqids[num].u.msg_qbytes != 0) {
86                                 id = IXSEQ_TO_IPCID(num,
87                                         kxmsqids[num].u.msg_perm);
88                                 if (msgctl(id, IPC_RMID, NULL) < 0) {
89                                         if (rmverbose > 1)
90                                                 warn("msqid(%d): ", id);
91                                         errflg++;
92                                 } else
93                                         if (rmverbose)
94                                                 printf(
95                                                     "Removed %s %d\n",
96                                                     IPC_TO_STRING('Q'),
97                                                     id);
98                         }
99                 return signaled ? -1 : 0;       /* errors maybe handled above */
100         }
101
102         if (key) {
103                 id = msgget(key, 0);
104                 if (id == -1)
105                         return -1;
106         }
107
108         return msgctl(id, IPC_RMID, NULL);
109 }
110
111 static int
112 shmrm(key_t key, int id)
113 {
114
115         if (key == -1 || id == -1) {
116                 struct shmid_kernel *kxshmids;
117                 size_t kxshmids_len;
118                 int num;
119
120                 kget(X_SHMINFO, &shminfo, sizeof(shminfo));
121                 kxshmids_len = sizeof(struct shmid_kernel) * shminfo.shmmni;
122                 kxshmids = malloc(kxshmids_len);
123                 kget(X_SHMSEGS, kxshmids, kxshmids_len);
124                 num = shminfo.shmmni;
125                 while (num-- && !signaled)
126                         if (kxshmids[num].u.shm_perm.mode & 0x0800) {
127                                 id = IXSEQ_TO_IPCID(num,
128                                         kxshmids[num].u.shm_perm);
129                                 if (shmctl(id, IPC_RMID, NULL) < 0) {
130                                         if (rmverbose > 1)
131                                                 warn("shmid(%d): ", id);
132                                         errflg++;
133                                 } else
134                                         if (rmverbose)
135                                                 printf(
136                                                     "Removed %s %d\n",
137                                                     IPC_TO_STRING('M'),
138                                                     id);
139                         }
140                 return signaled ? -1 : 0;       /* errors maybe handled above */
141         }
142
143         if (key) {
144                 id = shmget(key, 0, 0);
145                 if (id == -1)
146                         return -1;
147         }
148
149         return shmctl(id, IPC_RMID, NULL);
150 }
151
152 static int
153 semrm(key_t key, int id)
154 {
155         union semun arg;
156
157         if (key == -1 || id == -1) {
158                 struct semid_kernel *kxsema;
159                 size_t kxsema_len;
160                 int num;
161
162                 kget(X_SEMINFO, &seminfo, sizeof(seminfo));
163                 kxsema_len = sizeof(struct semid_kernel) * seminfo.semmni;
164                 kxsema = malloc(kxsema_len);
165                 kget(X_SEMA, kxsema, kxsema_len);
166                 num = seminfo.semmni;
167                 while (num-- && !signaled)
168                         if ((kxsema[num].u.sem_perm.mode & SEM_ALLOC) != 0) {
169                                 id = IXSEQ_TO_IPCID(num,
170                                         kxsema[num].u.sem_perm);
171                                 if (semctl(id, 0, IPC_RMID, NULL) < 0) {
172                                         if (rmverbose > 1)
173                                                 warn("semid(%d): ", id);
174                                         errflg++;
175                                 } else
176                                         if (rmverbose)
177                                                 printf(
178                                                     "Removed %s %d\n",
179                                                     IPC_TO_STRING('S'),
180                                                     id);
181                         }
182                 return signaled ? -1 : 0;       /* errors maybe handled above */
183         }
184
185         if (key) {
186                 id = semget(key, 0, 0);
187                 if (id == -1)
188                         return -1;
189         }
190
191         return semctl(id, 0, IPC_RMID, arg);
192 }
193
194 static void
195 not_configured(int signo __unused)
196 {
197
198         signaled++;
199 }
200
201 int
202 main(int argc, char *argv[])
203 {
204         int c, result, target_id;
205         key_t target_key;
206
207         while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
208
209                 signaled = 0;
210                 switch (c) {
211                 case 'v':
212                         rmverbose++;
213                         break;
214                 case 'y':
215                         use_sysctl = 0;
216                         break;
217                 }
218         }
219
220         optind = 1;
221         errflg = 0;
222         signal(SIGSYS, not_configured);
223         while ((c = getopt(argc, argv, "q:m:s:Q:M:S:vWy")) != -1) {
224
225                 signaled = 0;
226                 switch (c) {
227                 case 'q':
228                 case 'm':
229                 case 's':
230                         target_id = atoi(optarg);
231                         if (c == 'q')
232                                 result = msgrm(0, target_id);
233                         else if (c == 'm')
234                                 result = shmrm(0, target_id);
235                         else
236                                 result = semrm(0, target_id);
237                         if (result < 0) {
238                                 errflg++;
239                                 if (!signaled)
240                                         warn("%sid(%d): ",
241                                             IPC_TO_STR(toupper(c)), target_id);
242                                 else
243                                         warnx(
244                                             "%ss are not configured "
245                                             "in the running kernel",
246                                             IPC_TO_STRING(toupper(c)));
247                         }
248                         break;
249                 case 'Q':
250                 case 'M':
251                 case 'S':
252                         target_key = atol(optarg);
253                         if (target_key == IPC_PRIVATE) {
254                                 warnx("can't remove private %ss",
255                                     IPC_TO_STRING(c));
256                                 continue;
257                         }
258                         if (c == 'Q')
259                                 result = msgrm(target_key, 0);
260                         else if (c == 'M')
261                                 result = shmrm(target_key, 0);
262                         else
263                                 result = semrm(target_key, 0);
264                         if (result < 0) {
265                                 errflg++;
266                                 if (!signaled)
267                                         warn("%ss(%ld): ",
268                                             IPC_TO_STR(c), target_key);
269                                 else
270                                         warnx("%ss are not configured "
271                                             "in the running kernel",
272                                             IPC_TO_STRING(c));
273                         }
274                         break;
275                 case 'v':
276                 case 'y':
277                         /* Handled in other getopt() loop */
278                         break;
279                 case 'W':
280                         msgrm(-1, 0);
281                         shmrm(-1, 0);
282                         semrm(-1, 0);
283                         break;
284                 case ':':
285                         fprintf(stderr,
286                             "option -%c requires an argument\n", optopt);
287                         usage();
288                 case '?':
289                         fprintf(stderr, "unrecognized option: -%c\n", optopt);
290                         usage();
291                 }
292         }
293
294         if (optind != argc) {
295                 fprintf(stderr, "unknown argument: %s\n", argv[optind]);
296                 usage();
297         }
298         exit(errflg);
299 }