os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/waitpid.c
Update contrib.
4 * This procedure emulates the POSIX waitpid kernel call on
5 * BSD systems that don't have waitpid but do have wait3.
6 * This code is based on a prototype version written by
7 * Mark Diekhans and Karl Lehenbauer.
9 * Copyright (c) 1993 The Regents of the University of California.
10 * Copyright (c) 1994 Sun Microsystems, Inc.
12 * See the file "license.terms" for information on usage and redistribution
13 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15 * RCS: @(#) $Id: waitpid.c,v 1.3 2000/01/11 22:08:50 hobbs Exp $
26 * A linked list of the following structures is used to keep track
27 * of processes for which we received notification from the kernel,
28 * but the application hasn't waited for them yet (this can happen
29 * because wait may not return the process we really want). We
30 * save the information here until the application finally does
31 * wait for the process.
34 typedef struct WaitInfo {
35 pid_t pid; /* Pid of process that exited. */
36 WAIT_STATUS_TYPE status; /* Status returned when child exited
38 struct WaitInfo *nextPtr; /* Next in list of exited processes. */
41 static WaitInfo *deadList = NULL; /* First in list of all dead
45 *----------------------------------------------------------------------
49 * This procedure emulates the functionality of the POSIX
50 * waitpid kernel call, using the BSD wait3 kernel call.
51 * Note: it doesn't emulate absolutely all of the waitpid
52 * functionality, in that it doesn't support pid's of 0
56 * -1 is returned if there is an error in the wait kernel call.
57 * Otherwise the pid of an exited or suspended process is
58 * returned and *statusPtr is set to the status value of the
64 *----------------------------------------------------------------------
72 waitpid(pid, statusPtr, options)
73 pid_t pid; /* The pid to wait on. Must be -1 or
74 * greater than zero. */
75 int *statusPtr; /* Where to store wait status for the
77 int options; /* OR'ed combination of WNOHANG and
80 register WaitInfo *waitPtr, *prevPtr;
82 WAIT_STATUS_TYPE status;
84 if ((pid < -1) || (pid == 0)) {
90 * See if there's a suitable process that has already stopped or
91 * exited. If so, remove it from the list of exited processes and
92 * return its information.
95 for (waitPtr = deadList, prevPtr = NULL; waitPtr != NULL;
96 prevPtr = waitPtr, waitPtr = waitPtr->nextPtr) {
97 if ((pid != waitPtr->pid) && (pid != -1)) {
100 if (!(options & WUNTRACED) && (WIFSTOPPED(waitPtr->status))) {
103 result = waitPtr->pid;
104 *statusPtr = *((int *) &waitPtr->status);
105 if (prevPtr == NULL) {
106 deadList = waitPtr->nextPtr;
108 prevPtr->nextPtr = waitPtr->nextPtr;
110 ckfree((char *) waitPtr);
115 * Wait for any process to stop or exit. If it's an acceptable one
116 * then return it to the caller; otherwise store information about it
117 * in the list of exited processes and try again. On systems that
118 * have only wait but not wait3, there are several situations we can't
119 * handle, but we do the best we can (e.g. can still handle some
120 * combinations of options by invoking wait instead of wait3).
125 if (options & WNOHANG) {
132 result = wait(&status);
134 result = wait3(&status, options, 0);
136 if ((result == -1) && (errno == EINTR)) {
143 if ((pid != result) && (pid != -1)) {
146 if (!(options & WUNTRACED) && (WIFSTOPPED(status))) {
149 *statusPtr = *((int *) &status);
153 * Can't return this info to caller. Save it in the list of
154 * stopped or exited processes. Tricky point: first check for
155 * an existing entry for the process and overwrite it if it
156 * exists (e.g. a previously stopped process might now be dead).
160 for (waitPtr = deadList; waitPtr != NULL; waitPtr = waitPtr->nextPtr) {
161 if (waitPtr->pid == result) {
162 waitPtr->status = status;
166 waitPtr = (WaitInfo *) ckalloc(sizeof(WaitInfo));
167 waitPtr->pid = result;
168 waitPtr->status = status;
169 waitPtr->nextPtr = deadList;