1*36477Ssam static char Sccsid[] = "@(#)fatal.c 1.4 12/22/88";
230493Slepreau
330489Slepreau # include "../hdr/macros.h"
430489Slepreau # include "../hdr/fatal.h"
5*36477Ssam #include <sys/syscall.h>
6*36477Ssam #define syswrite(a,b,c) syscall(SYS_write,a,b,c)
730489Slepreau
830489Slepreau /*
930489Slepreau General purpose error handler.
1030489Slepreau Typically, low level subroutines which detect error conditions
1130489Slepreau (an open or create routine, for example) return the
1230489Slepreau value of calling fatal with an appropriate error message string.
1330489Slepreau E.g., return(fatal("can't do it"));
1430489Slepreau Higher level routines control the execution of fatal
1530489Slepreau via the global word Fflags.
1630489Slepreau The macros FSAVE and FRSTR in <fatal.h> can be used by higher
1730489Slepreau level subroutines to save and restore the Fflags word.
1830489Slepreau
1930489Slepreau The argument to fatal is a pointer to an error message string.
2030489Slepreau The action of this routine is driven completely from
2130489Slepreau the "Fflags" global word (see <fatal.h>).
2230489Slepreau The following discusses the interpretation of the various bits
2330489Slepreau of Fflags.
2430489Slepreau
2530489Slepreau The FTLMSG bit controls the writing of the error
2630489Slepreau message on file descriptor 2. The message is preceded
2730489Slepreau by the string "ERROR: ", unless the global character pointer
2830489Slepreau "Ffile" is non-zero, in which case the message is preceded
2930489Slepreau by the string "ERROR [<Ffile>]: ". A newline is written
3030489Slepreau after the user supplied message.
3130489Slepreau
3230489Slepreau If the FTLCLN bit is on, clean_up is called with an
3330489Slepreau argument of 0 (see clean.c).
3430489Slepreau
3530489Slepreau If the FTLFUNC bit is on, the function pointed to by the global
3630489Slepreau function pointer "Ffunc" is called with the user supplied
3730489Slepreau error message pointer as argument.
3830489Slepreau (This feature can be used to log error messages).
3930489Slepreau
4030489Slepreau The FTLACT bits determine how fatal should return.
4130489Slepreau If the FTLJMP bit is on longjmp(Fjmp) is
4236470Ssam called (Fjmp is a global vector of n words, see
4330489Slepreau setjmp, longjmp documentation).
4430489Slepreau
4530489Slepreau If the FTLEXIT bit is on the value of userexit(1) is
4630489Slepreau passed as an argument to exit(II)
4730489Slepreau (see userexit.c).
4830489Slepreau
4930489Slepreau If none of the FTLACT bits are on
5030489Slepreau (the default value for Fflags is 0), the global word
5130489Slepreau "Fvalue" (initialized to -1) is returned.
5230489Slepreau
5330489Slepreau If all fatal globals have their default values, fatal simply
5430489Slepreau returns -1.
5530489Slepreau */
5630489Slepreau
5730489Slepreau int Fcnt;
5830489Slepreau int Fflags;
5930489Slepreau char *Ffile;
6030493Slepreau int Fvalue = -1;
6130489Slepreau int (*Ffunc)();
6236470Ssam jmp_buf Fjmp;
6330489Slepreau
6430489Slepreau
fatal(msg)6530489Slepreau fatal(msg)
6630489Slepreau char *msg;
6730489Slepreau {
6830489Slepreau ++Fcnt;
6930489Slepreau if (Fflags & FTLMSG) {
7030489Slepreau syswrite(2,"ERROR",5);
7130489Slepreau if (Ffile) {
7230489Slepreau syswrite(2," [",2);
7330489Slepreau syswrite(2,Ffile,length(Ffile));
7430489Slepreau syswrite(2,"]",1);
7530489Slepreau }
7630489Slepreau syswrite(2,": ",2);
7730489Slepreau syswrite(2,msg,length(msg));
7830489Slepreau syswrite(2,"\n",1);
7930489Slepreau }
8030489Slepreau if (Fflags & FTLCLN)
8130489Slepreau clean_up(0);
8230489Slepreau if (Fflags & FTLFUNC)
8330489Slepreau (*Ffunc)(msg);
8430489Slepreau switch (Fflags & FTLACT) {
8530489Slepreau case FTLJMP:
8630489Slepreau longjmp(Fjmp, 1);
8730489Slepreau case FTLEXIT:
8830489Slepreau exit(userexit(1));
8930489Slepreau case FTLRET:
9030489Slepreau return(Fvalue);
9130489Slepreau }
9230489Slepreau }
93