]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/wait.cc
* DevNotes: Add entry cgf-000013.
[newlib-cygwin.git] / winsup / cygwin / wait.cc
CommitLineData
1fd5e000
CF
1/* wait.cc: Posix wait routines.
2
f0968c1e 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4ae63783 4 2005, 2009, 2011, 2012 Red Hat, Inc.
1fd5e000
CF
5
6This file is part of Cygwin.
7
8This software is a copyrighted work licensed under the terms of the
9Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10details. */
11
4c8d72de 12#include "winsup.h"
1fd5e000 13#include <sys/wait.h>
bccd5e0d 14#include "sigproc.h"
4a3584c8 15#include "thread.h"
e431827c 16#include "cygtls.h"
4ae63783 17#include "cygwait.h"
1fd5e000
CF
18
19/* This is called _wait and not wait because the real wait is defined
20 in libc/syscalls/syswait.c. It calls us. */
21
c367dfd0 22extern "C" pid_t
5ec14fe4 23wait (int *status)
1fd5e000
CF
24{
25 return wait4 (-1, status, 0, NULL);
26}
27
c367dfd0 28extern "C" pid_t
1fd5e000
CF
29waitpid (pid_t intpid, int *status, int options)
30{
31 return wait4 (intpid, status, options, NULL);
32}
33
c367dfd0 34extern "C" pid_t
1fd5e000
CF
35wait3 (int *status, int options, struct rusage *r)
36{
37 return wait4 (-1, status, options, r);
38}
39
40/* Wait for any child to complete.
41 * Note: this is not thread safe. Use of wait in multiple threads will
42 * not work correctly.
43 */
44
c367dfd0 45extern "C" pid_t
1fd5e000
CF
46wait4 (int intpid, int *status, int options, struct rusage *r)
47{
9470a80c 48 int res;
1fd5e000 49 HANDLE waitfor;
183f4d80 50 waitq *w = &_my_tls.wq;
1fd5e000 51
4a3584c8
TP
52 pthread_testcancel ();
53
f6111483 54 while (1)
1fd5e000 55 {
05cb7b17 56 sig_dispatch_pending ();
acced2ce 57 if (options & ~(WNOHANG | WUNTRACED | WCONTINUED))
f6111483
CF
58 {
59 set_errno (EINVAL);
183f4d80
CF
60 res = -1;
61 break;
f6111483
CF
62 }
63
64 if (r)
65 memset (r, 0, sizeof (*r));
66
f6111483
CF
67 w->pid = intpid;
68 w->options = options;
69 w->rusage = r;
70 sigproc_printf ("calling proc_subproc, pid %d, options %d",
08b0a057 71 w->pid, w->options);
1c5c9a6b 72 if (!proc_subproc (PROC_WAIT, (DWORD) w))
f6111483
CF
73 {
74 set_errno (ENOSYS);
75 paranoid_printf ("proc_subproc returned 0");
76 res = -1;
183f4d80 77 break;
f6111483
CF
78 }
79
80 if ((waitfor = w->ev) == NULL)
81 goto nochildren;
82
962f9a2c 83 res = cancelable_wait (waitfor, cw_infinite, cw_cancel | cw_cancel_self);
f6111483 84
ce331834 85 sigproc_printf ("%d = cancelable_wait (...)", res);
f6111483
CF
86
87 if (w->ev == NULL)
88 {
89 nochildren:
90 /* found no children */
91 set_errno (ECHILD);
92 res = -1;
183f4d80 93 break;
f6111483
CF
94 }
95
96 if (w->status == -1)
97 {
183f4d80
CF
98 if (_my_tls.call_signal_handler ())
99 continue;
f6111483 100 set_sig_errno (EINTR);
f6111483
CF
101 res = -1;
102 }
103 else if (res != WAIT_OBJECT_0)
104 {
f6111483
CF
105 set_errno (EINVAL);
106 res = -1;
107 }
108 else if ((res = w->pid) != 0 && status)
109 *status = w->status;
183f4d80 110 break;
1fd5e000
CF
111 }
112
ce331834 113 syscall_printf ("%R = wait4(%d, %p, %d, %p)", res, intpid, w->status, options, r);
1fd5e000 114 w->status = -1;
9470a80c 115 return res;
1fd5e000 116}
This page took 0.447887 seconds and 5 git commands to generate.