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
13struct unreaped {
14  pid_t pid;
15  int status;
16};
17static struct unreaped *unreaped;
18static int n;
19
20static 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
39pid_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