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