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