From: Jakub Jelinek POSIX requires EINVAL to be set if: "The process or thread would have blocked, and the abs_timeout parameter specified a nanoseconds field value less than zero or greater than or equal to 1000 million." but 2.6.5-mm3 returns -EINVAL even if the process or thread would not block (if the queue is not empty for timedreceive or not full for timedsend). --- 25-akpm/ipc/mqueue.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) diff -puN ipc/mqueue.c~mq-timespec-checking-fix ipc/mqueue.c --- 25/ipc/mqueue.c~mq-timespec-checking-fix Fri Apr 9 16:30:36 2004 +++ 25-akpm/ipc/mqueue.c Fri Apr 9 16:30:36 2004 @@ -765,8 +765,7 @@ asmlinkage long sys_mq_timedsend(mqd_t m if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX)) return -EINVAL; - if (unlikely((timeout = prepare_timeout(u_abs_timeout)) < 0)) - return timeout; + timeout = prepare_timeout(u_abs_timeout); ret = -EBADF; filp = fget(mqdes); @@ -802,6 +801,9 @@ asmlinkage long sys_mq_timedsend(mqd_t m if (filp->f_flags & O_NONBLOCK) { spin_unlock(&info->lock); ret = -EAGAIN; + } else if (unlikely(timeout < 0)) { + spin_unlock(&info->lock); + ret = timeout; } else { wait.task = current; wait.msg = (void *) msg_ptr; @@ -842,9 +844,7 @@ asmlinkage ssize_t sys_mq_timedreceive(m struct mqueue_inode_info *info; struct ext_wait_queue wait; - - if (unlikely((timeout = prepare_timeout(u_abs_timeout)) < 0)) - return timeout; + timeout = prepare_timeout(u_abs_timeout); ret = -EBADF; filp = fget(mqdes); @@ -871,6 +871,10 @@ asmlinkage ssize_t sys_mq_timedreceive(m spin_unlock(&info->lock); ret = -EAGAIN; msg_ptr = NULL; + } else if (unlikely(timeout < 0)) { + spin_unlock(&info->lock); + ret = timeout; + msg_ptr = NULL; } else { wait.task = current; wait.state = STATE_NONE; _