diff options
Diffstat (limited to 'xc/test/xsuite/port/waitpid.c')
-rw-r--r-- | xc/test/xsuite/port/waitpid.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/xc/test/xsuite/port/waitpid.c b/xc/test/xsuite/port/waitpid.c new file mode 100644 index 000000000..f8f60b001 --- /dev/null +++ b/xc/test/xsuite/port/waitpid.c @@ -0,0 +1,117 @@ +/* $XConsortium$ */ +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> + +#ifdef DEBUG +# include <stdio.h> +# define DBP(fmt,arg) (fprintf(stderr, "waitpid(%d): ", currpid), \ + fprintf(stderr, fmt, arg), fflush(stderr)) +#else +# define DBP(fmt,arg) +#endif + +#define MAXTAB 20 + +static struct { + pid_t pid; + int status; +} savtab[MAXTAB]; +static int ntab = 0; +static pid_t currpid = 0; + +pid_t +waitpid(pid, stat_loc, options) +pid_t pid; +int *stat_loc; +int options; +{ + int rval, i; + int local_loc; + + /* Clear the table for each new process */ + if (getpid() != currpid) + { + ntab = 0; + currpid = getpid(); + DBP("clearing table\n", 0); + } + + DBP("waiting for pid %d\n", pid); + + if (options & ~(WNOHANG|WUNTRACED)) + { + errno = EINVAL; + return -1; + } + + if (pid == -1) + { + /* see if any saved */ + for (i=0; i<ntab; i++) + if (savtab[i].pid != 0) + { + pid = savtab[i].pid; + if (stat_loc) + *stat_loc = savtab[i].status; + savtab[i].pid = 0; + DBP("got %d from table\n", pid); + return pid; + } + + DBP("return wait3(...)\n", 0); + return wait3(stat_loc, options, (int *)0); + } + + if (pid <= 0) + { + /* can't do this functionality (without reading /dev/kmem!) */ + errno = EINVAL; + return -1; + } + + /* see if already saved */ + for (i=0; i<ntab; i++) + if (savtab[i].pid == pid) + { + if (stat_loc) + *stat_loc = savtab[i].status; + savtab[i].pid = 0; + DBP("found %d in table\n", pid); + return pid; + } + + rval = wait3(&local_loc, options, (int *)0); + DBP("wait3() returned %d\n", rval); + while (rval != pid && rval != -1 && rval != 0) + { + /* save for later */ + for (i=0; i<ntab; i++) + if (savtab[i].pid == 0) + { + savtab[i].pid = rval; + savtab[i].status = local_loc; + DBP("saved %d in free slot\n", rval); + break; + } + if (i == ntab) + { + if (ntab < MAXTAB) + { + savtab[ntab].pid = rval; + savtab[ntab].status = local_loc; + ++ntab; + DBP("saved %d in new slot\n", rval); + } + else + DBP("no free slot for %d\n", rval); + } + rval = wait3(&local_loc, options, (int *)0); + DBP("wait3() returned %d\n", rval); + } + + if(stat_loc) + *stat_loc = local_loc; + + return rval; +} |