kernel: Implement WEXITED for waitid.

Previously dead teams were always returned (as needed for wait/waitpid).
Using waitid it should however be possible to omit the WEXITED flag to
only get stopped (WUNTRACED | WSTOPPED) or continued (WCONTINUED) teams.

Adjust the other caller of the _kern_wait_for_child syscall, used by the
various less specific wait* functions, to always include WEXITED. This
avoids having to special case waitid in the syscall interface or with an
extra flag.

Add a check to ensure that any of these flags is set to avoid the now
possible case of nothing being specified. This fails with B_BAD_VALUE
(EINVAL) as on other systems.
This commit is contained in:
Michael Lotz 2018-01-03 01:34:30 +01:00
parent 63e2d20137
commit 36ef138ce5
2 changed files with 15 additions and 5 deletions

View File

@ -2321,15 +2321,19 @@ get_job_control_entry(team_job_control_children& children, pid_t id)
checked.
\param id The match criterion.
\param flags Specifies which children shall be considered. Dead children
always are. Stopped children are considered when \a flags is ORed
bitwise with \c WUNTRACED or \c WSTOPPED, continued children when
\a flags is ORed bitwise with \c WCONTINUED.
are considered when \a flags is ORed bitwise with \c WEXITED, stopped
children are considered when \a flags is ORed bitwise with \c WUNTRACED
or \c WSTOPPED, continued children when \a flags is ORed bitwise with
\c WCONTINUED.
\return The first matching entry or \c NULL, if none matches.
*/
static job_control_entry*
get_job_control_entry(Team* team, pid_t id, uint32 flags)
{
job_control_entry* entry = get_job_control_entry(team->dead_children, id);
job_control_entry* entry = NULL;
if ((flags & WEXITED) != 0)
entry = get_job_control_entry(team->dead_children, id);
if (entry == NULL && (flags & WCONTINUED) != 0)
entry = get_job_control_entry(team->continued_children, id);
@ -2433,6 +2437,11 @@ wait_for_child(pid_t child, uint32 flags, siginfo_t& _info,
T(WaitForChild(child, flags));
if ((flags & (WEXITED | WUNTRACED | WSTOPPED | WCONTINUED)) == 0) {
T(WaitForChildDone(B_BAD_VALUE));
return B_BAD_VALUE;
}
pid_t originalChild = child;
bool ignoreFoundEntries = false;

View File

@ -28,7 +28,8 @@ _waitpid(pid_t pid, int* _status, int options, team_usage_info *usage_info)
{
// wait
siginfo_t info;
pid_t child = _kern_wait_for_child(pid, options, &info, usage_info);
pid_t child = _kern_wait_for_child(pid, options | WEXITED, &info,
usage_info);
pthread_testcancel();