]> git.cworth.org Git - tar/blob - lib/waitpid.c
Imported Upstream version 1.20
[tar] / lib / waitpid.c
1 /* Emulate waitpid on systems that just have wait.
2    Copyright 1994, 1995, 1998, 1999, 2007 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, or (at your option)
7    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; see the file COPYING.
16    If not, write to the Free Software Foundation, 
17    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
18
19 #if HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
26 #include <errno.h>
27 #ifndef errno
28 extern int errno;
29 #endif
30
31 #define WAITPID_CHILDREN 8
32 static pid_t waited_pid[WAITPID_CHILDREN];
33 static int waited_status[WAITPID_CHILDREN];
34
35 pid_t
36 waitpid (pid_t pid, int *stat_loc, int options)
37 {
38   int i;
39   pid_t p;
40
41   if (!options && (pid == -1 || 0 < pid))
42     {
43       /* If we have already waited for this child, return it immediately.  */
44       for (i = 0;  i < WAITPID_CHILDREN;  i++)
45         {
46           p = waited_pid[i];
47           if (p && (p == pid || pid == -1))
48             {
49               waited_pid[i] = 0;
50               goto success;
51             }
52         }
53
54       /* The child has not returned yet; wait for it, accumulating status.  */
55       for (i = 0;  i < WAITPID_CHILDREN;  i++)
56         if (! waited_pid[i])
57           {
58             p = wait (&waited_status[i]);
59             if (p < 0)
60               return p;
61             if (p == pid || pid == -1)
62               goto success;
63             waited_pid[i] = p;
64           }
65     }
66
67   /* We cannot emulate this wait call, e.g. because of too many children.  */
68   errno = EINVAL;
69   return -1;
70
71 success:
72   if (stat_loc)
73     *stat_loc = waited_status[i];
74   return p;
75 }