/* * Mark a command as don't care. */ void free_command(int pid) { register struct child* cp = findchild(pid); if (cp->done) delchild(cp); else cp->free = 1; }
/* * Wait for a specific child to die. */ int wait_command(int pid) { register struct child* cp = findchild(pid); int status = -1; holdsigs(); while (waitpid(pid, &status, 0) == -1 && errno == EINTR); relsesigs(); delchild(cp); return status; }
/* * Mark a child as don't care. */ void free_child(int pid) { sigset_t nset, oset; struct child *cp = findchild(pid); (void)sigemptyset(&nset); (void)sigaddset(&nset, SIGCHLD); (void)sigprocmask(SIG_BLOCK, &nset, &oset); if (cp->done) delchild(cp); else cp->free = 1; (void)sigprocmask(SIG_SETMASK, &oset, NULL); }
/*ARGSUSED*/ void sigchild(int signo __unused) { int pid; int status; struct child *cp; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { cp = findchild(pid); if (cp->free) delchild(cp); else { cp->done = 1; cp->status = status; } } }
/* * Wait for a specific child to die. */ int wait_child(int pid) { sigset_t nset, oset; struct child *cp = findchild(pid); sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); while (!cp->done) (void)sigsuspend(&oset); wait_status = cp->status; delchild(cp); sigprocmask(SIG_SETMASK, &oset, NULL); return ((WIFEXITED(wait_status) && WEXITSTATUS(wait_status)) ? -1 : 0); }