diff options
author | Davidlohr Bueso | 2011-09-14 19:02:15 +0200 |
---|---|---|
committer | Sami Kerola | 2011-09-17 15:07:52 +0200 |
commit | 7678c735b200d80b888810f4a72a31a51425b8eb (patch) | |
tree | 9e349f6c10e983e963b1a089fe0327c6641725a6 | |
parent | ipcrm: add --verbose option (diff) | |
download | kernel-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>
-rw-r--r-- | sys-utils/ipcrm.c | 46 |
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) |