|
|
1.1 root 1: # include "ctlmod.h"
2: # include "pipes.h"
3: # include <sccs.h>
4:
5: SCCSID(@(#)proc_err.c 7.1 2/5/81)
6:
7: /*
8: ** PROC_ERR -- Process error message
9: **
10: ** This routine processes an error. It searches back through
11: ** the chain of contexts until it finds one that is willing to
12: ** process this error, or it finds that it must transfer the
13: ** error to another process to handle it.
14: **
15: ** It also unwinds the tree of
16: ** activations. It leaves us in the context that processes
17: ** the error, or the state that should be reading the
18: ** input pipe.
19: **
20: ** The local error handling function returns zero if the
21: ** error should be ignored, anything else otherwise.
22: **
23: ** Parameters:
24: ** pc -- error parameter count.
25: ** pv -- error parameter vector.
26: ** ppb -- a pointer to a pipe block to use in
27: ** sending this error.
28: **
29: ** Returns:
30: ** none.
31: **
32: ** Side Effects:
33: ** Unwinds the list of activations.
34: ** The input pipe can be changed under certain
35: ** circumstances.
36: **
37: ** Trace Flags:
38: ** 6.8 - 6.15
39: */
40:
41:
42: proc_err(ppb, pc, pv)
43: pb_t *ppb;
44: int pc;
45: PARM pv[];
46: {
47: register struct fn_def *f;
48: extern char *Proc_name;
49: register int i;
50: register ctx_t *ctx;
51: extern pb_t *MonPpb;
52:
53: # ifdef xCTR2
54: if (tTf(6, 8))
55: lprintf("proc_err: new = %d\n", Ctx.ctx_new);
56: # endif
57: pb_prime(ppb, PB_ERR);
58:
59: /*
60: ** Scan back on the list of context dependencies.
61: ** If we come to someone who can process this message,
62: ** we go ahead and do it. We also take this
63: ** opportunity to unwind the context list & call the
64: ** cleanup functions.
65: */
66:
67: for (ctx = &Ctx; ctx != NULL; ctx = ctx->ctx_link)
68: {
69: Proc_name = ctx->ctx_name;
70: f = ctx->ctx_fn;
71: # ifdef xCTR2
72: if (tTf(6, 9))
73: lprintf("proc_err: unwinding %s: errfn=%x, ppb=%x, link=%x, resp=%d, fn=%x\n",
74: Proc_name, ctx->ctx_errfn, ctx->ctx_ppb,
75: ctx->ctx_link, ctx->ctx_resp, f);
76: # endif
77:
78: /* Do the actual error processing. */
79: ppb->pb_proc = ctx->ctx_resp;
80: if (ctx->ctx_errfn != NULL)
81: i = (*ctx->ctx_errfn)(pc, pv);
82: else
83: i = -1;
84:
85: # ifdef xCTR2
86: if (tTf(6, 11))
87: lprintf("proc_err: errcode %d\n", i);
88: # endif
89: if (i == 0)
90: break;
91: else if (i > 0)
92: {
93: /* turn into nonfatal error */
94: ppb->pb_stat |= PB_INFO;
95: ppb->pb_proc = PB_FRONT;
96: }
97: else
98: {
99: /* call the cleanup function */
100: if (f != NULL && f->fn_active > 0)
101: (*f->fn_cleanup)(1);
102: }
103:
104: /* arrange to leave if parent not in this process */
105: if (ppb->pb_proc != Cm.cm_myproc)
106: {
107: send_off(ppb, pc, pv);
108: pb_flush(ppb);
109:
110: /* throw away dead contexts and exit */
111: break;
112: }
113: }
114: if (ctx == NULL)
115: syserr("proc_err: no parent");
116:
117: # ifdef xCTR3
118: if (tTf(6, 12))
119: {
120: lprintf("proc_err: cleanup: ctx=%x, ->_link=%x, MonPpb = ", ctx, ctx->ctx_link);
121: pb_dump(MonPpb, TRUE);
122: }
123: # endif
124: /* pop contexts down to ctx and exit */
125: ctx = ctx->ctx_link;
126: while (Ctx.ctx_link != ctx)
127: {
128: if (Ctx.ctx_link == NULL)
129: syserr("proc_err: underflow");
130: Ctx.ctx_new = TRUE;
131: resetp();
132: }
133:
134: /*
135: ** Flush input pipe.
136: ** THIS CODE IS ONLY NEEDED TO MAKE READMON WORK, AND
137: ** SHOULD BE REMOVED WHEN READMON GOES AWAY!!
138: */
139:
140: if (ctx == NULL)
141: {
142: Cm.cm_input = Cm.cm_rinput;
143: while (!bitset(PB_EOF, MonPpb->pb_stat))
144: pb_read(MonPpb);
145: MonPpb->pb_st = PB_UNKNOWN;
146: }
147:
148: longjmp(Ctx.ctx_jbuf, 1);
149: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.