This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c49197b0df720ab4b549aafab8812c294c18fdc1 Author: Marco Casaroli <[email protected]> AuthorDate: Tue Nov 3 14:25:21 2026 +0100 sched/mqueue: Keep the key of a System V message queue. msgget() did not keep the key. The queue identifier was the index in the queue table plus one, and msgget() used the key as an identifier. So msgget(key, 0) after msgget(key, IPC_CREAT) gave ENOENT, IPC_CREAT | IPC_EXCL never gave EEXIST, and msgget(1, 0) found any queue with the identifier 1. Keep the key in the queue, separate from the identifier, and find the queue of a key by its key. IPC_PRIVATE always makes a new queue. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- sched/mqueue/msg.h | 17 ++++++++++++++--- sched/mqueue/msgget.c | 19 ++++++++++++++----- sched/mqueue/msginternal.c | 33 ++++++++++++++++++++++++++------- sched/mqueue/msgrcv.c | 4 ++-- sched/mqueue/msgsnd.c | 4 ++-- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/sched/mqueue/msg.h b/sched/mqueue/msg.h index 68e66c83ae4..5a03116b2e0 100644 --- a/sched/mqueue/msg.h +++ b/sched/mqueue/msg.h @@ -53,7 +53,8 @@ struct msgq_s { struct mqueue_cmn_s cmn; struct list_node msglist; /* Prioritized message list */ - key_t key; + key_t key; /* The msgget() key, or IPC_PRIVATE */ + int16_t id; /* The message queue identifier */ int16_t maxmsgs; /* Maximum number of messages in the queue */ int16_t nmsgs; /* Number of message in the queue */ uint16_t maxmsgsize; /* Max size of message in message queue */ @@ -106,11 +107,21 @@ void nxmsg_free(FAR struct msgq_s *msgq); * Name: nxmsg_lookup * * Description: - * Find the message queue in look-up table + * Find the message queue with the identifier msqid * ****************************************************************************/ -FAR struct msgq_s *nxmsg_lookup(key_t key); +FAR struct msgq_s *nxmsg_lookup(int msqid); + +/**************************************************************************** + * Name: nxmsg_findkey + * + * Description: + * Find the message queue of a key (not IPC_PRIVATE) + * + ****************************************************************************/ + +FAR struct msgq_s *nxmsg_findkey(key_t key); #ifdef __cplusplus } diff --git a/sched/mqueue/msgget.c b/sched/mqueue/msgget.c index 79bf841524f..42aa48a2c1c 100644 --- a/sched/mqueue/msgget.c +++ b/sched/mqueue/msgget.c @@ -60,18 +60,27 @@ int msgget(key_t key, int msgflg) flags = enter_critical_section(); - msgq = nxmsg_lookup(key); - if (msgq) + /* IPC_PRIVATE always makes a new queue */ + + msgq = key != IPC_PRIVATE ? nxmsg_findkey(key) : NULL; + if (msgq != NULL) { if ((msgflg & IPC_CREAT) && (msgflg & IPC_EXCL)) { ret = -EEXIST; } } + else if (key != IPC_PRIVATE && (msgflg & IPC_CREAT) == 0) + { + ret = -ENOENT; + } else { - ret = (key != IPC_PRIVATE && !(msgflg & IPC_CREAT)) ? - -ENOENT : nxmsg_alloc(&msgq); + ret = nxmsg_alloc(&msgq); + if (ret >= 0) + { + msgq->key = key; + } } leave_critical_section(flags); @@ -82,5 +91,5 @@ int msgget(key_t key, int msgflg) return ERROR; } - return msgq->key; + return msgq->id; } diff --git a/sched/mqueue/msginternal.c b/sched/mqueue/msginternal.c index 7034072614e..8d4f72c9f40 100644 --- a/sched/mqueue/msginternal.c +++ b/sched/mqueue/msginternal.c @@ -72,7 +72,7 @@ static FAR struct msgq_s *nxmsg_alloc_internal(void) if (g_msgqs[i] == NULL) { g_msgqs[i] = msgq; - msgq->key = i + 1; + msgq->id = i + 1; return msgq; } } @@ -91,7 +91,7 @@ static FAR struct msgq_s *nxmsg_alloc_internal(void) g_msgqs[g_nmsgq] = msgq; - msgq->key = g_nmsgq + 1; + msgq->id = g_nmsgq + 1; g_nmsgq += MQ_PERBLOCK; @@ -172,12 +172,12 @@ void nxmsg_free(FAR struct msgq_s *msgq) FAR struct msgbuf_s *tmp; int index; - if (msgq == NULL || msgq->key <= 0 || msgq->key > g_nmsgq) + if (msgq == NULL || msgq->id <= 0 || msgq->id > g_nmsgq) { return; } - index = msgq->key - 1; + index = msgq->id - 1; /* Remove the queue from the table first, so that no task finds it after * the wake-up or while kmm_free() waits for the heap lock. @@ -200,12 +200,31 @@ void nxmsg_free(FAR struct msgq_s *msgq) * Name: nxmsg_lookup ****************************************************************************/ -FAR struct msgq_s *nxmsg_lookup(key_t key) +FAR struct msgq_s *nxmsg_lookup(int msqid) { - if (key <= 0 || key > g_nmsgq) + if (msqid <= 0 || msqid > g_nmsgq) { return NULL; } - return g_msgqs[key - 1]; + return g_msgqs[msqid - 1]; +} + +/**************************************************************************** + * Name: nxmsg_findkey + ****************************************************************************/ + +FAR struct msgq_s *nxmsg_findkey(key_t key) +{ + int i; + + for (i = 0; i < g_nmsgq; i++) + { + if (g_msgqs[i] != NULL && g_msgqs[i]->key == key) + { + return g_msgqs[i]; + } + } + + return NULL; } diff --git a/sched/mqueue/msgrcv.c b/sched/mqueue/msgrcv.c index 2402991e301..7860e6f79a3 100644 --- a/sched/mqueue/msgrcv.c +++ b/sched/mqueue/msgrcv.c @@ -45,7 +45,7 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct msgbuf_s **rcvmsg, FAR struct msgbuf_s *newmsg = NULL; FAR struct msgbuf_s *tmp; FAR struct tcb_s *rtcb; - key_t key = msgq->key; + int msqid = msgq->id; #ifdef CONFIG_CANCELLATION_POINTS /* msgrcv_wait() is not a cancellation point, but it may be called @@ -164,7 +164,7 @@ static int msgrcv_wait(FAR struct msgq_s *msgq, FAR struct msgbuf_s **rcvmsg, /* msgctl(IPC_RMID) may have freed the queue before this task ran */ - if (nxmsg_lookup(key) != msgq) + if (nxmsg_lookup(msqid) != msgq) { return -EIDRM; } diff --git a/sched/mqueue/msgsnd.c b/sched/mqueue/msgsnd.c index b4f5ad911e1..14677970480 100644 --- a/sched/mqueue/msgsnd.c +++ b/sched/mqueue/msgsnd.c @@ -42,7 +42,7 @@ static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg) { FAR struct tcb_s *rtcb; - key_t key = msgq->key; + int msqid = msgq->id; #ifdef CONFIG_CANCELLATION_POINTS /* msgsnd_wait() is not a cancellation point, but may be called via @@ -121,7 +121,7 @@ static int msgsnd_wait(FAR struct msgq_s *msgq, int msgflg) /* msgctl(IPC_RMID) may have freed the queue before this task ran */ - if (nxmsg_lookup(key) != msgq) + if (nxmsg_lookup(msqid) != msgq) { return -EIDRM; }
