Esempio n. 1
0
int main()
{
    struct Process *child;
    
    struct TagItem tags[] =
    {
	{ NP_Entry,         (IPTR) entry              },
    	{ NP_Cli,           (IPTR) TRUE               },
        { NP_Name,          (IPTR) "test"             },
        { NP_NotifyOnDeath, (IPTR) TRUE               },
        { TAG_DONE,         0                         }
    };
    
    child = CreateNewProc(tags);
    
    if(child)
    {
	ULONG childstatus;
	ULONG childid = GetETask((struct Task*) child)->et_UniqueID;
	Printf("Checking status value for non-existing child id\n");
	childstatus = ChildStatus(-1);
	assert(childstatus == CHILD_NOTFOUND);
	Printf("Result: CHILD_NOTFOUND\n");
	Printf("Checking status value for running child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_ACTIVE);
	Printf("Result: CHILD_ACTIVE\n");
	ChildWait(childid);
	Printf("Checking status value for died child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_EXITED);
	Printf("Result: CHILD_EXITED\n");
	ChildFree(childid);
	Printf("Checking status value for freed child id\n");
	childstatus = ChildStatus(childid);
	assert(childstatus == CHILD_NOTFOUND);
	Printf("Result: CHILD_NOTFOUND\n");
    }
    else
	PrintFault(IoErr(), "Couldn't create child process");
    return 0;
}
Esempio n. 2
0
        pid_t waitpid(

/*  SYNOPSIS */
        pid_t pid,
        int *status,
        int options)

/*  FUNCTION
        Waits for child process with given process id to change state. State
        change is one of the following events: child has exited, child was
        terminated by a signal, child was stopped by a signal, child was
        resumed by a signal.
        
        The function stores status of the process that changed state in the
        pointer given as status argument.

        The following macros can be used to extract information from the
        status value:

        WIFEXITED(status)    - true if the process has exited
        WEXITSTATUS(status)  - exit status of the exited process
        WIFSIGNALED(status)  - true if the child process was terminated by a
                               signal
        WTERMSIG(status)     - number of the signal that caused process
                               termination
        WIFSTOPPED(status)   - true if the child process was stopped by a
                               signal
        WSTOPSIG(status)     - number of the signal that caused child process
                               stop
        WIFCONTINUED(status) - true if the child process was resumed by the
                               SIGCONT signal.

        Unless WNOHANG option is set, parent process will be suspended until a
        child changes state. If a child process has already changed state,
        function returns immediately.

    INPUTS
        pid - Process id of the process you want to wait for or -1 to wait for
                any child process
        status - Pointer to int where child status will be stored or NULL if
                you don't want to store status.
        options - ORed zero or more of the following constants:
        
            WNOHANG - return immediately if no child process changed state

    RESULT
        Process id of the child process on success or -1 on error. If an error
        occurred, the global variable errno is set.

    NOTES
        This function will work only for child processeses notifying parent
        process of their death, for example processes created by vfork() call.
        If you want to use it for other processes, remember to set the
        NP_NotifyOnDeath tag value to TRUE during child process creation.

    EXAMPLE

    BUGS

    SEE ALSO
        wait()

    INTERNALS
        Since POSIX signals are not yet implemented, WIFSIGNALED, WIFSTOPPED
        and WIFCONTINUED macros always return 0. WIFEXITED always returns 1.

        The et_UniqueID field of the ETask structure is used as process id.

******************************************************************************/
{
    struct ETask *et;
    ULONG tid = pid;
    pid_t ret = -1;
    int exchildno;

    D(bug("waitpid(%d, %p, %d)\n", pid, status, options));

    et = GetETask(FindTask(NULL));
    if(!et)
    {
        /* only ETasks are fertile */
        errno = ECHILD;
        return -1;
    }
    
    if (pid < -1 || pid == 0)
    {
        /* process groups not yet supported */
        errno = EINVAL;
        return -1;
    }

    if (pid == -1)
        tid = 0;

    if(tid != 0 && ChildStatus(tid) == CHILD_NOTFOUND)
    {
        /* error if there's no such child */
        errno = ECHILD;
        return -1;
    }

    if (options & ~WNOHANG)
    {
        /* option not yet supported */
        errno = EINVAL;
        return -1;
    }
    
    /* not very pretty, perhaps we need a function for counting dead 
       children? */
    ListLength(&et->et_TaskMsgPort.mp_MsgList, exchildno);
    if ((options & WNOHANG) && (
        (tid != 0 && ChildStatus(tid) != CHILD_EXITED) ||
        (tid == 0 && exchildno == 0)
    ))
    {
        D(bug("waitpid: no dead children\n"));
        /* no dead children atm */
        return 0;
    }

    D(bug("waitpid: wait for %d to die\n", tid));
    et = (struct ETask *)ChildWait(tid);
    if (et != (struct ETask *)CHILD_NOTNEW)
    {
        if(status)
        {
            *status = et->et_Result1;
        }
        ret = et->et_UniqueID;
        ChildFree(et->et_UniqueID);
    }
    else
        errno = ECHILD;
    
    D(bug("waitpid: leaving (%d)\n", ret));

    return ret;
}