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
18 #include <sys/types.h>
29 /* for tolower and isupper */
32 #ifndef HAVE_UNION_SEMUN
33 /* according to X/OPEN we have to define it ourselves */
37 unsigned short int *array
;
38 struct seminfo
*__buf
;
42 typedef enum type_id
{
48 /* print the new usage */
49 static void __attribute__ ((__noreturn__
)) usage(FILE * out
)
51 fprintf(out
, USAGE_HEADER
);
52 fprintf(out
, " %s [options]\n", program_invocation_short_name
);
53 fprintf(out
, " %s <shm|msg|sem> <id> [...]\n", program_invocation_short_name
);
54 fprintf(out
, USAGE_OPTIONS
);
55 fputs(_(" -m, --shmem-id <id> remove shared memory segment by shmid\n"), out
);
56 fputs(_(" -M, --shmem-key <key> remove shared memory segment by key\n"), out
);
57 fputs(_(" -q, --queue-id <id> remove message queue by id\n"), out
);
58 fputs(_(" -Q, --queue-key <key> remove message queue by key\n"), out
);
59 fputs(_(" -s, --semaphore-id <id> remove semaprhore by id\n"), out
);
60 fputs(_(" -S, --semaphore-key <key> remove semaprhore by key\n"), out
);
61 fprintf(out
, USAGE_HELP
);
62 fprintf(out
, USAGE_VERSION
);
63 fprintf(out
, USAGE_BEGIN_TAIL
);
64 fprintf(out
, USAGE_MAN_TAIL
, "ipcrm(1)");
65 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
68 int remove_id(int type
, int iskey
, int id
)
71 /* needed to delete semaphores */
78 shmctl(id
, IPC_RMID
, NULL
);
81 msgctl(id
, IPC_RMID
, NULL
);
84 semctl(id
, 0, IPC_RMID
, arg
);
87 errx(EXIT_FAILURE
, "impossible occurred");
90 /* how did the removal go? */
96 errmsg
= iskey
? _("permission denied for key") : _("permission denied for id");
99 errmsg
= iskey
? _("invalid key") : _("invalid id");
102 errmsg
= iskey
? _("already removed key") : _("already removed id");
106 err(EXIT_FAILURE
, _("key failed"));
107 err(EXIT_FAILURE
, _("id failed"));
109 warnx("%s (%d)", errmsg
, id
);
113 static int remove_arg_list(type_id type
, int argc
, char **argv
)
120 id
= strtoul(argv
[0], &end
, 10);
122 warnx(_("invalid id: %s"), argv
[0]);
125 if (remove_id(type
, 0, id
))
134 static int deprecated_main(int argc
, char **argv
)
138 if (!strcmp(argv
[1], "shm"))
140 else if (!strcmp(argv
[1], "msg"))
142 else if (!strcmp(argv
[1], "sem"))
148 warnx(_("not enough arguments"));
152 if (remove_arg_list(type
, argc
- 2, &argv
[2]))
155 printf(_("resource(s) deleted\n"));
159 unsigned long strtokey(const char *str
, const char *errmesg
)
164 if (str
== NULL
|| *str
== '\0')
167 /* keys are in hex or decimal */
168 num
= strtoul(str
, &end
, 0);
170 if (errno
|| str
== end
|| (end
&& *end
))
176 err(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
178 errx(EXIT_FAILURE
, "%s: '%s'", errmesg
, str
);
182 static int key_to_id(type_id type
, char *optarg
)
185 /* keys are in hex or decimal */
186 key_t key
= strtokey(optarg
, "failed to parse argument");
187 if (key
== IPC_PRIVATE
) {
188 warnx(_("illegal key (%s)"), optarg
);
193 id
= shmget(key
, 0, 0);
199 id
= semget(key
, 0, 0);
202 errx(EXIT_FAILURE
, "impossible occurred");
208 errmsg
= _("permission denied for key");
211 errmsg
= _("already removed key");
214 errmsg
= _("invalid key");
217 err(EXIT_FAILURE
, _("key failed"));
219 warnx("%s (%s)", errmsg
, optarg
);
224 int main(int argc
, char **argv
)
231 static const struct option longopts
[] = {
232 {"shmem-id", required_argument
, NULL
, 'm'},
233 {"shmem-key", required_argument
, NULL
, 'M'},
234 {"queue-id", required_argument
, NULL
, 'q'},
235 {"queue-key", required_argument
, NULL
, 'Q'},
236 {"semaphore-id", required_argument
, NULL
, 's'},
237 {"semaphore-key", required_argument
, NULL
, 'S'},
238 {"version", no_argument
, NULL
, 'V'},
239 {"help", no_argument
, NULL
, 'h'},
243 /* if the command is executed without parameters, do nothing */
247 setlocale(LC_ALL
, "");
248 bindtextdomain(PACKAGE
, LOCALEDIR
);
251 /* check to see if the command is being invoked in the old way if so
252 * then remove argument list */
253 if (deprecated_main(argc
, argv
))
256 /* process new syntax to conform with SYSV ipcrm */
258 (c
= getopt_long(argc
, argv
, "q:m:s:Q:M:S:hV", longopts
, NULL
)) != -1;
263 id
= key_to_id(SHM
, optarg
);
271 id
= strtoll_or_err(optarg
, _("failed to parse argument"));
273 if (remove_id(SHM
, iskey
, id
))
278 id
= key_to_id(MSG
, optarg
);
286 id
= strtoll_or_err(optarg
, _("failed to parse argument"));
288 if (remove_id(MSG
, iskey
, id
))
293 id
= key_to_id(SEM
, optarg
);
301 id
= strtoll_or_err(optarg
, _("failed to parse argument"));
303 if (remove_id(SEM
, iskey
, id
))
309 printf(UTIL_LINUX_VERSION
);
316 /* print usage if we still have some arguments left over */
317 if (optind
!= argc
) {
318 warnx(_("unknown argument: %s"), argv
[optind
]);
322 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;