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