Exemple #1
0
/* 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_;
}
Exemple #2
0
/* 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_;
}