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
)
133 id
= strtoul(argv
[0], &end
, 10);
134 if (errno
|| !end
|| *end
!= 0) {
135 warnx(_("invalid id: %s"), argv
[0]);
138 if (remove_id(type
, 0, id
))
147 static int deprecated_main(int argc
, char **argv
)
151 if (!strcmp(argv
[1], "shm"))
153 else if (!strcmp(argv
[1], "msg"))
155 else if (!strcmp(argv
[1], "sem"))
161 warnx(_("not enough arguments"));
162 errtryhelp(EXIT_FAILURE
);
165 if (remove_arg_list(type
, argc
- 2, &argv
[2]))
168 printf(_("resource(s) deleted\n"));
172 static unsigned long strtokey(const char *str
, const char *errmesg
)
177 if (str
== NULL
|| *str
== '\0')
180 /* keys are in hex or decimal */
181 num
= strtoul(str
, &end
, 0);
183 if (errno
|| str
== end
|| (end
&& *end
))
189 err(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
191 errx(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
195 static int key_to_id(type_id type
, char *s
)
198 /* keys are in hex or decimal */
199 key_t key
= strtokey(s
, "failed to parse argument");
200 if (key
== IPC_PRIVATE
) {
201 warnx(_("illegal key (%s)"), s
);
206 id
= shmget(key
, 0, 0);
212 id
= semget(key
, 0, 0);
217 errx(EXIT_FAILURE
, "impossible occurred");
223 errmsg
= _("permission denied for key");
226 errmsg
= _("already removed key");
229 errmsg
= _("invalid key");
232 err(EXIT_FAILURE
, _("key failed"));
234 warnx("%s (%s)", errmsg
, s
);
239 static int remove_all(type_id type
)
242 int id
, rm_me
, maxid
;
244 struct shmid_ds shmseg
;
246 struct semid_ds semary
;
247 struct seminfo seminfo
;
250 struct msqid_ds msgque
;
251 struct msginfo msginfo
;
253 if (type
== SHM
|| type
== ALL
) {
254 maxid
= shmctl(0, SHM_INFO
, &shmseg
);
257 _("kernel not configured for shared memory"));
258 for (id
= 0; id
<= maxid
; id
++) {
259 rm_me
= shmctl(id
, SHM_STAT
, &shmseg
);
262 ret
|= remove_id(SHM
, 0, rm_me
);
265 if (type
== SEM
|| type
== ALL
) {
266 arg
.array
= (ushort
*) (void *)&seminfo
;
267 maxid
= semctl(0, 0, SEM_INFO
, arg
);
270 _("kernel not configured for semaphores"));
271 for (id
= 0; id
<= maxid
; id
++) {
272 arg
.buf
= (struct semid_ds
*)&semary
;
273 rm_me
= semctl(id
, 0, SEM_STAT
, arg
);
276 ret
|= remove_id(SEM
, 0, rm_me
);
279 /* kFreeBSD hackery -- ah 20140723 */
286 if (type
== MSG
|| type
== ALL
) {
288 msgctl(0, MSG_INFO
, (struct msqid_ds
*)(void *)&msginfo
);
291 _("kernel not configured for message queues"));
292 for (id
= 0; id
<= maxid
; id
++) {
293 rm_me
= msgctl(id
, MSG_STAT
, &msgque
);
296 ret
|= remove_id(MSG
, 0, rm_me
);
302 int main(int argc
, char **argv
)
309 type_id what_all
= ALL
;
311 static const struct option longopts
[] = {
312 {"shmem-id", required_argument
, NULL
, 'm'},
313 {"shmem-key", required_argument
, NULL
, 'M'},
314 {"queue-id", required_argument
, NULL
, 'q'},
315 {"queue-key", required_argument
, NULL
, 'Q'},
316 {"semaphore-id", required_argument
, NULL
, 's'},
317 {"semaphore-key", required_argument
, NULL
, 'S'},
318 {"all", optional_argument
, NULL
, 'a'},
319 {"verbose", no_argument
, NULL
, 'v'},
320 {"version", no_argument
, NULL
, 'V'},
321 {"help", no_argument
, NULL
, 'h'},
325 /* if the command is executed without parameters, do nothing */
329 setlocale(LC_ALL
, "");
330 bindtextdomain(PACKAGE
, LOCALEDIR
);
332 close_stdout_atexit();
334 /* check to see if the command is being invoked in the old way if so
335 * then remove argument list */
336 if (deprecated_main(argc
, argv
))
339 /* process new syntax to conform with SYSV ipcrm */
340 while((c
= getopt_long(argc
, argv
, "q:m:s:Q:M:S:a::vhV", longopts
, NULL
)) != -1) {
345 id
= key_to_id(SHM
, optarg
);
353 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
354 if (remove_id(SHM
, iskey
, id
))
359 id
= key_to_id(MSG
, optarg
);
367 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
368 if (remove_id(MSG
, iskey
, id
))
373 id
= key_to_id(SEM
, optarg
);
381 id
= strtos32_or_err(optarg
, _("failed to parse argument"));
382 if (remove_id(SEM
, iskey
, id
))
388 if (!strcmp(optarg
, "shm"))
390 else if (!strcmp(optarg
, "msg"))
392 else if (!strcmp(optarg
, "sem"))
396 _("unknown argument: %s"), optarg
);
408 print_version(EXIT_SUCCESS
);
410 errtryhelp(EXIT_FAILURE
);
414 if (rm_all
&& remove_all(what_all
))
417 /* print usage if we still have some arguments left over */
419 warnx(_("unknown argument: %s"), argv
[optind
]);
420 errtryhelp(EXIT_FAILURE
);
423 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;