From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/OR_USING_C/10.5.c | 132 ++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 reference/C/CONTRIB/OR_USING_C/10.5.c (limited to 'reference/C/CONTRIB/OR_USING_C/10.5.c') diff --git a/reference/C/CONTRIB/OR_USING_C/10.5.c b/reference/C/CONTRIB/OR_USING_C/10.5.c new file mode 100644 index 0000000..df6140b --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.5.c @@ -0,0 +1,132 @@ +#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; + } + } +} + -- cgit v1.2.3-54-g00ecf