2 * krishna balasubramanian 1993
4 * 1999-02-22 Arkadiusz MiĆkiewicz <misiek@pld.ORG.PL>
5 * - added Native Language Support
7 * 1999-04-02 frank zago
8 * - can now remove several id's in the same call
21 #include <sys/types.h>
25 #include "closestream.h"
27 #ifndef HAVE_UNION_SEMUN
28 /* according to X/OPEN we have to define it ourselves */
32 unsigned short int *array
;
33 struct seminfo
*__buf
;
37 typedef enum type_id
{
44 static int verbose
= 0;
47 static void __attribute__((__noreturn__
)) usage(void)
50 fputs(USAGE_HEADER
, out
);
51 fprintf(out
, _(" %1$s [options]\n"
52 " %1$s shm|msg|sem <id>...\n"), program_invocation_short_name
);
54 fputs(USAGE_SEPARATOR
, out
);
55 fputs(_("Remove certain IPC resources.\n"), out
);
57 fputs(USAGE_OPTIONS
, out
);
58 fputs(_(" -m, --shmem-id <id> remove shared memory segment by id\n"), out
);
59 fputs(_(" -M, --shmem-key <key> remove shared memory segment by key\n"), out
);
60 fputs(_(" -q, --queue-id <id> remove message queue by id\n"), out
);
61 fputs(_(" -Q, --queue-key <key> remove message queue by key\n"), out
);
62 fputs(_(" -s, --semaphore-id <id> remove semaphore by id\n"), out
);
63 fputs(_(" -S, --semaphore-key <key> remove semaphore by key\n"), out
);
64 fputs(_(" -a, --all[=shm|msg|sem] remove all (in the specified category)\n"), out
);
65 fputs(_(" -v, --verbose explain what is being done\n"), out
);
67 fputs(USAGE_SEPARATOR
, out
);
68 printf(USAGE_HELP_OPTIONS(28));
69 printf(USAGE_MAN_TAIL("ipcrm(1)"));
74 static int remove_id(int type
, int iskey
, int id
)
78 /* needed to delete semaphores */
86 printf(_("removing shared memory segment id `%d'\n"), id
);
87 ret
= shmctl(id
, IPC_RMID
, NULL
);
91 printf(_("removing message queue id `%d'\n"), id
);
92 ret
= msgctl(id
, IPC_RMID
, NULL
);
96 printf(_("removing semaphore id `%d'\n"), id
);
97 ret
= semctl(id
, 0, IPC_RMID
, arg
);
100 errx(EXIT_FAILURE
, "impossible occurred");
103 /* how did the removal go? */
108 errmsg
= iskey
? _("permission denied for key") : _("permission denied for id");
111 errmsg
= iskey
? _("invalid key") : _("invalid id");
114 errmsg
= iskey
? _("already removed key") : _("already removed id");
117 err(EXIT_FAILURE
, "%s", iskey
? _("key failed") : _("id failed"));
119 warnx("%s (%d)", errmsg
, id
);
125 static int remove_arg_list(type_id type
, int argc
, char **argv
)
132 id
= strtoul(argv
[0], &end
, 10);
134 warnx(_("invalid id: %s"), argv
[0]);
137 if (remove_id(type
, 0, id
))
146 static int deprecated_main(int argc
, char **argv
)
150 if (!strcmp(argv
[1], "shm"))
152 else if (!strcmp(argv
[1], "msg"))
154 else if (!strcmp(argv
[1], "sem"))
160 warnx(_("not enough arguments"));
161 errtryhelp(EXIT_FAILURE
);
164 if (remove_arg_list(type
, argc
- 2, &argv
[2]))
167 printf(_("resource(s) deleted\n"));
171 static unsigned long strtokey(const char *str
, const char *errmesg
)
176 if (str
== NULL
|| *str
== '\0')
179 /* keys are in hex or decimal */
180 num
= strtoul(str
, &end
, 0);
182 if (errno
|| str
== end
|| (end
&& *end
))
188 err(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
190 errx(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
194 static int key_to_id(type_id type
, char *s
)
197 /* keys are in hex or decimal */
198 key_t key
= strtokey(s
, "failed to parse argument");
199 if (key
== IPC_PRIVATE
) {
200 warnx(_("illegal key (%s)"), s
);
205 id
= shmget(key
, 0, 0);
211 id
= semget(key
, 0, 0);
216 errx(EXIT_FAILURE
, "impossible occurred");
222 errmsg
= _("permission denied for key");
225 errmsg
= _("already removed key");
228 errmsg
= _("invalid key");
231 err(EXIT_FAILURE
, _("key failed"));
233 warnx("%s (%s)", errmsg
, s
);
238 static int remove_all(type_id type
)
241 int id
, rm_me
, maxid
;
243 struct shmid_ds shmseg
;
245 struct semid_ds semary
;
246 struct seminfo seminfo
;
249 struct msqid_ds msgque
;
250 struct msginfo msginfo
;
252 if (type
== SHM
|| type
== ALL
) {
253 maxid
= shmctl(0, SHM_INFO
, &shmseg
);
256 _("kernel not configured for shared memory"));
257 for (id
= 0; id
<= maxid
; id
++) {
258 rm_me
= shmctl(id
, SHM_STAT
, &shmseg
);
261 ret
|= remove_id(SHM
, 0, rm_me
);
264 if (type
== SEM
|| type
== ALL
) {
265 arg
.array
= (ushort
*) (void *)&seminfo
;
266 maxid
= semctl(0, 0, SEM_INFO
, arg
);
269 _("kernel not configured for semaphores"));
270 for (id
= 0; id
<= maxid
; id
++) {
271 arg
.buf
= (struct semid_ds
*)&semary
;
272 rm_me
= semctl(id
, 0, SEM_STAT
, arg
);
275 ret
|= remove_id(SEM
, 0, rm_me
);
278 /* kFreeBSD hackery -- ah 20140723 */
285 if (type
== MSG
|| type
== ALL
) {
287 msgctl(0, MSG_INFO
, (struct msqid_ds
*)(void *)&msginfo
);
290 _("kernel not configured for message queues"));
291 for (id
= 0; id
<= maxid
; id
++) {
292 rm_me
= msgctl(id
, MSG_STAT
, &msgque
);
295 ret
|= remove_id(MSG
, 0, rm_me
);
301 int main(int argc
, char **argv
)
308 type_id what_all
= ALL
;
310 static const struct option longopts
[] = {
311 {"shmem-id", required_argument
, NULL
, 'm'},
312 {"shmem-key", required_argument
, NULL
, 'M'},
313 {"queue-id", required_argument
, NULL
, 'q'},
314 {"queue-key", required_argument
, NULL
, 'Q'},
315 {"semaphore-id", required_argument
, NULL
, 's'},
316 {"semaphore-key", required_argument
, NULL
, 'S'},
317 {"all", optional_argument
, NULL
, 'a'},
318 {"verbose", no_argument
, NULL
, 'v'},
319 {"version", no_argument
, NULL
, 'V'},
320 {"help", no_argument
, NULL
, 'h'},
324 /* if the command is executed without parameters, do nothing */
328 setlocale(LC_ALL
, "");
329 bindtextdomain(PACKAGE
, LOCALEDIR
);
331 atexit(close_stdout
);
333 /* check to see if the command is being invoked in the old way if so
334 * then remove argument list */
335 if (deprecated_main(argc
, argv
))
338 /* process new syntax to conform with SYSV ipcrm */
339 while((c
= getopt_long(argc
, argv
, "q:m:s:Q:M:S:a::vhV", longopts
, NULL
)) != -1) {
344 id
= key_to_id(SHM
, optarg
);
352 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
353 if (remove_id(SHM
, iskey
, id
))
358 id
= key_to_id(MSG
, optarg
);
366 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
367 if (remove_id(MSG
, iskey
, id
))
372 id
= key_to_id(SEM
, optarg
);
380 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
381 if (remove_id(SEM
, iskey
, id
))
387 if (!strcmp(optarg
, "shm"))
389 else if (!strcmp(optarg
, "msg"))
391 else if (!strcmp(optarg
, "sem"))
395 _("unknown argument: %s"), optarg
);
406 printf(UTIL_LINUX_VERSION
);
409 errtryhelp(EXIT_FAILURE
);
413 if (rm_all
&& remove_all(what_all
))
416 /* print usage if we still have some arguments left over */
418 warnx(_("unknown argument: %s"), argv
[optind
]);
419 errtryhelp(EXIT_FAILURE
);
422 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;