]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* wait.cc: Posix wait routines. |
2 | ||
bc837d22 CF |
3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, |
4 | 2009, 2011, 2012 Red Hat, Inc. | |
1fd5e000 CF |
5 | |
6 | This file is part of Cygwin. | |
7 | ||
8 | This software is a copyrighted work licensed under the terms of the | |
9 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
10 | details. */ | |
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 | 22 | extern "C" pid_t |
5ec14fe4 | 23 | wait (int *status) |
1fd5e000 CF |
24 | { |
25 | return wait4 (-1, status, 0, NULL); | |
26 | } | |
27 | ||
c367dfd0 | 28 | extern "C" pid_t |
1fd5e000 CF |
29 | waitpid (pid_t intpid, int *status, int options) |
30 | { | |
31 | return wait4 (intpid, status, options, NULL); | |
32 | } | |
33 | ||
c367dfd0 | 34 | extern "C" pid_t |
1fd5e000 CF |
35 | wait3 (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 | 45 | extern "C" pid_t |
1fd5e000 CF |
46 | wait4 (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 | ||
806e732c | 83 | res = cygwait (waitfor, cw_infinite, cw_cancel | cw_cancel_self); |
f6111483 | 84 | |
806e732c | 85 | sigproc_printf ("%d = cygwait (...)", 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 | } |