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; }
