1: # include "ctlmod.h" 2: # include "pipes.h" 3: # include <sccs.h> 4: 5: SCCSID(@(#)proc_err.c 8.1 12/31/84) 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: }