/* ARGSUSED */ static void j_sigchld(int sig) { int errno_ = errno; Job *j; Proc *p = NULL; int pid; int status; struct rusage ru0, ru1; /* Don't wait for any processes if a job is partially started. * This is so we don't do away with the process group leader * before all the processes in a pipe line are started (so the * setpgid() won't fail) */ for (j = job_list; j; j = j->next) if (j->ppid == procpid && !(j->flags & JF_STARTED)) { held_sigchld = 1; goto finished; } getrusage(RUSAGE_CHILDREN, &ru0); do { pid = waitpid(-1, &status, (WNOHANG|WUNTRACED)); if (pid <= 0) /* return if would block (0) ... */ break; /* ... or no children or interrupted (-1) */ getrusage(RUSAGE_CHILDREN, &ru1); /* find job and process structures for this pid */ for (j = job_list; j != (Job *) 0; j = j->next) for (p = j->proc_list; p != (Proc *) 0; p = p->next) if (p->pid == pid) goto found; found: if (j == (Job *) 0) { /* Can occur if process has kids, then execs shell warningf(true, "bad process waited for (pid = %d)", pid); */ ru0 = ru1; continue; } (void)timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime); (void)timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime); (void)timeradd(&j->systime, &ru1.ru_stime, &j->systime); (void)timersub(&j->systime, &ru0.ru_stime, &j->systime); ru0 = ru1; p->status = status; #ifdef JOBS if (WIFSTOPPED(status)) p->state = PSTOPPED; else #endif /* JOBS */ if (WIFSIGNALED(status)) p->state = PSIGNALLED; else p->state = PEXITED; check_job(j); /* check to see if entire job is done */ } while (1); finished: errno = errno_; }
/* SIGCHLD handler to reap children and update job states * * If jobs are compiled in then this routine expects sigchld to be blocked. */ static void j_sigchld(int sig) { int errno_ = errno; Job *j; Proc *p = 0; int pid; WAIT_T status; struct tms t0, t1; /* Don't wait for any processes if a job is partially started. * This is so we don't do away with the process group leader * before all the processes in a pipe line are started (so the * setpgid() won't fail) */ for (j = job_list; j; j = j->next) if (j->ppid == procpid && !(j->flags & JF_STARTED)) { held_sigchld = 1; return; } ksh_times(&t0); do { pid = wait(&status); if (pid <= 0) /* return if would block (0) ... */ break; /* ... or no children or interrupted (-1) */ ksh_times(&t1); /* find job and process structures for this pid */ for (j = job_list; j != (Job *) 0; j = j->next) for (p = j->proc_list; p != (Proc *) 0; p = p->next) if (p->pid == pid) goto found; found: if (j == (Job *) 0) { /* Can occur if process has kids, then execs shell warningf(true, "bad process waited for (pid = %d)", pid); */ t0 = t1; continue; } j->usrtime += t1.tms_cutime - t0.tms_cutime; j->systime += t1.tms_cstime - t0.tms_cstime; t0 = t1; p->status = status; if (WIFSIGNALED(status)) p->state = PSIGNALLED; else p->state = PEXITED; check_job(j); /* check to see if entire job is done */ } while (0); errno = errno_; }