#include #include #include #include "10.h" waitfor() { int pid; JOB *j; PROC *p; JOB *findjob(); union wait status; /* * As long as we get something's status back... */ while ((pid = wait3(&status, WUNTRACED, 0)) >= 0) { /* * Find the job structure which has this * process. */ j = findjob(pid); /* * Find the process structure. */ for (p = j->procs; p->pid != pid; p = p->next) /* empty */ ; /* * Find out what happened to the process. */ if (WIFSTOPPED(status)) { /* * See if we know the reason it was * stopped. The w_stopsig element of * the structure contains the number * of the signal which stopped the * process. */ switch (status.w_stopsig) { case SIGTTIN: p->status |= PTTYINPUT; break; case SIGTTOU: p->status |= PTTYOUTPUT; break; case SIGSTOP: p->status |= PSTOPSIGNAL; break; default: break; } p->status |= PSTOPPED; j->status |= JNEEDNOTE; } else if (WIFEXITED(status)) { /* * Normal termination. */ if (status.w_retcode == 0) p->status |= PDONE; else p->status |= PEXITED; p->exitcode = status.w_retcode; /* * We're only going to note processes * exiting if all the processes in the * job are complete. */ if (alldone(j)) j->status |= JNEEDNOTE; } else if (WIFSIGNALED(status)) { p->status |= PSIGNALED; /* * Save the termination signal. */ p->termsig = status.w_termsig; /* * Check for a core dump. */ if (status.w_coredump) p->status |= PCOREDUMP; /* * We're only going to note processes * exiting if all the processes in the * job are complete. */ if (alldone(j)) j->status |= JNEEDNOTE; } /* * If this process is the one which was in the * foreground, we need to do special things, * and then return to the main control section * of the shell. */ if (j->pgrp == TermPgrp) { /* * If the job is stopped, we need to call * the stop routine. */ if (WIFSTOPPED(status)) { stop(j); printf("Stopped\n"); } /* * If the job exited or died somehow, we * need to regain control of the terminal. */ if (WIFEXITED(status) || WIFSIGNALED(status)) { ioctl(1, TIOCSPGRP, &MyPgrp); TermPgrp = MyPgrp; } /* * Go back. */ return; } } }