This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 59c8eef88d771ae546cfdaff875a5985e9584272
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Oct 30 08:43:04 2026 +0100

    sched/mqueue: Return the POSIX error numbers from msgrcv() and msgsnd().
    
    msgrcv() with IPC_NOWAIT failed with EAGAIN when the queue had no
    message of the requested type.  POSIX requires ENOMSG.
    
    msgrcv() failed with EMSGSIZE when msgsz was less than
    CONFIG_MQ_MAXMSGSIZE and MSG_NOERROR was not set, also when the message
    fits in msgsz.  POSIX requires E2BIG only when the message is longer
    than msgsz.  Now msgrcv() compares msgsz with the length of the
    selected message: a longer message stays in the queue and msgrcv()
    fails with E2BIG; with MSG_NOERROR the message is truncated, as before.
    
    msgsnd() failed with EMSGSIZE when msgsz was greater than the maximum
    message size, and accepted a message type less than 1.  POSIX requires
    EINVAL for both.
    
    Update the errno lists in the function comments.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 include/sys/msg.h     | 23 ++++++++++++++---------
 sched/mqueue/msgrcv.c | 33 +++++++++++++++++++++------------
 sched/mqueue/msgsnd.c | 16 +++++++---------
 3 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/include/sys/msg.h b/include/sys/msg.h
index 4832f6b9e30..ba63a9c3f93 100644
--- a/include/sys/msg.h
+++ b/include/sys/msg.h
@@ -162,15 +162,13 @@ int msgget(key_t key, int msgflg);
  *   msgflg - Operations flags
  *
  * Returned Value:
- *   On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
+ *   On success, msgsnd() returns 0 (OK); on error, -1 (ERROR)
  *   is returned, with errno set to indicate the error:
  *
- *   EAGAIN   The queue was full and the O_NONBLOCK flag was set for the
- *            message queue description referred to by mqdes.
- *   EINVAL   Either msg or mqdes is NULL or the value of prio is invalid.
- *   EPERM    Message queue opened not opened for writing.
- *   EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
- *            message queue.
+ *   EAGAIN   The queue is full and IPC_NOWAIT is set.
+ *   EINVAL   msqid is not a valid message queue identifier, mtype is
+ *            less than 1, or msgsz is greater than the maximum message
+ *            size of the queue.
  *   EINTR    The call was interrupted by a signal handler.
  *
  ****************************************************************************/
@@ -196,8 +194,15 @@ int msgsnd(int msqid, FAR const void *msgp, size_t msgsz, 
int msgflg);
  * Returned Value:
  *   On success, msgrcv() returns the number of bytes actually copied
  *   into the mtext array.
- *   On failure, both functions return -1, and set errno to indicate
- *   the error.
+ *   On failure, msgrcv() returns -1 and sets errno to indicate the
+ *   error:
+ *
+ *   E2BIG   The message is longer than msgsz and MSG_NOERROR is not set.
+ *           The message stays in the queue.
+ *   EINVAL  msqid is not a valid message queue identifier.
+ *   ENOMSG  IPC_NOWAIT is set and the queue has no message of the
+ *           requested type.
+ *   EINTR   The call was interrupted by a signal handler.
  *
  ****************************************************************************/
 
diff --git a/sched/mqueue/msgrcv.c b/sched/mqueue/msgrcv.c
index b3044c806e7..a3c58355d2e 100644
--- a/sched/mqueue/msgrcv.c
+++ b/sched/mqueue/msgrcv.c
@@ -40,7 +40,7 @@
  ****************************************************************************/
 
 static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct msgbuf_s **rcvmsg,
-                       long msgtyp, int msgflg)
+                       size_t msgsz, long msgtyp, int msgflg)
 {
   FAR struct msgbuf_s *newmsg = NULL;
   FAR struct msgbuf_s *tmp;
@@ -99,13 +99,22 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct 
msgbuf_s **rcvmsg,
 
       if (newmsg)
         {
+          /* A message longer than msgsz stays in the queue.  With
+           * MSG_NOERROR, msgrcv() truncates the message.
+           */
+
+          if (newmsg->msize > msgsz && (msgflg & MSG_NOERROR) == 0)
+            {
+              return -E2BIG;
+            }
+
           list_delete(&newmsg->node);
           goto found;
         }
 
       if ((msgflg & IPC_NOWAIT) != 0)
         {
-          return -EAGAIN;
+          return -ENOMSG;
         }
 
       /* The queue is empty!  Should we block until there the above condition
@@ -182,8 +191,15 @@ found:
  * Returned Value:
  *   On success, msgrcv() returns the number of bytes actually copied
  *   into the mtext array.
- *   On failure, both functions return -1, and set errno to indicate
- *   the error.
+ *   On failure, msgrcv() returns -1 and sets errno to indicate the
+ *   error:
+ *
+ *   E2BIG   The message is longer than msgsz and MSG_NOERROR is not set.
+ *           The message stays in the queue.
+ *   EINVAL  msqid is not a valid message queue identifier.
+ *   ENOMSG  IPC_NOWAIT is set and the queue has no message of the
+ *           requested type.
+ *   EINTR   The call was interrupted by a signal handler.
  *
  ****************************************************************************/
 
@@ -212,14 +228,7 @@ ssize_t msgrcv(int msqid, FAR void *msgp, size_t msgsz, 
long msgtyp,
       goto errout_with_critical;
     }
 
-  if (msgsz < msgq->maxmsgsize &&
-      ((msgflg & MSG_NOERROR) == 0))
-    {
-      ret = -EMSGSIZE;
-      goto errout_with_critical;
-    }
-
-  ret = msgrcv_wait(msgq, &msg, msgtyp, msgflg);
+  ret = msgrcv_wait(msgq, &msg, msgsz, msgtyp, msgflg);
   if (ret < 0)
     {
       goto errout_with_critical;
diff --git a/sched/mqueue/msgsnd.c b/sched/mqueue/msgsnd.c
index 3b769d672f4..1f0324392b4 100644
--- a/sched/mqueue/msgsnd.c
+++ b/sched/mqueue/msgsnd.c
@@ -144,15 +144,13 @@ static int msgsnd_wait(FAR struct msgq_s *msgq, int 
msgflg)
  *   msgflg - Operations flags
  *
  * Returned Value:
- *   On success, mq_send() returns 0 (OK); on error, -1 (ERROR)
+ *   On success, msgsnd() returns 0 (OK); on error, -1 (ERROR)
  *   is returned, with errno set to indicate the error:
  *
- *   EAGAIN   The queue was full and the O_NONBLOCK flag was set for the
- *            message queue description referred to by mqdes.
- *   EINVAL   Either msg or mqdes is NULL or the value of prio is invalid.
- *   EPERM    Message queue opened not opened for writing.
- *   EMSGSIZE 'msglen' was greater than the maxmsgsize attribute of the
- *            message queue.
+ *   EAGAIN   The queue is full and IPC_NOWAIT is set.
+ *   EINVAL   msqid is not a valid message queue identifier, mtype is
+ *            less than 1, or msgsz is greater than the maximum message
+ *            size of the queue.
  *   EINTR    The call was interrupted by a signal handler.
  *
  ****************************************************************************/
@@ -181,9 +179,9 @@ int msgsnd(int msqid, FAR const void *msgp, size_t msgsz, 
int msgflg)
       goto errout_with_critical;
     }
 
-  if (msgsz > msgq->maxmsgsize)
+  if (buf->mtype < 1 || msgsz > msgq->maxmsgsize)
     {
-      ret = -EMSGSIZE;
+      ret = -EINVAL;
       goto errout_with_critical;
     }
 

Reply via email to