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