xref: /netbsd-src/external/gpl2/xcvs/dist/lib/waitpid.c (revision 5a6c14c844c4c665da5632061aebde7bb2cb5766)
1 #include <sys/cdefs.h>
2 __RCSID("$NetBSD: waitpid.c,v 1.2 2016/05/17 14:00:09 christos Exp $");
3 
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7 
8 #include "system.h"
9 #include "wait.h"
10 
11 #include <stdio.h>
12 
13 struct unreaped {
14   pid_t pid;
15   int status;
16 };
17 static struct unreaped *unreaped;
18 static int n;
19 
ualloc(oldptr,n)20 static struct unreaped *ualloc (oldptr, n)
21      struct unreaped *oldptr;
22      int n;
23 {
24   n *= sizeof (struct unreaped);
25   if (n == 0)
26     n = 1;
27   if (oldptr)
28     oldptr = (struct unreaped *) realloc ((char *) oldptr, n);
29   else
30     oldptr = (struct unreaped *) malloc (n);
31   if (oldptr == 0)
32     {
33       fprintf (stderr, "cannot allocate %d bytes\n", n);
34       exit (1);
35     }
36   return oldptr;
37 }
38 
waitpid(pid,status,options)39 pid_t waitpid (pid, status, options)
40      pid_t pid;
41      int *status;
42      int options;
43 {
44   int i;
45 
46   /* initialize */
47   if (unreaped == 0)
48     {
49       unreaped = ualloc (unreaped, 1);
50       unreaped[0].pid = 0;
51       n = 1;
52     }
53 
54   for (i = 0; unreaped[i].pid; i++)
55     if (unreaped[i].pid == pid)
56       {
57 	*status = unreaped[i].status;
58 	while (unreaped[i].pid)
59 	  {
60 	    unreaped[i] = unreaped[i+1];
61 	    i++;
62 	  }
63 	n--;
64 	return pid;
65       }
66 
67   while (1)
68     {
69 #ifdef HAVE_WAIT3
70       pid_t p = wait3 (status, options, (struct rusage *) 0);
71 #else
72       pid_t p = wait (status);
73 #endif
74 
75       if (p == 0 || p == -1 || p == pid)
76 	return p;
77 
78       n++;
79       unreaped = ualloc (unreaped, n);
80       unreaped[n-1].pid = p;
81       unreaped[n-1].status = *status;
82     }
83 }
84