home *** CD-ROM | disk | FTP | other *** search
- # include "ctlmod.h"
- # include "pipes.h"
- # include <sccs.h>
-
- SCCSID(@(#)proc_err.c 8.1 12/31/84)
-
- /*
- ** PROC_ERR -- Process error message
- **
- ** This routine processes an error. It searches back through
- ** the chain of contexts until it finds one that is willing to
- ** process this error, or it finds that it must transfer the
- ** error to another process to handle it.
- **
- ** It also unwinds the tree of
- ** activations. It leaves us in the context that processes
- ** the error, or the state that should be reading the
- ** input pipe.
- **
- ** The local error handling function returns zero if the
- ** error should be ignored, anything else otherwise.
- **
- ** Parameters:
- ** pc -- error parameter count.
- ** pv -- error parameter vector.
- ** ppb -- a pointer to a pipe block to use in
- ** sending this error.
- **
- ** Returns:
- ** none.
- **
- ** Side Effects:
- ** Unwinds the list of activations.
- ** The input pipe can be changed under certain
- ** circumstances.
- **
- ** Trace Flags:
- ** 6.8 - 6.15
- */
-
-
- proc_err(ppb, pc, pv)
- pb_t *ppb;
- int pc;
- PARM pv[];
- {
- register struct fn_def *f;
- extern char *Proc_name;
- register int i;
- register ctx_t *ctx;
- extern pb_t *MonPpb;
-
- # ifdef xCTR2
- if (tTf(6, 8))
- lprintf("proc_err: new = %d\n", Ctx.ctx_new);
- # endif
- pb_prime(ppb, PB_ERR);
-
- /*
- ** Scan back on the list of context dependencies.
- ** If we come to someone who can process this message,
- ** we go ahead and do it. We also take this
- ** opportunity to unwind the context list & call the
- ** cleanup functions.
- */
-
- for (ctx = &Ctx; ctx != NULL; ctx = ctx->ctx_link)
- {
- Proc_name = ctx->ctx_name;
- f = ctx->ctx_fn;
- # ifdef xCTR2
- if (tTf(6, 9))
- lprintf("proc_err: unwinding %s: errfn=%x, ppb=%x, link=%x, resp=%d, fn=%x\n",
- Proc_name, ctx->ctx_errfn, ctx->ctx_ppb,
- ctx->ctx_link, ctx->ctx_resp, f);
- # endif
-
- /* Do the actual error processing. */
- ppb->pb_proc = ctx->ctx_resp;
- if (ctx->ctx_errfn != NULL)
- i = (*ctx->ctx_errfn)(pc, pv);
- else
- i = -1;
-
- # ifdef xCTR2
- if (tTf(6, 11))
- lprintf("proc_err: errcode %d\n", i);
- # endif
- if (i == 0)
- break;
- else if (i > 0)
- {
- /* turn into nonfatal error */
- ppb->pb_stat |= PB_INFO;
- ppb->pb_proc = PB_FRONT;
- }
- else
- {
- /* call the cleanup function */
- if (f != NULL && f->fn_active > 0)
- (*f->fn_cleanup)(1);
- }
-
- /* arrange to leave if parent not in this process */
- if (ppb->pb_proc != Cm.cm_myproc)
- {
- send_off(ppb, pc, pv);
- pb_flush(ppb);
-
- /* throw away dead contexts and exit */
- break;
- }
- }
- if (ctx == NULL)
- syserr("proc_err: no parent");
-
- # ifdef xCTR3
- if (tTf(6, 12))
- {
- lprintf("proc_err: cleanup: ctx=%x, ->_link=%x, MonPpb = ", ctx, ctx->ctx_link);
- pb_dump(MonPpb, TRUE);
- }
- # endif
- /* pop contexts down to ctx and exit */
- ctx = ctx->ctx_link;
- while (Ctx.ctx_link != ctx)
- {
- if (Ctx.ctx_link == NULL)
- syserr("proc_err: underflow");
- Ctx.ctx_new = TRUE;
- resetp();
- }
-
- /*
- ** Flush input pipe.
- ** THIS CODE IS ONLY NEEDED TO MAKE READMON WORK, AND
- ** SHOULD BE REMOVED WHEN READMON GOES AWAY!!
- */
-
- if (ctx == NULL)
- {
- Cm.cm_input = Cm.cm_rinput;
- while (!bitset(PB_EOF, MonPpb->pb_stat))
- pb_read(MonPpb);
- MonPpb->pb_st = PB_UNKNOWN;
- }
-
- longjmp(Ctx.ctx_jbuf, 1);
- }
-