Imported Upstream version 4.5.10
[platform/upstream/findutils.git] / lib / waitpid.c
1 /* Emulate waitpid on systems that just have wait.
2    Copyright 1994, 1995, 1998, 1999, 2010 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <config.h>
18
19
20 #include <errno.h>
21 #ifndef errno
22 extern int errno;
23 #endif
24
25
26 #if defined _MSC_VER || defined __MINGW32__
27 /* Native Woe32 API.  */
28 #include <process.h>
29 #else
30 /* Unix API.  */
31 #include <sys/wait.h>
32 #endif
33
34 #define WAITPID_CHILDREN 8
35 static pid_t waited_pid[WAITPID_CHILDREN];
36 static int waited_status[WAITPID_CHILDREN];
37
38 pid_t
39 waitpid (pid_t pid, int *stat_loc, int options)
40 {
41   int i;
42   pid_t p;
43
44   if (!options && (pid == -1 || 0 < pid))
45     {
46       /* If we have already waited for this child, return it immediately.  */
47       for (i = 0;  i < WAITPID_CHILDREN;  i++)
48         {
49           p = waited_pid[i];
50           if (p && (p == pid || pid == -1))
51             {
52               waited_pid[i] = 0;
53               goto success;
54             }
55         }
56
57       /* The child has not returned yet; wait for it, accumulating status.  */
58       for (i = 0;  i < WAITPID_CHILDREN;  i++)
59         if (! waited_pid[i])
60           {
61             p = wait (&waited_status[i]);
62             if (p < 0)
63               return p;
64             if (p == pid || pid == -1)
65               goto success;
66             waited_pid[i] = p;
67           }
68     }
69
70   /* We cannot emulate this wait call, e.g. because of too many children.  */
71   errno = EINVAL;
72   return -1;
73
74 success:
75   if (stat_loc)
76     *stat_loc = waited_status[i];
77   return p;
78 }