X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Fipcrm.c;h=5dcda859a9cdcc99a85c55d9615e32f8642e53ce;hb=11c17f75a7f29da47eae35a2f41d274a99a95760;hp=9e18752a38b49b71030b93142e703d4e9ac7e170;hpb=6eb1e416743c597f8ecd3b595ddb00d3aa42c1f4;p=oweals%2Fbusybox.git diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 9e18752a3..5dcda859a 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c @@ -1,264 +1,211 @@ +/* vi: set sw=4 ts=4: */ /* - * ipcrm.c -- utility to allow removal of IPC objects and data structures. + * ipcrm.c - utility to allow removal of IPC objects and data structures. * * 01 Sept 2004 - Rodney Radford * Adapted for busybox from util-linux-2.12a. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * --- Pre-busybox history from util-linux-2.12a ------------------------ - * - * 1999-04-02 frank zago - * - can now remove several id's in the same call - * - * 1999-02-22 Arkadiusz Miÿkiewicz - * - added Native Language Support - * - * Original author - krishna balasubramanian 1993 + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ -#include -#include -#include -#include +#include "libbb.h" -#include +/* X/OPEN tells us to use for semctl() */ +/* X/OPEN tells us to use for msgctl() */ #include #include #include #include -/* X/OPEN tells us to use for semctl() */ -/* X/OPEN tells us to use for msgctl() */ -/* for getopt */ -#include - -/* for tolower and isupper */ -#include - -#include "busybox.h" - -#if defined (__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) +#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) /* union semun is defined by including */ #else /* according to X/OPEN we have to define it ourselves */ union semun { int val; struct semid_ds *buf; - unsigned short int *array; + unsigned short *array; struct seminfo *__buf; }; #endif +#define IPCRM_LEGACY 1 + + +#if IPCRM_LEGACY + typedef enum type_id { SHM, SEM, MSG } type_id; -static int -remove_ids(type_id type, int argc, char **argv) { - int id; - int ret = 0; /* for gcc */ - char *end; +static int remove_ids(type_id type, int argc, char **argv) +{ + unsigned long id; + int ret = 0; /* silence gcc */ int nb_errors = 0; union semun arg; arg.val = 0; - while(argc) { - - id = strtoul(argv[0], &end, 10); - - if (*end != 0) { - bb_printf ("invalid id: %s\n", argv[0]); - nb_errors ++; + while (argc) { + id = bb_strtoul(argv[0], NULL, 10); + if (errno || id > INT_MAX) { + bb_error_msg("invalid id: %s", argv[0]); + nb_errors++; } else { - switch(type) { - case SEM: - ret = semctl (id, 0, IPC_RMID, arg); - break; - - case MSG: - ret = msgctl (id, IPC_RMID, NULL); - break; - - case SHM: - ret = shmctl (id, IPC_RMID, NULL); - break; - } + if (type == SEM) + ret = semctl(id, 0, IPC_RMID, arg); + else if (type == MSG) + ret = msgctl(id, IPC_RMID, NULL); + else if (type == SHM) + ret = shmctl(id, IPC_RMID, NULL); if (ret) { - bb_printf ("cannot remove id %s (%s)\n", - argv[0], strerror(errno)); - nb_errors ++; + bb_perror_msg("cannot remove id %s", argv[0]); + nb_errors++; } } argc--; argv++; } - - return(nb_errors); -} - -static int deprecated_main(int argc, char **argv) -{ - if (argc < 3) { - bb_show_usage(); - bb_fflush_stdout_and_exit(1); - } - - if (!strcmp(argv[1], "shm")) { - if (remove_ids(SHM, argc-2, &argv[2])) - bb_fflush_stdout_and_exit(1); - } - else if (!strcmp(argv[1], "msg")) { - if (remove_ids(MSG, argc-2, &argv[2])) - bb_fflush_stdout_and_exit(1); - } - else if (!strcmp(argv[1], "sem")) { - if (remove_ids(SEM, argc-2, &argv[2])) - bb_fflush_stdout_and_exit(1); - } - else { - bb_printf ("unknown resource type: %s\n", argv[1]); - bb_show_usage(); - bb_fflush_stdout_and_exit(1); - } - bb_printf ("resource(s) deleted\n"); - return 0; + return nb_errors; } +#endif /* IPCRM_LEGACY */ +int ipcrm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int ipcrm_main(int argc, char **argv) { - int c; - int error = 0; - char *prog = argv[0]; + int c; + int error = 0; /* if the command is executed without parameters, do nothing */ if (argc == 1) return 0; - +#if IPCRM_LEGACY /* 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); + then run the old code. Valid commands are msg, shm, sem. */ + { + type_id what = 0; /* silence gcc */ + char w; + + w=argv[1][0]; + if ( ((w == 'm' && argv[1][1] == 's' && argv[1][2] == 'g') + || (argv[1][0] == 's' + && ((w=argv[1][1]) == 'h' || w == 'e') + && argv[1][2] == 'm') + ) && argv[1][3] == '\0' + ) { + + if (argc < 3) + bb_show_usage(); + + if (w == 'h') + what = SHM; + else if (w == 'm') + what = MSG; + else if (w == 'e') + what = SEM; + + if (remove_ids(what, argc-2, &argv[2])) + fflush_stdout_and_exit(EXIT_FAILURE); + printf("resource(s) deleted\n"); + return 0; + } + } +#endif /* IPCRM_LEGACY */ /* process new syntax to conform with SYSV ipcrm */ while ((c = getopt(argc, argv, "q:m:s:Q:M:S:h?")) != -1) { int result; int id = 0; - int iskey = isupper(c); + int iskey = (isupper)(c); /* needed to delete semaphores */ union semun arg; + arg.val = 0; - if ((c == '?') || (c == 'h')) - { + if ((c == '?') || (c == 'h')) { bb_show_usage(); - return 0; } /* we don't need case information any more */ c = tolower(c); - /* make sure the option is in range */ + /* make sure the option is in range: allowed are q, m, s */ if (c != 'q' && c != 'm' && c != 's') { bb_show_usage(); - error++; - return error; } if (iskey) { /* keys are in hex or decimal */ - key_t key = strtoul(optarg, NULL, 0); + key_t key = xstrtoul(optarg, 0); + if (key == IPC_PRIVATE) { error++; - bb_fprintf(stderr, "%s: illegal key (%s)\n", - prog, optarg); + bb_error_msg("illegal key (%s)", optarg); continue; } /* convert key to id */ id = ((c == 'q') ? msgget(key, 0) : - (c == 'm') ? shmget(key, 0, 0) : - semget(key, 0, 0)); + (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); if (id < 0) { - char *errmsg; + const char *errmsg; + error++; - switch(errno) { + switch (errno) { case EACCES: - errmsg = "permission denied for key"; + errmsg = "permission denied for"; break; case EIDRM: - errmsg = "already removed key"; + errmsg = "already removed"; break; case ENOENT: - errmsg = "invalid key"; + errmsg = "invalid"; break; default: - errmsg = "unknown error in key"; + errmsg = "unknown error in"; break; } - bb_fprintf(stderr, "%s: %s (%s)\n", - prog, errmsg, optarg); + bb_error_msg("%s %s (%s)", errmsg, "key", optarg); continue; } } else { /* ids are in decimal */ - id = strtoul(optarg, NULL, 10); + id = xatoul(optarg); } result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : - (c == 'm') ? shmctl(id, IPC_RMID, NULL) : - semctl(id, 0, IPC_RMID, arg)); + (c == 'm') ? shmctl(id, IPC_RMID, NULL) : + semctl(id, 0, IPC_RMID, arg)); + + if (result) { + const char *errmsg; + const char *const what = iskey ? "key" : "id"; - if (result < 0) { - char *errmsg; error++; - switch(errno) { + switch (errno) { case EACCES: case EPERM: - errmsg = iskey - ? "permission denied for key" - : "permission denied for id"; + errmsg = "permission denied for"; break; case EINVAL: - errmsg = iskey - ? "invalid key" - : "invalid id"; + errmsg = "invalid"; break; case EIDRM: - errmsg = iskey - ? "already removed key" - : "already removed id"; + errmsg = "already removed"; break; default: - errmsg = iskey - ? "unknown error in key" - : "unknown error in id"; + errmsg = "unknown error in"; break; } - bb_fprintf(stderr, "%s: %s (%s)\n", - prog, errmsg, optarg); + bb_error_msg("%s %s (%s)", errmsg, what, optarg); continue; } }