diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-11 22:54:54 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 22:54:54 -0700 |
| commit | f3ca8d5dd5c23594bda07893ae374bed7981d473 (patch) | |
| tree | 29d8c6c061b4f5cb96f4de0221c919c6881a2431 /ipc/mqueue.c | |
| parent | b95db64258b96d862b2d24ba825b98ac05f9c2fd (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.c | 6 |
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; |
