Imported Upstream version 2.5.1p3
[debian/amanda] / common-src / waitpid.c
1 /*
2  
3 Copyright (c) 1990, 1991, 1992  X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
25
26  *
27  * Copyright 1990, 1991, 1992 by UniSoft Group Limited.
28  * 
29  * Permission to use, copy, modify, distribute, and sell this software and
30  * its documentation for any purpose is hereby granted without fee,
31  * provided that the above copyright notice appear in all copies and that
32  * both that copyright notice and this permission notice appear in
33  * supporting documentation, and that the name of UniSoft not be
34  * used in advertising or publicity pertaining to distribution of the
35  * software without specific, written prior permission.  UniSoft
36  * makes no representations about the suitability of this software for any
37  * purpose.  It is provided "as is" without express or implied warranty.
38  *
39  * $XConsortium: waitpid.c,v 1.3 94/04/17 20:59:56 rws Exp $
40  */
41
42 /* modified for Amanda team:
43  * replaced all occurrences of "int" for status variables with "amwait_t"
44  * compile only if wait4() is not available; if it is, waitpid() is
45  * #defined to use wait4 instead.  */
46  
47 #include "config.h"
48
49 #ifdef HAVE_WAIT4
50 /* some compilers do not't like empty C sources */
51 static void foo() {};
52
53 #else
54
55 #if 1
56 #include "amanda.h"
57 #else
58 /* these are all included in amanda.h */
59 #include <sys/types.h>
60 #include <sys/wait.h>
61 #include <errno.h>
62 #endif
63
64 #ifdef DEBUG
65 #   include <stdio.h>
66 #   define      DBP(fmt,arg)    (fprintf(stderr, "waitpid(%d): ", currpid), \
67                                  fprintf(stderr, fmt, arg), fflush(stderr))
68 #else
69 #   define      DBP(fmt,arg)
70 #endif
71
72 #define MAXTAB 20
73
74 static struct {
75         pid_t pid;
76         amwait_t /*int*/ status;
77 } savtab[MAXTAB];
78 static int      ntab = 0;
79 static pid_t    currpid = 0;
80
81 pid_t
82 waitpid(pid, stat_loc, options)
83 pid_t pid;
84 amwait_t /*int*/ *stat_loc;
85 int options;
86 {
87         int rval, i;
88         amwait_t /*int*/ local_loc;
89
90         /* Clear the table for each new process */
91         if (getpid() != currpid)
92         {
93                 ntab = 0;
94                 currpid = getpid();
95                 DBP("clearing table\n", 0);
96         }
97
98         DBP("waiting for pid %d\n", pid);
99
100         if (options & ~(WNOHANG|WUNTRACED))
101         {
102                 errno = EINVAL;
103                 return -1;
104         }
105
106         if (pid == -1)
107         {
108                 /* see if any saved */
109                 for (i=0; i<ntab; i++)
110                         if (savtab[i].pid != 0)
111                         {
112                                 pid = savtab[i].pid;
113                                 if (stat_loc)
114                                         *stat_loc = savtab[i].status;
115                                 savtab[i].pid = 0;
116                                 DBP("got %d from table\n", pid);
117                                 return pid;
118                         }
119
120                 DBP("return wait3(...)\n", 0);
121                 return wait3(stat_loc, options, (int *)0);
122         }
123
124         if (pid <= 0)
125         {
126                 /* can't do this functionality (without reading /dev/kmem!) */
127                 errno = EINVAL;
128                 return -1;
129         }
130
131         /* see if already saved */
132         for (i=0; i<ntab; i++)
133                 if (savtab[i].pid == pid)
134                 {
135                         if (stat_loc)
136                                 *stat_loc = savtab[i].status;
137                         savtab[i].pid = 0;
138                         DBP("found %d in table\n", pid);
139                         return pid;
140                 }
141
142         rval = wait3(&local_loc, options, (int *)0);
143         DBP("wait3() returned %d\n", rval);
144         while (rval != pid && rval != -1 && rval != 0)
145         {
146                 /* save for later */
147                 for (i=0; i<ntab; i++)
148                         if (savtab[i].pid == 0)
149                         {
150                                 savtab[i].pid = rval;
151                                 savtab[i].status = local_loc;
152                                 DBP("saved %d in free slot\n", rval);
153                                 break;
154                         }
155                 if (i == ntab)
156                 {
157                         if (ntab < MAXTAB)
158                         {
159                                 savtab[ntab].pid = rval;
160                                 savtab[ntab].status = local_loc;
161                                 ++ntab;
162                                 DBP("saved %d in new slot\n", rval);
163                         }
164                         else
165                                 DBP("no free slot for %d\n", rval);
166                 }
167                 rval = wait3(&local_loc, options, (int *)0);
168                 DBP("wait3() returned %d\n", rval);
169         }
170
171         if(stat_loc)
172                 *stat_loc = local_loc;
173
174         return rval;
175 }
176 #endif