summaryrefslogtreecommitdiffstats
path: root/sys-utils/ipcrm.c
diff options
context:
space:
mode:
authorDavidlohr Bueso2011-09-14 19:02:15 +0200
committerSami Kerola2011-09-17 15:07:52 +0200
commit7678c735b200d80b888810f4a72a31a51425b8eb (patch)
tree9e349f6c10e983e963b1a089fe0327c6641725a6 /sys-utils/ipcrm.c
parentipcrm: add --verbose option (diff)
downloadkernel-qcow2-util-linux-7678c735b200d80b888810f4a72a31a51425b8eb.tar.gz
kernel-qcow2-util-linux-7678c735b200d80b888810f4a72a31a51425b8eb.tar.xz
kernel-qcow2-util-linux-7678c735b200d80b888810f4a72a31a51425b8eb.zip
ipcrm: check IPC syscalls
It's not enough to check errno for errors as the variable is not reset, we also need to check the last syscall return value to verify a problem. This addresses bogus msgqueue errors when deleting keys. Signed-off-by: Davidlohr Bueso <dave@gnu.org> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'sys-utils/ipcrm.c')
-rw-r--r--sys-utils/ipcrm.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/sys-utils/ipcrm.c b/sys-utils/ipcrm.c
index aab2c1026..ab06cd3cd 100644
--- a/sys-utils/ipcrm.c
+++ b/sys-utils/ipcrm.c
@@ -66,6 +66,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
int remove_id(int type, int iskey, int id)
{
+ int ret;
char *errmsg;
/* needed to delete semaphores */
union semun arg;
@@ -76,43 +77,44 @@ int remove_id(int type, int iskey, int id)
case SHM:
if (verbose)
printf(_("removing shared memory segment id `%d'\n"), id);
- shmctl(id, IPC_RMID, NULL);
+ ret = shmctl(id, IPC_RMID, NULL);
break;
case MSG:
if (verbose)
printf(_("removing message queue id `%d'\n"), id);
- msgctl(id, IPC_RMID, NULL);
+ ret = msgctl(id, IPC_RMID, NULL);
break;
case SEM:
if (verbose)
printf(_("removing semaphore id `%d'\n"), id);
- semctl(id, 0, IPC_RMID, arg);
+ ret = semctl(id, 0, IPC_RMID, arg);
break;
default:
errx(EXIT_FAILURE, "impossible occurred");
}
/* how did the removal go? */
- switch (errno) {
- case 0:
- return 0;
- 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:
- if (iskey)
- err(EXIT_FAILURE, _("key failed"));
- err(EXIT_FAILURE, _("id failed"));
+ if (ret < 0) {
+ 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:
+ if (iskey)
+ err(EXIT_FAILURE, _("key failed"));
+ err(EXIT_FAILURE, _("id failed"));
+ }
+ warnx("%s (%d)", errmsg, id);
+ return 1;
}
- warnx("%s (%d)", errmsg, id);
- return 1;
+ return 0;
}
static int remove_arg_list(type_id type, int argc, char **argv)