/****** rsbx.lib/WaitChild() *************************************************
*
*   NAME
*	WaitChild -- Wait for child process to terminate.
*
*   SYNOPSIS
*	term = WaitChild(child, status)
*
*	struct ChildNode *WaitChild(struct ChildNode *, long * );
*
*   FUNCTION
*	This function waits for a child process to terminate, and places the
*	    child's return val in the long pointed to by status. If the child
*	    identifier provided doen't belong to a child of this process, then
*	    0 is returned. If the child identifier is zero, returns the child
*	    identifier of a child that has terminated and sets the long status
*	    points to to its return val. If the child identifier is zero and
*	    no child has yet terminated, wait for any child to terminate and
*	    return its identifier and set the long status points to to its
*	    return val. If the child identifier is zero and there are no child
*	    processes of this process, return zero.
*
*   INPUTS
*	child         - Child identifier as returned by LaunchChildl() or by
*	                LaunchChildv().
*	status        - Pointer to a long to store the return val of the child
*	                in.
*
*   RESULT
*	term          - Child identifier of the child process whos return val
*	                was stored in the long pointed to by status, or zero
*	                if there was an error.
*
*   NOTES
*
*   SEE ALSO
*	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
*	LaunchChildv(), OrphanChild(), OrphanChildren().
*
*   BUGS
*	None Known.
*
******************************************************************************
*
*/

#include <proto/exec.h>
#include <rsbx/ChildTasking.h>


struct ChildNode *WaitChild(struct ChildNode *child, long *status)
	{
	struct ChildNode *node;

	while (1)
		{
		EmptyMorgue();

		if (child)
			{
			for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
				node->node.mln_Succ;
				node = (struct ChildNode *)node->node.mln_Succ)
				{
				if (node == child)
					{
					if (!child->notice.noticeptr)
						{
						*status = child->notice.ret;
						return child;
						}
					break;
					}
				}
			if (!node->node.mln_Succ)
				{
				return 0;
				}
			}
		else
			{
			for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
				node->node.mln_Succ;
				node = (struct ChildNode *)node->node.mln_Succ)
				{
				if (!node->notice.noticeptr)
					{
					*status = node->notice.ret;
					return node;
					}
				}

			}

		WaitPort(_Children->Morgue);
		}
	}
