1 /* vi: set sw=4 ts=4: */
3 * ipcrm.c -- utility to allow removal of IPC objects and data structures.
5 * 01 Sept 2004 - Rodney Radford <rradford@mindspring.com>
6 * Adapted for busybox from util-linux-2.12a.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * --- Pre-busybox history from util-linux-2.12a ------------------------
24 * 1999-04-02 frank zago
25 * - can now remove several id's in the same call
27 * 1999-02-22 Arkadiusz Miÿkiewicz <misiek@pld.ORG.PL>
28 * - added Native Language Support
30 * Original author - krishna balasubramanian 1993
38 #include <sys/types.h>
44 /* X/OPEN tells us to use <sys/{types,ipc,sem}.h> for semctl() */
45 /* X/OPEN tells us to use <sys/{types,ipc,msg}.h> for msgctl() */
49 /* for tolower and isupper */
54 #if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
55 /* union semun is defined by including <sys/sem.h> */
57 /* according to X/OPEN we have to define it ourselves */
61 unsigned short int *array;
62 struct seminfo *__buf;
66 typedef enum type_id {
73 remove_ids(type_id type, int argc, char **argv) {
75 int ret = 0; /* for gcc */
84 id = strtoul(argv[0], &end, 10);
87 bb_printf ("invalid id: %s\n", argv[0]);
92 ret = semctl (id, 0, IPC_RMID, arg);
96 ret = msgctl (id, IPC_RMID, NULL);
100 ret = shmctl (id, IPC_RMID, NULL);
105 bb_printf ("cannot remove id %s (%s)\n",
106 argv[0], strerror(errno));
117 static int deprecated_main(int argc, char **argv)
121 bb_fflush_stdout_and_exit(1);
124 if (!strcmp(argv[1], "shm")) {
125 if (remove_ids(SHM, argc-2, &argv[2]))
126 bb_fflush_stdout_and_exit(1);
128 else if (!strcmp(argv[1], "msg")) {
129 if (remove_ids(MSG, argc-2, &argv[2]))
130 bb_fflush_stdout_and_exit(1);
132 else if (!strcmp(argv[1], "sem")) {
133 if (remove_ids(SEM, argc-2, &argv[2]))
134 bb_fflush_stdout_and_exit(1);
137 bb_printf ("unknown resource type: %s\n", argv[1]);
139 bb_fflush_stdout_and_exit(1);
142 bb_printf ("resource(s) deleted\n");
147 int ipcrm_main(int argc, char **argv)
151 char *prog = argv[0];
153 /* if the command is executed without parameters, do nothing */
157 /* check to see if the command is being invoked in the old way if so
158 then run the old code */
159 if (strcmp(argv[1], "shm") == 0 ||
160 strcmp(argv[1], "msg") == 0 ||
161 strcmp(argv[1], "sem") == 0)
162 return deprecated_main(argc, argv);
164 /* process new syntax to conform with SYSV ipcrm */
165 while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) {
168 int iskey = isupper(c);
170 /* needed to delete semaphores */
174 if ((c == '?') || (c == 'h'))
180 /* we don't need case information any more */
183 /* make sure the option is in range */
184 if (c != 'q' && c != 'm' && c != 's') {
191 /* keys are in hex or decimal */
192 key_t key = strtoul(optarg, NULL, 0);
193 if (key == IPC_PRIVATE) {
195 bb_fprintf(stderr, "%s: illegal key (%s)\n",
200 /* convert key to id */
201 id = ((c == 'q') ? msgget(key, 0) :
202 (c == 'm') ? shmget(key, 0, 0) :
210 errmsg = "permission denied for key";
213 errmsg = "already removed key";
216 errmsg = "invalid key";
219 errmsg = "unknown error in key";
222 bb_fprintf(stderr, "%s: %s (%s)\n",
223 prog, errmsg, optarg);
227 /* ids are in decimal */
228 id = strtoul(optarg, NULL, 10);
231 result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
232 (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
233 semctl(id, 0, IPC_RMID, arg));
242 ? "permission denied for key"
243 : "permission denied for id";
252 ? "already removed key"
253 : "already removed id";
257 ? "unknown error in key"
258 : "unknown error in id";
261 bb_fprintf(stderr, "%s: %s (%s)\n",
262 prog, errmsg, optarg);
267 /* print usage if we still have some arguments left over */
268 if (optind != argc) {
272 /* exit value reflects the number of errors encountered */