1*30489Slepreau # include "../hdr/macros.h" 2*30489Slepreau # include "../hdr/fatal.h" 3*30489Slepreau SCCSID(@(#)fatal 2.2); 4*30489Slepreau 5*30489Slepreau /* 6*30489Slepreau General purpose error handler. 7*30489Slepreau Typically, low level subroutines which detect error conditions 8*30489Slepreau (an open or create routine, for example) return the 9*30489Slepreau value of calling fatal with an appropriate error message string. 10*30489Slepreau E.g., return(fatal("can't do it")); 11*30489Slepreau Higher level routines control the execution of fatal 12*30489Slepreau via the global word Fflags. 13*30489Slepreau The macros FSAVE and FRSTR in <fatal.h> can be used by higher 14*30489Slepreau level subroutines to save and restore the Fflags word. 15*30489Slepreau 16*30489Slepreau The argument to fatal is a pointer to an error message string. 17*30489Slepreau The action of this routine is driven completely from 18*30489Slepreau the "Fflags" global word (see <fatal.h>). 19*30489Slepreau The following discusses the interpretation of the various bits 20*30489Slepreau of Fflags. 21*30489Slepreau 22*30489Slepreau The FTLMSG bit controls the writing of the error 23*30489Slepreau message on file descriptor 2. The message is preceded 24*30489Slepreau by the string "ERROR: ", unless the global character pointer 25*30489Slepreau "Ffile" is non-zero, in which case the message is preceded 26*30489Slepreau by the string "ERROR [<Ffile>]: ". A newline is written 27*30489Slepreau after the user supplied message. 28*30489Slepreau 29*30489Slepreau If the FTLCLN bit is on, clean_up is called with an 30*30489Slepreau argument of 0 (see clean.c). 31*30489Slepreau 32*30489Slepreau If the FTLFUNC bit is on, the function pointed to by the global 33*30489Slepreau function pointer "Ffunc" is called with the user supplied 34*30489Slepreau error message pointer as argument. 35*30489Slepreau (This feature can be used to log error messages). 36*30489Slepreau 37*30489Slepreau The FTLACT bits determine how fatal should return. 38*30489Slepreau If the FTLJMP bit is on longjmp(Fjmp) is 39*30489Slepreau called (Fjmp is a global vector of 10 words, see 40*30489Slepreau setjmp, longjmp documentation). 41*30489Slepreau 42*30489Slepreau If the FTLEXIT bit is on the value of userexit(1) is 43*30489Slepreau passed as an argument to exit(II) 44*30489Slepreau (see userexit.c). 45*30489Slepreau 46*30489Slepreau If none of the FTLACT bits are on 47*30489Slepreau (the default value for Fflags is 0), the global word 48*30489Slepreau "Fvalue" (initialized to -1) is returned. 49*30489Slepreau 50*30489Slepreau If all fatal globals have their default values, fatal simply 51*30489Slepreau returns -1. 52*30489Slepreau */ 53*30489Slepreau 54*30489Slepreau int Fcnt; 55*30489Slepreau int Fflags; 56*30489Slepreau char *Ffile; 57*30489Slepreau int Fvalue -1; 58*30489Slepreau int (*Ffunc)(); 59*30489Slepreau int Fjmp[10]; 60*30489Slepreau 61*30489Slepreau 62*30489Slepreau fatal(msg) 63*30489Slepreau char *msg; 64*30489Slepreau { 65*30489Slepreau ++Fcnt; 66*30489Slepreau if (Fflags & FTLMSG) { 67*30489Slepreau syswrite(2,"ERROR",5); 68*30489Slepreau if (Ffile) { 69*30489Slepreau syswrite(2," [",2); 70*30489Slepreau syswrite(2,Ffile,length(Ffile)); 71*30489Slepreau syswrite(2,"]",1); 72*30489Slepreau } 73*30489Slepreau syswrite(2,": ",2); 74*30489Slepreau syswrite(2,msg,length(msg)); 75*30489Slepreau syswrite(2,"\n",1); 76*30489Slepreau } 77*30489Slepreau if (Fflags & FTLCLN) 78*30489Slepreau clean_up(0); 79*30489Slepreau if (Fflags & FTLFUNC) 80*30489Slepreau (*Ffunc)(msg); 81*30489Slepreau switch (Fflags & FTLACT) { 82*30489Slepreau case FTLJMP: 83*30489Slepreau longjmp(Fjmp, 1); 84*30489Slepreau case FTLEXIT: 85*30489Slepreau exit(userexit(1)); 86*30489Slepreau case FTLRET: 87*30489Slepreau return(Fvalue); 88*30489Slepreau } 89*30489Slepreau } 90