summaryrefslogtreecommitdiffstats
path: root/sys-utils/ipcrm.c
diff options
context:
space:
mode:
authorKarel Zak2006-12-07 00:25:54 +0100
committerKarel Zak2006-12-07 00:25:54 +0100
commit1d4ad1decc539c9729b592e6050460d6487c95f4 (patch)
treec158c5f5baf15ea4bab5c05b2f6e2bdaca332c29 /sys-utils/ipcrm.c
parentImported from util-linux-2.11o tarball. (diff)
downloadkernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.tar.gz
kernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.tar.xz
kernel-qcow2-util-linux-1d4ad1decc539c9729b592e6050460d6487c95f4.zip
Imported from util-linux-2.11q tarball.
Diffstat (limited to 'sys-utils/ipcrm.c')
-rw-r--r--sys-utils/ipcrm.c174
1 files changed, 158 insertions, 16 deletions
diff --git a/sys-utils/ipcrm.c b/sys-utils/ipcrm.c
index 3e3a9ba02..09ba14454 100644
--- a/sys-utils/ipcrm.c
+++ b/sys-utils/ipcrm.c
@@ -21,6 +21,11 @@
#include <sys/sem.h>
#include "nls.h"
+/* for getopt */
+#include <unistd.h>
+/* for tolower and isupper */
+#include <ctype.h>
+
#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* union semun is defined by including <sys/sem.h> */
#else
@@ -33,6 +38,8 @@ union semun {
};
#endif
+static void usage(char *);
+
char *execname;
typedef enum type_id {
@@ -86,41 +93,36 @@ remove_ids(type_id type, int argc, char **argv) {
return(nb_errors);
}
-static void display_usage(void)
+static void deprecate_display_usage(void)
{
- printf (_("usage: %s {shm | msg | sem} id ...\n"), execname);
+ usage(execname);
+ printf (_("deprecated usage: %s {shm | msg | sem} id ...\n"),
+ execname);
}
-int main(int argc, char **argv)
+static int deprecated_main(int argc, char **argv)
{
execname = argv[0];
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
if (argc < 3) {
- display_usage();
+ deprecate_display_usage();
exit(1);
}
if (!strcmp(argv[1], "shm")) {
- if (remove_ids(SHM, argc-2, &argv[2])) {
+ if (remove_ids(SHM, argc-2, &argv[2]))
exit(1);
- }
}
else if (!strcmp(argv[1], "msg")) {
- if (remove_ids(MSG, argc-2, &argv[2])) {
+ if (remove_ids(MSG, argc-2, &argv[2]))
exit(1);
- }
}
else if (!strcmp(argv[1], "sem")) {
- if (remove_ids(SEM, argc-2, &argv[2])) {
+ if (remove_ids(SEM, argc-2, &argv[2]))
exit(1);
- }
}
else {
- display_usage();
+ deprecate_display_usage();
printf (_("unknown resource type: %s\n"), argv[1]);
exit(1);
}
@@ -128,4 +130,144 @@ int main(int argc, char **argv)
printf (_("resource(s) deleted\n"));
return 0;
}
-
+
+
+/* print the new usage */
+static void
+usage(char *progname)
+{
+ fprintf(stderr,
+ _("usage: %s [ [-q msqid] [-m shmid] [-s semid]\n"
+ " [-Q msgkey] [-M shmkey] [-S semkey] ... ]\n"),
+ progname);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int error = 0;
+ char *prog = argv[0];
+
+ /* if the command is executed without parameters, do nothing */
+ if (argc == 1)
+ return 0;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* check to see if the command is being invoked in the old way if so
+ then run the old code */
+ if (strcmp(argv[1], "shm") == 0 ||
+ strcmp(argv[1], "msg") == 0 ||
+ strcmp(argv[1], "sem") == 0)
+ return deprecated_main(argc, argv);
+
+ /* process new syntax to conform with SYSV ipcrm */
+ while ((c = getopt(argc, argv, "q:m:s:Q:M:S:")) != -1) {
+ int result;
+ int id = 0;
+ int iskey = isupper(c);
+
+ /* needed to delete semaphores */
+ union semun arg;
+ arg.val = 0;
+
+ /* we don't need case information any more */
+ c = tolower(c);
+
+ /* make sure the option is in range */
+ if (c != 'q' && c != 'm' && c != 's') {
+ fprintf(stderr, _("%s: illegal option -- %c\n"),
+ prog, c);
+ usage(prog);
+ error++;
+ }
+
+ if (iskey) {
+ /* keys are in hex or decimal */
+ key_t key = strtoul(optarg, NULL, 0);
+ if (key == IPC_PRIVATE) {
+ error++;
+ fprintf(stderr, _("%s: illegal key (%s)\n"),
+ prog, optarg);
+ continue;
+ }
+
+ /* convert key to id */
+ id = ((c == 'q') ? msgget(key, 0) :
+ (c == 'm') ? shmget(key, 0, 0) :
+ semget(key, 0, 0));
+
+ if (id < 0) {
+ char *errmsg;
+ error++;
+ switch(errno) {
+ case EACCES:
+ errmsg = _("permission denied for key");
+ break;
+ case EIDRM:
+ errmsg = _("already removed key");
+ break;
+ case ENOENT:
+ errmsg = _("invalid key");
+ break;
+ default:
+ errmsg = _("unknown error in key");
+ break;
+ }
+ fprintf(stderr, "%s: %s (%s)\n",
+ prog, errmsg, optarg);
+ continue;
+ }
+ } else {
+ /* ids are in decimal */
+ id = strtoul(optarg, NULL, 10);
+ }
+
+ result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
+ (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
+ semctl(id, 0, IPC_RMID, arg));
+
+ if (result < 0) {
+ char *errmsg;
+ error++;
+ switch(errno) {
+ case EACCES:
+ case EPERM:
+ errmsg = iskey
+ ? _("permission denied for key")
+ : _("permission denied for id");
+ break;
+ case EINVAL:
+ errmsg = iskey
+ ? _("invalid key")
+ : _("invalid id");
+ break;
+ case EIDRM:
+ errmsg = iskey
+ ? _("already removed key")
+ : _("already removed id");
+ break;
+ default:
+ errmsg = iskey
+ ? _("unknown error in key")
+ : _("unknown error in id");
+ break;
+ }
+ fprintf(stderr, _("%s: %s (%s)\n"),
+ prog, errmsg, optarg);
+ continue;
+ }
+ }
+
+ /* print usage if we still have some arguments left over */
+ if (optind != argc) {
+ fprintf(stderr, _("%s: unknown argument: %s\n"),
+ prog, argv[optind]);
+ usage(prog);
+ }
+
+ /* exit value reflects the number of errors encountered */
+ return error;
+}