183 lines
4.6 KiB
C
183 lines
4.6 KiB
C
/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
|
||
* This software is quasi-public; it may be used freely with
|
||
* like software, but may NOT be sold or made part of licensed
|
||
* products without permission of the author.
|
||
*/
|
||
/* EEERR - Error handling & testing routines
|
||
*/
|
||
|
||
#include "elle.h"
|
||
|
||
#if V6
|
||
#include "eesigs.h"
|
||
#else
|
||
#include <signal.h>
|
||
#endif
|
||
|
||
/* EFUN: "Hit Breakpoint" */
|
||
f_bkpt()
|
||
{ clean_exit();
|
||
bpt();
|
||
set_tty();
|
||
}
|
||
bpt() {} /* Put a DDT/ADB breakpoint here */
|
||
|
||
#if !(STRERROR) /* If strerror() not supported, we provide it. */
|
||
extern int sys_nerr; /* Max index into sys_errlist */
|
||
extern char *sys_errlist[];
|
||
|
||
char *
|
||
strerror(num)
|
||
int num;
|
||
{
|
||
static char badbuf[30];
|
||
if (num > 0 && num <= sys_nerr)
|
||
return (sys_errlist[num]);
|
||
sprintf(badbuf, "unknown error %d", num);
|
||
return badbuf;
|
||
}
|
||
#endif /* -STRERROR */
|
||
|
||
|
||
errsbm(type,adr,str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
|
||
register int type; /* Type, flags */
|
||
int (*adr)(); /* Addr called from */
|
||
char *str; /* Printf string */
|
||
{ register struct buffer *b;
|
||
int oldttystate;
|
||
|
||
oldttystate = clean_exit(); /* Ensure not in editing mode */
|
||
if(type == SBFERR) /* File overwrite error? A0 is FD */
|
||
{ printf("WARNING - FILE CORRUPTED!\nBuffers affected:\n");
|
||
for(b = buf_head; b; b = b->b_next)
|
||
{ if(sb_fdinp((SBBUF *)b, a0))
|
||
printf((b->b_fn ? " %s: %s\n" : " %s\n"),
|
||
b->b_name, b->b_fn);
|
||
}
|
||
if (oldttystate > 0) set_tty();
|
||
return(1); /* Try to continue normally */
|
||
}
|
||
printf("%sERR: %o ", (type ? "SBX" : "SBM"), adr);
|
||
printf(str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
|
||
askerr();
|
||
}
|
||
|
||
/*
|
||
* Bite_bag -- Try to save our rear ends after a catastrophe.
|
||
* This routine is mainly called from "interrupt"
|
||
* level when a memory fault or bus error occurs.
|
||
* We try to save the buffer to the file "ELLE.crash"
|
||
* in the current working directory. If it loses, well
|
||
* then you have really lost. Note: this routine does
|
||
* not reset the appropriate signal handler, so it is
|
||
* never re-entered. If a fault repeats once in this
|
||
* code, then the world dies.
|
||
*/
|
||
|
||
bite_bag(fault) /* We come here on any memory error */
|
||
int fault;
|
||
{
|
||
int ostate;
|
||
/* Some systems, such as BSD4.x and SUN, do not reset caught signals
|
||
* to SIG_DFL.
|
||
* This is a win, but isn't what vanilla UNIX code expects.
|
||
* Since it doesn't hurt to do it explicitly, we always turn it off
|
||
* explicitly...
|
||
*/
|
||
signal(fault, SIG_DFL); /* Reinstate default handling */
|
||
|
||
ostate = clean_exit(); /* Fix up the terminal modes first! */
|
||
printf("ELLE stopped by fatal interrupt (%d)!\n\
|
||
Type S or W to try saving your work.\n",fault);
|
||
askerr();
|
||
if(ostate > 0) set_tty();
|
||
signal(fault, bite_bag); /* If continued, re-enable signal */
|
||
}
|
||
|
||
/* HUP_EXIT - Called by a SIGHUP hangup signal.
|
||
* Tries to save all modified buffers before exiting.
|
||
* Note that the TTY is not touched at all, although the terminal mode
|
||
* flag is set just in case further error handling routines are invoked.
|
||
*/
|
||
hup_exit()
|
||
{ extern int trm_mode; /* See e_disp.c */
|
||
|
||
trm_mode = -1; /* Say TTY is now detached */
|
||
saveworld((struct buffer *)0, 0); /* Save world, w/o feedback */
|
||
exit(1);
|
||
}
|
||
|
||
errint() /* Routine provided for ADB jumps */
|
||
{ askerr();
|
||
}
|
||
char askh1[] = "\
|
||
A - Abort process\n\
|
||
B - Breakpoint (must have \"bpt:b\" set in ADB)\n\
|
||
C - Continue\n\
|
||
D - Diagnostic command mode\n";
|
||
char askh2[] = "\
|
||
S - Try to save current buffer\n\
|
||
W - Try to save world (all modified buffers)\n";
|
||
|
||
int bsaving = 0; /* Set while in middle of saving buffer(s) */
|
||
|
||
askerr()
|
||
{ register struct buffer *b;
|
||
char linbuf[100];
|
||
char *asklin();
|
||
extern int (*funtab[])(); /* In E_CMDS.C */
|
||
int ostate;
|
||
|
||
ostate = clean_exit(); /* Clean up TTY if not already done */
|
||
reask:
|
||
printf("(A,B,C,D,S,W,?)");
|
||
switch(upcase(*asklin(linbuf)))
|
||
{
|
||
case '?':
|
||
writez(1,askh1); /* Too long for &$@! printf */
|
||
writez(1,askh2); /* Too long for &$@! V6 C */
|
||
break; /* optimizer (/lib/c2) */
|
||
case 'A':
|
||
abort();
|
||
break;
|
||
case 'B':
|
||
bpt();
|
||
break;
|
||
case 'Q':
|
||
case 'C':
|
||
goto done;
|
||
case 'D':
|
||
if(funtab[FN_DEBUG])
|
||
(*funtab[FN_DEBUG])(-1);
|
||
else printf("Sorry, no diagnostics\n");
|
||
break;
|
||
case 'S': /* Try to save current buffer only */
|
||
b = cur_buf;
|
||
goto savb;
|
||
case 'W': /* Try to save all modified buffers */
|
||
b = 0;
|
||
savb: if(bsaving++)
|
||
{ printf("Already saving -- continued");
|
||
goto done;
|
||
}
|
||
saveworld(b, 1); /* Save, with feedback */
|
||
bsaving = 0;
|
||
break;
|
||
}
|
||
goto reask;
|
||
done:
|
||
if(ostate > 0)
|
||
set_tty();
|
||
}
|
||
|
||
char *
|
||
asklin(acp)
|
||
char *acp;
|
||
{ register char *cp;
|
||
register int c;
|
||
cp = acp;
|
||
while((c = tgetc()) != LF)
|
||
*cp++ = c;
|
||
*cp++ = 0;
|
||
return(acp);
|
||
}
|