diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:38:33 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:38:33 +0000 |
commit | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (patch) | |
tree | dc4fcf1e5e22a040716ef92c496b8d94959b2baa /winsup/cygwin/wait.cc | |
parent | 369d8a8fd5e887eca547bf34bccfdf755c9e5397 (diff) | |
download | newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.zip newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.tar.gz newlib-1fd5e000ace55b323124c7e556a7a864b972a5c4.tar.bz2 |
import winsup-2000-02-17 snapshot
Diffstat (limited to 'winsup/cygwin/wait.cc')
-rw-r--r-- | winsup/cygwin/wait.cc | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc new file mode 100644 index 0000000..1822400 --- /dev/null +++ b/winsup/cygwin/wait.cc @@ -0,0 +1,113 @@ +/* wait.cc: Posix wait routines. + + Copyright 1996, 1997, 1998, 1999 Cygnus Solutions. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include <sys/wait.h> +#include <stdlib.h> +#include <errno.h> +#include "winsup.h" + +/* This is called _wait and not wait because the real wait is defined + in libc/syscalls/syswait.c. It calls us. */ + +extern "C" +pid_t +_wait (int *status) +{ + return wait4 (-1, status, 0, NULL); +} + +pid_t +waitpid (pid_t intpid, int *status, int options) +{ + return wait4 (intpid, status, options, NULL); +} + +pid_t +wait3 (int *status, int options, struct rusage *r) +{ + return wait4 (-1, status, options, r); +} + +/* Wait for any child to complete. + * Note: this is not thread safe. Use of wait in multiple threads will + * not work correctly. + */ + +pid_t +wait4 (int intpid, int *status, int options, struct rusage *r) +{ + int rc; + waitq *w; + HANDLE waitfor; + + if (options & ~(WNOHANG | WUNTRACED)) + { + set_errno (EINVAL); + return -1; + } + + if (r) + memset (r, 0, sizeof (*r)); + + if ((w = (waitq *) waitq_storage.get ()) == NULL) + w = (waitq *) waitq_storage.create (); + + w->pid = intpid; + w->options = options; + w->rusage = r; + sigproc_printf("calling proc_subproc, pid %d, options %d", + w->pid, w->options); + if (!proc_subproc(PROC_WAIT, (DWORD)w)) + { + set_errno(ENOSYS); + paranoid_printf ("proc_subproc returned 0"); + rc = -1; + goto done; + } + + if ((waitfor = w->ev) == NULL) + goto nochildren; + + rc = WaitForSingleObject (waitfor, INFINITE); + + sigproc_printf ("%d = WaitForSingleObject (...)", rc); + + if (w->ev == NULL) + { + nochildren: + /* found no children */ + set_errno (ECHILD); + rc = -1; + goto done; + } + + if (w->status == -1) + { + set_sig_errno (EINTR); + rc = -1; + } + else if (rc != WAIT_OBJECT_0) + { + /* We shouldn't set errno to any random value if we can help it. + See the Posix manual for a list of valid values for `errno'. */ + set_errno (EINVAL); + rc = -1; + } + else if ((rc = w->pid) != 0 && status) + *status = w->status; + +done: + sigproc_printf ("intpid %d, status %p, w->status %d, options %d, rc %d", + intpid, status, w->status, options, rc); + w->status = -1; + if (rc < 0) + sigproc_printf("*** errno = %d", get_errno()); + return rc; +} |