OSDN Git Service

* exceptions.cc (set_signal_mask): Remove useless debugging output.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / wait.cc
1 /* wait.cc: Posix wait routines.
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4    2005, 2009, 2011 Red Hat, Inc.
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
12 #include "winsup.h"
13 #include <sys/wait.h>
14 #include "sigproc.h"
15 #include "thread.h"
16 #include "cygtls.h"
17
18 /* This is called _wait and not wait because the real wait is defined
19    in libc/syscalls/syswait.c.  It calls us.  */
20
21 extern "C" pid_t
22 wait (int *status)
23 {
24   return wait4 (-1, status, 0, NULL);
25 }
26
27 extern "C" pid_t
28 waitpid (pid_t intpid, int *status, int options)
29 {
30   return wait4 (intpid, status, options, NULL);
31 }
32
33 extern "C" pid_t
34 wait3 (int *status, int options, struct rusage *r)
35 {
36   return wait4 (-1, status, options, r);
37 }
38
39 /* Wait for any child to complete.
40  * Note: this is not thread safe.  Use of wait in multiple threads will
41  * not work correctly.
42  */
43
44 extern "C" pid_t
45 wait4 (int intpid, int *status, int options, struct rusage *r)
46 {
47   int res;
48   HANDLE waitfor;
49   waitq *w = &_my_tls.wq;
50
51   pthread_testcancel ();
52
53   while (1)
54     {
55       sig_dispatch_pending ();
56       if (options & ~(WNOHANG | WUNTRACED | WCONTINUED))
57         {
58           set_errno (EINVAL);
59           res = -1;
60           break;
61         }
62
63       if (r)
64         memset (r, 0, sizeof (*r));
65
66       w->pid = intpid;
67       w->options = options;
68       w->rusage = r;
69       sigproc_printf ("calling proc_subproc, pid %d, options %d",
70                       w->pid, w->options);
71       if (!proc_subproc (PROC_WAIT, (DWORD) w))
72         {
73           set_errno (ENOSYS);
74           paranoid_printf ("proc_subproc returned 0");
75           res = -1;
76           break;
77         }
78
79       if ((waitfor = w->ev) == NULL)
80         goto nochildren;
81
82       res = cancelable_wait (waitfor);
83
84       sigproc_printf ("%d = cancelable_wait (...)", res);
85
86       if (w->ev == NULL)
87         {
88         nochildren:
89           /* found no children */
90           set_errno (ECHILD);
91           res = -1;
92           break;
93         }
94
95       if (w->status == -1)
96         {
97           if (_my_tls.call_signal_handler ())
98             continue;
99           set_sig_errno (EINTR);
100           res = -1;
101         }
102       else if (res != WAIT_OBJECT_0)
103         {
104           set_errno (EINVAL);
105           res = -1;
106         }
107       else if ((res = w->pid) != 0 && status)
108         *status = w->status;
109       break;
110     }
111
112   syscall_printf ("%R = wait4(%d, %p, %d, %p)", res, intpid, w->status, options, r);
113   w->status = -1;
114   return res;
115 }