/* wait.cc: Posix wait routines. 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 "winsup.h" #include #include "sigproc.h" #include "thread.h" #include "cygtls.h" #include "cygwait.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); } extern "C" pid_t waitpid (pid_t intpid, int *status, int options) { return wait4 (intpid, status, options, NULL); } extern "C" 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. */ extern "C" pid_t wait4 (int intpid, int *status, int options, struct rusage *r) { int res; HANDLE waitfor; waitq *w = &_my_tls.wq; pthread_testcancel (); while (1) { sig_dispatch_pending (); if (options & ~(WNOHANG | WUNTRACED | WCONTINUED)) { set_errno (EINVAL); res = -1; break; } if (r) memset (r, 0, sizeof (*r)); 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, (uintptr_t) w)) { set_errno (ENOSYS); paranoid_printf ("proc_subproc returned 0"); res = -1; break; } if ((waitfor = w->ev) == NULL) goto nochildren; res = cygwait (waitfor, cw_infinite, cw_cancel | cw_cancel_self); sigproc_printf ("%d = cygwait (...)", res); if (w->ev == NULL) { nochildren: /* found no children */ set_errno (ECHILD); res = -1; break; } if (w->status == -1) { if (_my_tls.call_signal_handler ()) continue; set_sig_errno (EINTR); res = -1; } else if (res != WAIT_OBJECT_0) { set_errno (EINVAL); res = -1; } else if ((res = w->pid) != 0 && status) *status = w->status; break; } syscall_printf ("%R = wait4(%d, %y, %d, %p)", res, intpid, w->status, options, r); w->status = -1; return res; }