xref: /csrg-svn/bin/sh/error.c (revision 47110)
1*47110Sbostic /*-
2*47110Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*47110Sbostic  * All rights reserved.
4*47110Sbostic  *
5*47110Sbostic  * This code is derived from software contributed to Berkeley by
6*47110Sbostic  * Kenneth Almquist.
7*47110Sbostic  *
8*47110Sbostic  * %sccs.include.redist.c%
9*47110Sbostic  */
10*47110Sbostic 
11*47110Sbostic #ifndef lint
12*47110Sbostic static char sccsid[] = "@(#)error.c	5.1 (Berkeley) 03/07/91";
13*47110Sbostic #endif /* not lint */
14*47110Sbostic 
15*47110Sbostic /*
16*47110Sbostic  * Errors and exceptions.
17*47110Sbostic  */
18*47110Sbostic 
19*47110Sbostic #include "shell.h"
20*47110Sbostic #include "main.h"
21*47110Sbostic #include "options.h"
22*47110Sbostic #include "output.h"
23*47110Sbostic #include "error.h"
24*47110Sbostic #include <signal.h>
25*47110Sbostic #ifdef __STDC__
26*47110Sbostic #include "stdarg.h"
27*47110Sbostic #else
28*47110Sbostic #include <varargs.h>
29*47110Sbostic #endif
30*47110Sbostic #include <errno.h>
31*47110Sbostic 
32*47110Sbostic 
33*47110Sbostic /*
34*47110Sbostic  * Code to handle exceptions in C.
35*47110Sbostic  */
36*47110Sbostic 
37*47110Sbostic struct jmploc *handler;
38*47110Sbostic int exception;
39*47110Sbostic volatile int suppressint;
40*47110Sbostic volatile int intpending;
41*47110Sbostic char *commandname;
42*47110Sbostic 
43*47110Sbostic 
44*47110Sbostic /*
45*47110Sbostic  * Called to raise an exception.  Since C doesn't include exceptions, we
46*47110Sbostic  * just do a longjmp to the exception handler.  The type of exception is
47*47110Sbostic  * stored in the global variable "exception".
48*47110Sbostic  */
49*47110Sbostic 
50*47110Sbostic void
51*47110Sbostic exraise(e) {
52*47110Sbostic 	if (handler == NULL)
53*47110Sbostic 		abort();
54*47110Sbostic 	exception = e;
55*47110Sbostic 	longjmp(handler->loc, 1);
56*47110Sbostic }
57*47110Sbostic 
58*47110Sbostic 
59*47110Sbostic /*
60*47110Sbostic  * Called from trap.c when a SIGINT is received.  (If the user specifies
61*47110Sbostic  * that SIGINT is to be trapped or ignored using the trap builtin, then
62*47110Sbostic  * this routine is not called.)  Suppressint is nonzero when interrupts
63*47110Sbostic  * are held using the INTOFF macro.  The call to _exit is necessary because
64*47110Sbostic  * there is a short period after a fork before the signal handlers are
65*47110Sbostic  * set to the appropriate value for the child.  (The test for iflag is
66*47110Sbostic  * just defensive programming.)
67*47110Sbostic  */
68*47110Sbostic 
69*47110Sbostic void
70*47110Sbostic onint() {
71*47110Sbostic 	if (suppressint) {
72*47110Sbostic 		intpending++;
73*47110Sbostic 		return;
74*47110Sbostic 	}
75*47110Sbostic 	intpending = 0;
76*47110Sbostic #ifdef BSD
77*47110Sbostic 	sigsetmask(0);
78*47110Sbostic #endif
79*47110Sbostic 	if (rootshell && iflag)
80*47110Sbostic 		exraise(EXINT);
81*47110Sbostic 	else
82*47110Sbostic 		_exit(128 + SIGINT);
83*47110Sbostic }
84*47110Sbostic 
85*47110Sbostic 
86*47110Sbostic 
87*47110Sbostic void
88*47110Sbostic error2(a, b)
89*47110Sbostic 	char *a, *b;
90*47110Sbostic 	{
91*47110Sbostic 	error("%s: %s", a, b);
92*47110Sbostic }
93*47110Sbostic 
94*47110Sbostic 
95*47110Sbostic /*
96*47110Sbostic  * Error is called to raise the error exception.  If the first argument
97*47110Sbostic  * is not NULL then error prints an error message using printf style
98*47110Sbostic  * formatting.  It then raises the error exception.
99*47110Sbostic  */
100*47110Sbostic 
101*47110Sbostic #ifdef __STDC__
102*47110Sbostic void
103*47110Sbostic error(char *msg, ...) {
104*47110Sbostic #else
105*47110Sbostic void
106*47110Sbostic error(va_alist)
107*47110Sbostic 	va_dcl
108*47110Sbostic 	{
109*47110Sbostic 	char *msg;
110*47110Sbostic #endif
111*47110Sbostic 	va_list ap;
112*47110Sbostic 
113*47110Sbostic 	CLEAR_PENDING_INT;
114*47110Sbostic 	INTOFF;
115*47110Sbostic #ifdef __STDC__
116*47110Sbostic 	va_start(ap, msg);
117*47110Sbostic #else
118*47110Sbostic 	va_start(ap);
119*47110Sbostic 	msg = va_arg(ap, char *);
120*47110Sbostic #endif
121*47110Sbostic #ifdef DEBUG
122*47110Sbostic 	if (msg)
123*47110Sbostic 		TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
124*47110Sbostic 	else
125*47110Sbostic 		TRACE(("error(NULL) pid=%d\n", getpid()));
126*47110Sbostic #endif
127*47110Sbostic 	if (msg) {
128*47110Sbostic 		if (commandname)
129*47110Sbostic 			outfmt(&errout, "%s: ", commandname);
130*47110Sbostic 		doformat(&errout, msg, ap);
131*47110Sbostic 		out2c('\n');
132*47110Sbostic 	}
133*47110Sbostic 	va_end(ap);
134*47110Sbostic 	flushall();
135*47110Sbostic 	exraise(EXERROR);
136*47110Sbostic }
137*47110Sbostic 
138*47110Sbostic 
139*47110Sbostic 
140*47110Sbostic /*
141*47110Sbostic  * Table of error messages.
142*47110Sbostic  */
143*47110Sbostic 
144*47110Sbostic struct errname {
145*47110Sbostic 	short errcode;		/* error number */
146*47110Sbostic 	short action;		/* operation which encountered the error */
147*47110Sbostic 	char *msg;		/* text describing the error */
148*47110Sbostic };
149*47110Sbostic 
150*47110Sbostic 
151*47110Sbostic #define ALL (E_OPEN|E_CREAT|E_EXEC)
152*47110Sbostic 
153*47110Sbostic STATIC const struct errname errormsg[] = {
154*47110Sbostic 	EINTR, ALL,	"interrupted",
155*47110Sbostic 	EACCES, ALL,	"permission denied",
156*47110Sbostic 	EIO, ALL,		"I/O error",
157*47110Sbostic 	ENOENT, E_OPEN,	"no such file",
158*47110Sbostic 	ENOENT, E_CREAT,	"directory nonexistent",
159*47110Sbostic 	ENOENT, E_EXEC,	"not found",
160*47110Sbostic 	ENOTDIR, E_OPEN,	"no such file",
161*47110Sbostic 	ENOTDIR, E_CREAT,	"directory nonexistent",
162*47110Sbostic 	ENOTDIR, E_EXEC,	"not found",
163*47110Sbostic 	EISDIR, ALL,	"is a directory",
164*47110Sbostic /*    EMFILE, ALL,	"too many open files", */
165*47110Sbostic 	ENFILE, ALL,	"file table overflow",
166*47110Sbostic 	ENOSPC, ALL,	"file system full",
167*47110Sbostic #ifdef EDQUOT
168*47110Sbostic 	EDQUOT, ALL,	"disk quota exceeded",
169*47110Sbostic #endif
170*47110Sbostic #ifdef ENOSR
171*47110Sbostic 	ENOSR, ALL,	"no streams resources",
172*47110Sbostic #endif
173*47110Sbostic 	ENXIO, ALL,	"no such device or address",
174*47110Sbostic 	EROFS, ALL,	"read-only file system",
175*47110Sbostic 	ETXTBSY, ALL,	"text busy",
176*47110Sbostic #ifdef SYSV
177*47110Sbostic 	EAGAIN, E_EXEC,	"not enough memory",
178*47110Sbostic #endif
179*47110Sbostic 	ENOMEM, ALL,	"not enough memory",
180*47110Sbostic #ifdef ENOLINK
181*47110Sbostic 	ENOLINK, ALL,	"remote access failed"
182*47110Sbostic #endif
183*47110Sbostic #ifdef EMULTIHOP
184*47110Sbostic 	EMULTIHOP, ALL,	"remote access failed",
185*47110Sbostic #endif
186*47110Sbostic #ifdef ECOMM
187*47110Sbostic 	ECOMM, ALL,	"remote access failed",
188*47110Sbostic #endif
189*47110Sbostic #ifdef ESTALE
190*47110Sbostic 	ESTALE, ALL,	"remote access failed",
191*47110Sbostic #endif
192*47110Sbostic #ifdef ETIMEDOUT
193*47110Sbostic 	ETIMEDOUT, ALL,	"remote access failed",
194*47110Sbostic #endif
195*47110Sbostic #ifdef ELOOP
196*47110Sbostic 	ELOOP, ALL,	"symbolic link loop",
197*47110Sbostic #endif
198*47110Sbostic 	E2BIG, E_EXEC,	"argument list too long",
199*47110Sbostic #ifdef ELIBACC
200*47110Sbostic 	ELIBACC, E_EXEC,	"shared library missing",
201*47110Sbostic #endif
202*47110Sbostic 	0, 0,		NULL
203*47110Sbostic };
204*47110Sbostic 
205*47110Sbostic 
206*47110Sbostic /*
207*47110Sbostic  * Return a string describing an error.  The returned string may be a
208*47110Sbostic  * pointer to a static buffer that will be overwritten on the next call.
209*47110Sbostic  * Action describes the operation that got the error.
210*47110Sbostic  */
211*47110Sbostic 
212*47110Sbostic char *
213*47110Sbostic errmsg(e, action) {
214*47110Sbostic 	struct errname const *ep;
215*47110Sbostic 	static char buf[12];
216*47110Sbostic 
217*47110Sbostic 	for (ep = errormsg ; ep->errcode ; ep++) {
218*47110Sbostic 		if (ep->errcode == e && (ep->action & action) != 0)
219*47110Sbostic 			return ep->msg;
220*47110Sbostic 	}
221*47110Sbostic 	fmtstr(buf, sizeof buf, "error %d", e);
222*47110Sbostic 	return buf;
223*47110Sbostic }
224