xref: /csrg-svn/local/toolchest/ksh/sh/error.c (revision 35140)
1*35140Smarc /*
2*35140Smarc 
3*35140Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35140Smarc  *      All Rights Reserved
5*35140Smarc 
6*35140Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35140Smarc  *      CODE OF AT&T.
8*35140Smarc  *      The copyright notice above does not
9*35140Smarc  *      evidence any actual or intended
10*35140Smarc  *      publication of such source code.
11*35140Smarc 
12*35140Smarc  */
13*35140Smarc /* @(#)error.c	1.1 */
14*35140Smarc /*
15*35140Smarc  * UNIX shell
16*35140Smarc  *
17*35140Smarc  * S. R. Bourne
18*35140Smarc  * Rewritten by David Korn
19*35140Smarc  * AT&T Bell Laboratories
20*35140Smarc  *
21*35140Smarc  */
22*35140Smarc 
23*35140Smarc #include	"flags.h"
24*35140Smarc #include	"defs.h"
25*35140Smarc #include	"io.h"
26*35140Smarc #include	"brkincr.h"
27*35140Smarc #include	"jobs.h"
28*35140Smarc #include	"sym.h"
29*35140Smarc 
30*35140Smarc /* These routines are defined by this module */
31*35140Smarc void	exitsh();
32*35140Smarc void	done();
33*35140Smarc void	failed();
34*35140Smarc void	rmtemp();
35*35140Smarc 
36*35140Smarc /* These routines are used by this module but defined elsewhere */
37*35140Smarc extern void	arg_clear();
38*35140Smarc extern void	chktrap();
39*35140Smarc extern void	free();
40*35140Smarc extern void	hist_flush();
41*35140Smarc extern char	*movstr();
42*35140Smarc extern void	name_unscope();
43*35140Smarc extern void	p_flush();
44*35140Smarc extern void	p_prp();
45*35140Smarc extern void	p_setout();
46*35140Smarc extern void	p_str();
47*35140Smarc extern void	restore();
48*35140Smarc extern void	rm_files();
49*35140Smarc extern void	setcooked();
50*35140Smarc #ifdef VFORK
51*35140Smarc extern void	vfork_restore();
52*35140Smarc #endif	/* VFORK */
53*35140Smarc 
54*35140Smarc /* ========	error handling	======== */
55*35140Smarc 
56*35140Smarc 	/* Find out if it is time to go away.
57*35140Smarc 	 * `trapnote' is set to SIGSET when fault is seen and
58*35140Smarc 	 * no trap has been set.
59*35140Smarc 	 */
60*35140Smarc 
61*35140Smarc /*
62*35140Smarc  *  This routine is called when fatal errors are encountered
63*35140Smarc  *  A message is printed out and the shell tries to exit
64*35140Smarc  */
65*35140Smarc 
failed(s1,s2)66*35140Smarc void failed(s1,s2)
67*35140Smarc register char *s1,*s2;
68*35140Smarc {
69*35140Smarc 	p_setout(stderr);
70*35140Smarc 	p_prp(s1,s2?':':NL);
71*35140Smarc 	if(s2)
72*35140Smarc 	{
73*35140Smarc 		putc(SP,output);
74*35140Smarc 		p_str(s2,NL);
75*35140Smarc 	}
76*35140Smarc 	exitsh(ERROR);
77*35140Smarc }
78*35140Smarc 
79*35140Smarc /* Arrive here from `FATAL' errors
80*35140Smarc  *  a) exit command,
81*35140Smarc  *  b) default trap,
82*35140Smarc  *  c) fault with no trap set.
83*35140Smarc  *
84*35140Smarc  * Action is to return to command level or exit.
85*35140Smarc  */
86*35140Smarc 
exitsh(xno)87*35140Smarc void exitsh(xno)
88*35140Smarc int xno;
89*35140Smarc {
90*35140Smarc 	register unsigned state=(states&~(ERRFLG|MONITOR));
91*35140Smarc 	exitval=xno;
92*35140Smarc 	if(state&BUILTIN)
93*35140Smarc 		longjmp(*freturn,1);
94*35140Smarc 	state |= is_option(ERRFLG|MONITOR);
95*35140Smarc 	if((state&(ERRFLG|FORKED|TTYFLG)) != TTYFLG)
96*35140Smarc 	{
97*35140Smarc 		states = state;
98*35140Smarc 		done(0);
99*35140Smarc 	}
100*35140Smarc 	else
101*35140Smarc 	{
102*35140Smarc 		if((state&FUNCTION)==0)
103*35140Smarc 		{
104*35140Smarc 			p_flush();
105*35140Smarc 			/* flush out input buffer */
106*35140Smarc 			setbuf(input,input->_base);
107*35140Smarc 			name_unscope();
108*35140Smarc 			arg_clear();
109*35140Smarc 			restore(0);
110*35140Smarc 		}
111*35140Smarc #ifdef VFORK
112*35140Smarc 		vfork_restore();
113*35140Smarc #endif	/* VFORK */
114*35140Smarc 		execbrk = breakcnt = 0;
115*35140Smarc 		aliflg = 0;
116*35140Smarc 		exec_flag = 0;
117*35140Smarc 		hist_flush();
118*35140Smarc #ifdef JOBS
119*35140Smarc 		state &= ~(FUNCTION|FIXFLG|NONSTOP|READC|RWAIT|PROMPT|READPR|MONITOR|BUILTIN|VFORKED);
120*35140Smarc 		state |= is_option(INTFLG|READPR|MONITOR);
121*35140Smarc 		jobstat.j_flag = 0;
122*35140Smarc #else
123*35140Smarc 		state &= ~(FUNCTION|FIXFLG|RWAIT|PROMPT|READPR|BUILTIN);
124*35140Smarc 		state |= is_option(INTFLG|READPR);
125*35140Smarc #endif	/* JOBS */
126*35140Smarc 		states = state;
127*35140Smarc 		longjmp(*freturn,1);
128*35140Smarc 	}
129*35140Smarc }
130*35140Smarc 
131*35140Smarc /*
132*35140Smarc  * This is the exit routine for the shell
133*35140Smarc  */
134*35140Smarc 
done(sig)135*35140Smarc void done(sig)
136*35140Smarc register int sig;
137*35140Smarc {
138*35140Smarc 	register char *t;
139*35140Smarc 	register int savxit = exitval;
140*35140Smarc 	if(t=trapcom[0])
141*35140Smarc 	{
142*35140Smarc 		trapcom[0]=0; /*should free but not long */
143*35140Smarc 		execexp(t,(FILE*)0);
144*35140Smarc 	}
145*35140Smarc 	else
146*35140Smarc 	{
147*35140Smarc 		/* avoid recursive call for set -e */
148*35140Smarc 		states &= ~ERRFLG;
149*35140Smarc 		chktrap();
150*35140Smarc 	}
151*35140Smarc 	rmtemp((IOPTR)0);
152*35140Smarc #ifdef ACCT
153*35140Smarc 	doacct();
154*35140Smarc #endif	/* ACCT */
155*35140Smarc #if VSH || ESH
156*35140Smarc 	if(is_option(EMACS|EDITVI|GMACS) && standin->fstak==0)
157*35140Smarc 		setcooked(fileno(input));
158*35140Smarc #endif
159*35140Smarc 	if(states&RM_TMP)
160*35140Smarc 	/* clean up all temp files */
161*35140Smarc 		rm_files(tmpout);
162*35140Smarc 	p_flush();
163*35140Smarc #ifdef JOBS
164*35140Smarc 	if(sig==SIGHUP || (is_option(INTFLG)&&(getppid()==1)))
165*35140Smarc 		kill_all();
166*35140Smarc #endif	/* JOBS */
167*35140Smarc 	if(sig)
168*35140Smarc 	{
169*35140Smarc 		/* generate fault termination code */
170*35140Smarc 		signal(sig,SIG_DFL);
171*35140Smarc #ifdef BSD_4_2
172*35140Smarc 		sigrelse(sig);
173*35140Smarc #endif	/* BSD_4_2 */
174*35140Smarc 		kill(getpid(),sig);
175*35140Smarc 		pause();
176*35140Smarc 	}
177*35140Smarc 	exit(savxit);
178*35140Smarc }
179*35140Smarc 
180*35140Smarc /*
181*35140Smarc  * remove temporary files
182*35140Smarc  */
183*35140Smarc 
rmtemp(base)184*35140Smarc void	rmtemp(base)
185*35140Smarc IOPTR 	base;
186*35140Smarc {
187*35140Smarc 	register IOPTR iop = iotemp;
188*35140Smarc 	while(iop>base)
189*35140Smarc 	{
190*35140Smarc 		unlink(iop->ioname);
191*35140Smarc 		free(iop->iolink);
192*35140Smarc 		iop=iop->iolst;
193*35140Smarc 	}
194*35140Smarc 	iotemp = iop;
195*35140Smarc }
196