home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / rc / part06 / wait.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-30  |  2.1 KB  |  125 lines

  1. #include <errno.h>
  2. #include <setjmp.h>
  3. #include "rc.h"
  4. #include "jbwrap.h"
  5.  
  6. bool forked = FALSE;
  7.  
  8. static int rc_wait(int *);
  9.  
  10. typedef struct Pid Pid;
  11.  
  12. static struct Pid {
  13.     int pid, stat;
  14.     bool alive;
  15.     Pid *n;
  16. } *plist = NULL;
  17.  
  18. extern int rc_fork() {
  19.     Pid *new = enew(Pid);
  20.     int pid = fork();
  21.     switch (pid) {
  22.     case -1:
  23.         uerror("fork");
  24.         rc_error(NULL);
  25.         /* NOTREACHED */
  26.     case 0:
  27.         forked = TRUE;
  28.         SIGCHK;
  29.         return 0;
  30.     default:
  31.         new->pid = pid;
  32.         new->alive = TRUE;
  33.         new->n = plist;
  34.         plist = new;
  35.         return pid;
  36.     }
  37. }
  38.  
  39. extern int rc_wait4(int pid, int *stat, bool nointr) {
  40.     Pid *r, *prev;
  41.     int ret;
  42.     /* first look for a child which may already have exited */
  43. again:    for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n)
  44.         if (r->pid == pid)
  45.             break;
  46.     if (r == NULL) {
  47.         errno = ECHILD; /* no children */
  48.         uerror("wait");
  49.         *stat = 0x100; /* exit(1) */
  50.         return -1;
  51.     }
  52.     if (r->alive) {
  53.         while (pid != (ret = rc_wait(stat))) {
  54.             Pid *q;
  55.             if (ret < 0) {
  56.                 if (nointr)
  57.                     goto again;
  58.                 return ret;
  59.             }
  60.             for (q = plist; q != NULL; q = q->n)
  61.                 if (q->pid == ret) {
  62.                     q->alive = FALSE;
  63.                     q->stat = *stat;
  64.                     break;
  65.                 }
  66.         }
  67.     } else
  68.         *stat = r->stat;
  69.     if (prev == NULL)
  70.         plist = r->n; /* remove element from head of list */
  71.     else
  72.         prev->n = r->n;
  73.     efree(r);
  74.     return pid;
  75. }
  76.  
  77. extern List *sgetapids() {
  78.     List *r;
  79.     Pid *p;
  80.     for (r = NULL, p = plist; p != NULL; p = p->n) {
  81.         List *q;
  82.         if (!p->alive)
  83.             continue;
  84.         q = nnew(List);
  85.         q->w = nprint("%d", p->pid);
  86.         q->m = NULL;
  87.         q->n = r;
  88.         r = q;
  89.     }
  90.     return r;
  91. }
  92.  
  93. extern void waitforall() {
  94.     int stat;
  95.     while (plist != NULL) {
  96.         int pid = rc_wait4(plist->pid, &stat, FALSE);
  97.         if (pid > 0)
  98.             setstatus(pid, stat);
  99.         else
  100.             set(FALSE);
  101.         SIGCHK;
  102.     }
  103. }
  104.  
  105. /*
  106.    rc_wait: a wait() wrapper that interfaces wait() w/rc signals.
  107.    Note that the signal queue is not checked in this fn; someone
  108.    may want to resume the wait() without delivering any signals.
  109. */
  110.  
  111. static int rc_wait(int *stat) {
  112.     int r;
  113.     interrupt_happened = FALSE;
  114.     if (!setjmp(slowbuf.j)) {
  115.         slow = TRUE;
  116.         if (!interrupt_happened)
  117.             r = wait(stat);
  118.         else
  119.             r = -1;
  120.     } else
  121.         r = -1;
  122.     slow = FALSE;
  123.     return r;
  124. }
  125.