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 23a724dc0f8aea1531bfeb7a900b7019443a21d6
Author: yushuailong <[email protected]>
AuthorDate: Thu Sep 10 17:03:23 2026 +0800

    sched/waitid: honor WNOWAIT instead of discarding child status
    
    waitid() documents WNOWAIT support but exited_child() unconditionally
    removed and freed the child status entry, so a second wait on the same
    child failed with ECHILD. Debug builds were also inconsistent: the
    options mask rejected WNOWAIT entirely with ENOSYS.
    
    Pass options down to exited_child() and skip the discard when WNOWAIT
    is set, matching waitpid(), and add WNOWAIT to the debug options mask.
    
    Assisted-by: OpenAI Codex
    Signed-off-by: yushuailong <[email protected]>
---
 sched/sched/sched_waitid.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/sched/sched/sched_waitid.c b/sched/sched/sched_waitid.c
index 330f26afec6..ca7525cd778 100644
--- a/sched/sched/sched_waitid.c
+++ b/sched/sched/sched_waitid.c
@@ -56,7 +56,7 @@
 #ifdef CONFIG_SCHED_CHILD_STATUS
 static void exited_child(FAR struct tcb_s *rtcb,
                          FAR struct child_status_s *child,
-                         FAR siginfo_t *info)
+                         FAR siginfo_t *info, int options)
 {
   /* The child has exited. Return the saved exit status (and some fudged
    * information).
@@ -72,10 +72,15 @@ static void exited_child(FAR struct tcb_s *rtcb,
       info->si_status          = child->ch_status;
     }
 
-  /* Discard the child entry */
+  /* Discard the child entry unless WNOWAIT is set (the caller wants the
+   * child to remain in a waitable state).
+   */
 
-  group_remove_child(rtcb->group, child->ch_pid);
-  group_free_child(child);
+  if ((options & WNOWAIT) == 0)
+    {
+      group_remove_child(rtcb->group, child->ch_pid);
+      group_free_child(child);
+    }
 }
 #endif
 
@@ -117,7 +122,7 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
                * Return the exit status and break out of the loop.
                */
 
-              exited_child(rtcb, child, info);
+              exited_child(rtcb, child, info, options);
               break;
             }
         }
@@ -141,7 +146,7 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
                * of the loop.
                */
 
-              exited_child(rtcb, child, info);
+              exited_child(rtcb, child, info, options);
               break;
             }
         }
@@ -232,7 +237,7 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
 
                       if ((child->ch_flags & CHILD_FLAG_EXITED) != 0)
                         {
-                          exited_child(rtcb, child, NULL);
+                          exited_child(rtcb, child, NULL, options);
                         }
                     }
 #endif
@@ -255,7 +260,7 @@ int waittcb(FAR struct tcb_s *rtcb, idtype_t idtype, int 
options,
                   if (child &&
                       (child->ch_flags & CHILD_FLAG_EXITED) != 0)
                     {
-                      exited_child(rtcb, child, NULL);
+                      exited_child(rtcb, child, NULL, options);
                     }
                 }
 #endif
@@ -369,7 +374,7 @@ int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, 
int options)
 
   if ((idtype == P_PID || idtype == P_ALL) &&
       (options & WEXITED) != 0 &&
-      (options & ~(WEXITED | WNOHANG)) == 0)
+      (options & ~(WEXITED | WNOHANG | WNOWAIT)) == 0)
 #endif
     {
       errcode = OK;

Reply via email to