summaryrefslogtreecommitdiffstats
path: root/sys-utils/ipcutils.c
diff options
context:
space:
mode:
authorRuediger Meier2014-03-12 14:53:20 +0100
committerRuediger Meier2014-03-13 23:23:25 +0100
commit08e7d10bd8a7894a6f83396bad337396b7191de7 (patch)
tree81a4d1f9c6958d94cc2ab5bea38ce6b94b9c585c /sys-utils/ipcutils.c
parenttests: add basic test case for ipcs -m -i n (diff)
downloadkernel-qcow2-util-linux-08e7d10bd8a7894a6f83396bad337396b7191de7.tar.gz
kernel-qcow2-util-linux-08e7d10bd8a7894a6f83396bad337396b7191de7.tar.xz
kernel-qcow2-util-linux-08e7d10bd8a7894a6f83396bad337396b7191de7.zip
ipcs: fix ipc_msg_get_info fallback case
"ipcs -q" (case id < 0) was broken since v2.22-256-g35118df if /sys is not usable. The main issue was that the use of msqid argument did not cleanly distinguished between "queue identifier" and "index of kernel's internal array". Also now the fallback case and the regular case behave more equally regarding it's return value (introducing another counter j). Note that the case id >= 0 now performs a slower lookup. This could be avoided but then we would better handle both case differently like it was before the above mentioned cleanup commit. Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
Diffstat (limited to 'sys-utils/ipcutils.c')
-rw-r--r--sys-utils/ipcutils.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/sys-utils/ipcutils.c b/sys-utils/ipcutils.c
index c98c5d8b5..2491f7c91 100644
--- a/sys-utils/ipcutils.c
+++ b/sys-utils/ipcutils.c
@@ -423,26 +423,20 @@ int ipc_msg_get_info(int id, struct msg_data **msgds)
/* Fallback; /proc or /sys file(s) missing. */
msg_fallback:
- i = id < 0 ? 0 : id;
-
- maxid = msgctl(id, MSG_STAT, &dummy);
+ maxid = msgctl(0, MSG_INFO, &dummy);
if (maxid < 0)
return 0;
- while (i <= maxid) {
+ for (int j = 0; j <= maxid; j++) {
int msgid;
struct ipc_perm *ipcp = &msgseg.msg_perm;
- msgid = msgctl(i, MSG_STAT, &msgseg);
- if (msgid < 0) {
- if (-1 < id) {
- free(*msgds);
- return 0;
- }
- i++;
+ msgid = msgctl(j, MSG_STAT, &msgseg);
+ if (msgid < 0 || (id > -1 && msgid != id)) {
continue;
}
+ i++;
p->msg_perm.key = ipcp->KEY;
p->msg_perm.id = msgid;
p->msg_perm.mode = ipcp->mode;
@@ -463,11 +457,12 @@ msg_fallback:
p->next = xcalloc(1, sizeof(struct msg_data));
p = p->next;
p->next = NULL;
- i++;
} else
- return 1;
+ break;
}
+ if (i == 0)
+ free(*msgds);
return i;
}