1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/ioctl.h>
#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;
}
}
}
|