home *** CD-ROM | disk | FTP | other *** search
- #include <errno.h>
- #include <setjmp.h>
- #include "rc.h"
- #include "jbwrap.h"
-
- bool forked = FALSE;
-
- static int rc_wait(int *);
-
- typedef struct Pid Pid;
-
- static struct Pid {
- int pid, stat;
- bool alive;
- Pid *n;
- } *plist = NULL;
-
- extern int rc_fork() {
- Pid *new = enew(Pid);
- int pid = fork();
- switch (pid) {
- case -1:
- uerror("fork");
- rc_error(NULL);
- /* NOTREACHED */
- case 0:
- forked = TRUE;
- SIGCHK;
- return 0;
- default:
- new->pid = pid;
- new->alive = TRUE;
- new->n = plist;
- plist = new;
- return pid;
- }
- }
-
- extern int rc_wait4(int pid, int *stat, bool nointr) {
- Pid *r, *prev;
- int ret;
- /* first look for a child which may already have exited */
- again: for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n)
- if (r->pid == pid)
- break;
- if (r == NULL) {
- errno = ECHILD; /* no children */
- uerror("wait");
- *stat = 0x100; /* exit(1) */
- return -1;
- }
- if (r->alive) {
- while (pid != (ret = rc_wait(stat))) {
- Pid *q;
- if (ret < 0) {
- if (nointr)
- goto again;
- return ret;
- }
- for (q = plist; q != NULL; q = q->n)
- if (q->pid == ret) {
- q->alive = FALSE;
- q->stat = *stat;
- break;
- }
- }
- } else
- *stat = r->stat;
- if (prev == NULL)
- plist = r->n; /* remove element from head of list */
- else
- prev->n = r->n;
- efree(r);
- return pid;
- }
-
- extern List *sgetapids() {
- List *r;
- Pid *p;
- for (r = NULL, p = plist; p != NULL; p = p->n) {
- List *q;
- if (!p->alive)
- continue;
- q = nnew(List);
- q->w = nprint("%d", p->pid);
- q->m = NULL;
- q->n = r;
- r = q;
- }
- return r;
- }
-
- extern void waitforall() {
- int stat;
- while (plist != NULL) {
- int pid = rc_wait4(plist->pid, &stat, FALSE);
- if (pid > 0)
- setstatus(pid, stat);
- else
- set(FALSE);
- SIGCHK;
- }
- }
-
- /*
- rc_wait: a wait() wrapper that interfaces wait() w/rc signals.
- Note that the signal queue is not checked in this fn; someone
- may want to resume the wait() without delivering any signals.
- */
-
- static int rc_wait(int *stat) {
- int r;
- interrupt_happened = FALSE;
- if (!setjmp(slowbuf.j)) {
- slow = TRUE;
- if (!interrupt_happened)
- r = wait(stat);
- else
- r = -1;
- } else
- r = -1;
- slow = FALSE;
- return r;
- }
-