]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ipcrm: check IPC syscalls
authorDavidlohr Bueso <dave@gnu.org>
Wed, 14 Sep 2011 17:02:15 +0000 (14:02 -0300)
committerSami Kerola <kerolasa@iki.fi>
Sat, 17 Sep 2011 13:07:52 +0000 (15:07 +0200)
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>
sys-utils/ipcrm.c

index aab2c10260260e9ef84f0c094a9dbf5c52c7bb9a..ab06cd3cd6141ddad85cb6d839540a2e29b3e25f 100644 (file)
@@ -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)