summaryrefslogtreecommitdiff
path: root/ipc/mqueue.c
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 22:54:54 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 22:54:54 -0700
commitf3ca8d5dd5c23594bda07893ae374bed7981d473 (patch)
tree29d8c6c061b4f5cb96f4de0221c919c6881a2431 /ipc/mqueue.c
parentb95db64258b96d862b2d24ba825b98ac05f9c2fd (diff)
[PATCH] posix message queue update
From: Manfred Spraul <manfred@colorfullife.com> My discussion with Ulrich had one result: - mq_setattr can accept implementation defined flags. Right now we have none, but we might add some later (e.g. switch to CLOCK_MONOTONIC for mq_timed{send,receive} or something similar). When we add flags, we might need the fields for additional information. And they don't hurt. Therefore add four __reserved fields to mq_attr. - fail mq_setattr if we get unknown flags - otherwise glibc can't detect if it's running on a future kernel that supports new features. - use memset to initialize the mq_attr structure - theoretically we could leak kernel memory. - Only set O_NONBLOCK in mq_attr, explicitely clear O_RDWR & friends. openposix uses getattr, attr |=O_NONBLOCK, setattr - a sane approach. Without clearing O_RDWR, this fails. I've retested all openposix conformance tests with the new patch - the two new FAILED tests check undefined behavior. Note that I won't have net access until Sunday - if the message queue patch breaks something important either ask Krzysztof or drop it. Ulrich had another good idea for SIGEV_THREAD, but I must think about it. It would mean less complexitiy in glibc, but more code in the kernel. I'm not yet convinced that it's overall better.
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r--ipc/mqueue.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index c9a3e652a026..b5f731781f56 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -121,7 +121,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode)
INIT_LIST_HEAD(&info->e_wait_q[1].list);
info->notify_owner = 0;
info->qsize = 0;
- info->attr.mq_curmsgs = 0;
+ memset(&info->attr, 0, sizeof(info->attr));
info->attr.mq_maxmsg = DFLT_MSGMAX;
info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
info->messages = kmalloc(DFLT_MSGMAX * sizeof(struct msg_msg *), GFP_KERNEL);
@@ -1082,6 +1082,8 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
if (u_mqstat != NULL) {
if (copy_from_user(&mqstat, u_mqstat, sizeof(struct mq_attr)))
return -EFAULT;
+ if (mqstat.mq_flags & (~O_NONBLOCK))
+ return -EINVAL;
}
ret = -EBADF;
@@ -1097,7 +1099,7 @@ asmlinkage long sys_mq_getsetattr(mqd_t mqdes,
spin_lock(&info->lock);
omqstat = info->attr;
- omqstat.mq_flags = filp->f_flags;
+ omqstat.mq_flags = filp->f_flags & O_NONBLOCK;
if (u_mqstat) {
if (mqstat.mq_flags & O_NONBLOCK)
filp->f_flags |= O_NONBLOCK;