From 50428979d0d1bb4c24c89bcc36a914158c56b373 Mon Sep 17 00:00:00 2001 From: yangyalei Date: Tue, 7 Mar 2023 21:36:22 +0800 Subject: [PATCH] fix wait after vfork return error Signed-off-by: yangyalei --- include/nuttx/sched.h | 4 +++- libs/libc/unistd/lib_vfork.c | 6 ++++-- sched/sched/sched_waitpid.c | 16 ++++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 47f2549ea2..aaaecc4a01 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -1457,6 +1457,7 @@ void nxsched_get_stateinfo(FAR struct tcb_s *tcb, FAR char *state, * pid - The task ID of the thread to waid for * stat_loc - The location to return the exit status * options - ignored + * release - Wheather release exited child process infomation * * Returned Value: * If nxsched_waitpid() returns because the status of a child process is @@ -1485,7 +1486,8 @@ void nxsched_get_stateinfo(FAR struct tcb_s *tcb, FAR char *state, ****************************************************************************/ #ifdef CONFIG_SCHED_WAITPID -pid_t nxsched_waitpid(pid_t pid, FAR int *stat_loc, int options); +pid_t nxsched_waitpid(pid_t pid, FAR int *stat_loc, int options, + bool release); #endif /**************************************************************************** diff --git a/libs/libc/unistd/lib_vfork.c b/libs/libc/unistd/lib_vfork.c index e23014d26c..15c21fdd8c 100644 --- a/libs/libc/unistd/lib_vfork.c +++ b/libs/libc/unistd/lib_vfork.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include +#include #include #include @@ -63,10 +64,11 @@ pid_t vfork(void) * until running finished or performing exec */ - ret = waitpid(pid, &status, 0); + ret = nxsched_waitpid(pid, &status, 0, false); if (ret < 0) { - serr("ERROR: waitpid failed: %d\n", get_errno()); + set_errno(-ret); + serr("ERROR: waitpid failed: %d\n", -ret); } } diff --git a/sched/sched/sched_waitpid.c b/sched/sched/sched_waitpid.c index ef535a62a8..069808f4e1 100644 --- a/sched/sched/sched_waitpid.c +++ b/sched/sched/sched_waitpid.c @@ -62,6 +62,7 @@ * pid - The task ID of the thread to waid for * stat_loc - The location to return the exit status * options - ignored + * release - Wheather release exited child process infomation * * Returned Value: * If nxsched_waitpid() returns because the status of a child process is @@ -90,7 +91,7 @@ ****************************************************************************/ #ifndef CONFIG_SCHED_HAVE_PARENT -pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options) +pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options, bool release) { FAR struct tcb_s *ctcb; FAR struct task_group_s *group; @@ -221,7 +222,7 @@ errout: ****************************************************************************/ #else -pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options) +pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options, bool release) { FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *ctcb; @@ -388,8 +389,11 @@ pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options) /* Discard the child entry and break out of the loop */ - group_remove_child(rtcb->group, pid); - group_free_child(child); + if (release) + { + group_remove_child(rtcb->group, pid); + group_free_child(child); + } break; } } @@ -475,7 +479,7 @@ pid_t nxsched_waitpid(pid_t pid, int *stat_loc, int options) /* Discard the child entry, if we have one */ - if (child != NULL) + if (child != NULL && release) { group_remove_child(rtcb->group, child->ch_pid); group_free_child(child); @@ -636,7 +640,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options) /* Let nxsched_waitpid() do the work. */ - ret = nxsched_waitpid(pid, stat_loc, options); + ret = nxsched_waitpid(pid, stat_loc, options, true); if (ret < 0) { set_errno(-ret);