Annotation of src/bin/sh/error.c, Revision 1.19
1.19 ! mycroft 1: /* $NetBSD: error.c,v 1.18 1998/01/31 12:36:16 christos Exp $ */
1.11 cgd 2:
1.1 cgd 3: /*-
1.6 jtc 4: * Copyright (c) 1991, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * This code is derived from software contributed to Berkeley by
8: * Kenneth Almquist.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
1.17 christos 39: #include <sys/cdefs.h>
1.1 cgd 40: #ifndef lint
1.11 cgd 41: #if 0
1.14 christos 42: static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95";
1.11 cgd 43: #else
1.19 ! mycroft 44: __RCSID("$NetBSD: error.c,v 1.18 1998/01/31 12:36:16 christos Exp $");
1.11 cgd 45: #endif
1.1 cgd 46: #endif /* not lint */
47:
48: /*
49: * Errors and exceptions.
50: */
51:
1.18 christos 52: #include <signal.h>
53: #include <unistd.h>
54: #include <errno.h>
55:
1.1 cgd 56: #include "shell.h"
57: #include "main.h"
58: #include "options.h"
59: #include "output.h"
60: #include "error.h"
1.14 christos 61: #include "show.h"
1.1 cgd 62:
63:
64: /*
65: * Code to handle exceptions in C.
66: */
67:
68: struct jmploc *handler;
69: int exception;
70: volatile int suppressint;
71: volatile int intpending;
72: char *commandname;
73:
74:
1.17 christos 75: static void exverror __P((int, char *, va_list)) __attribute__((__noreturn__));
1.15 christos 76:
1.1 cgd 77: /*
78: * Called to raise an exception. Since C doesn't include exceptions, we
79: * just do a longjmp to the exception handler. The type of exception is
80: * stored in the global variable "exception".
81: */
82:
83: void
1.15 christos 84: exraise(e)
1.9 cgd 85: int e;
86: {
1.1 cgd 87: if (handler == NULL)
88: abort();
89: exception = e;
90: longjmp(handler->loc, 1);
91: }
92:
93:
94: /*
95: * Called from trap.c when a SIGINT is received. (If the user specifies
96: * that SIGINT is to be trapped or ignored using the trap builtin, then
97: * this routine is not called.) Suppressint is nonzero when interrupts
98: * are held using the INTOFF macro. The call to _exit is necessary because
99: * there is a short period after a fork before the signal handlers are
100: * set to the appropriate value for the child. (The test for iflag is
101: * just defensive programming.)
102: */
103:
104: void
105: onint() {
1.13 mycroft 106: sigset_t sigset;
1.12 mycroft 107:
1.1 cgd 108: if (suppressint) {
109: intpending++;
110: return;
111: }
112: intpending = 0;
1.13 mycroft 113: sigemptyset(&sigset);
114: sigprocmask(SIG_SETMASK, &sigset, NULL);
1.1 cgd 115: if (rootshell && iflag)
116: exraise(EXINT);
117: else
118: _exit(128 + SIGINT);
1.19 ! mycroft 119: /* NOTREACHED */
1.1 cgd 120: }
121:
122:
123: /*
1.15 christos 124: * Exverror is called to raise the error exception. If the first argument
1.1 cgd 125: * is not NULL then error prints an error message using printf style
126: * formatting. It then raises the error exception.
127: */
1.15 christos 128: static void
129: exverror(cond, msg, ap)
130: int cond;
131: char *msg;
132: va_list ap;
133: {
134: CLEAR_PENDING_INT;
135: INTOFF;
136:
137: #ifdef DEBUG
138: if (msg)
139: TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
140: else
141: TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
142: #endif
143: if (msg) {
144: if (commandname)
145: outfmt(&errout, "%s: ", commandname);
146: doformat(&errout, msg, ap);
147: out2c('\n');
148: }
149: flushall();
150: exraise(cond);
1.19 ! mycroft 151: /* NOTREACHED */
1.15 christos 152: }
153:
1.1 cgd 154:
1.16 christos 155: #ifdef __STDC__
1.1 cgd 156: void
1.14 christos 157: error(char *msg, ...)
1.1 cgd 158: #else
159: void
160: error(va_alist)
161: va_dcl
1.14 christos 162: #endif
163: {
1.16 christos 164: #ifndef __STDC__
1.1 cgd 165: char *msg;
166: #endif
167: va_list ap;
1.16 christos 168: #ifdef __STDC__
1.15 christos 169: va_start(ap, msg);
170: #else
171: va_start(ap);
172: msg = va_arg(ap, char *);
173: #endif
174: exverror(EXERROR, msg, ap);
175: va_end(ap);
176: }
177:
1.14 christos 178:
1.16 christos 179: #ifdef __STDC__
1.15 christos 180: void
181: exerror(int cond, char *msg, ...)
182: #else
183: void
184: exerror(va_alist)
185: va_dcl
186: #endif
187: {
1.16 christos 188: #ifndef __STDC__
1.15 christos 189: int cond;
190: char *msg;
191: #endif
192: va_list ap;
1.16 christos 193: #ifdef __STDC__
1.1 cgd 194: va_start(ap, msg);
195: #else
196: va_start(ap);
1.15 christos 197: cond = va_arg(ap, int);
1.1 cgd 198: msg = va_arg(ap, char *);
199: #endif
1.15 christos 200: exverror(cond, msg, ap);
1.1 cgd 201: va_end(ap);
202: }
203:
204:
205:
206: /*
207: * Table of error messages.
208: */
209:
210: struct errname {
211: short errcode; /* error number */
212: short action; /* operation which encountered the error */
213: char *msg; /* text describing the error */
214: };
215:
216:
217: #define ALL (E_OPEN|E_CREAT|E_EXEC)
218:
219: STATIC const struct errname errormsg[] = {
1.14 christos 220: { EINTR, ALL, "interrupted" },
221: { EACCES, ALL, "permission denied" },
222: { EIO, ALL, "I/O error" },
223: { ENOENT, E_OPEN, "no such file" },
224: { ENOENT, E_CREAT,"directory nonexistent" },
225: { ENOENT, E_EXEC, "not found" },
226: { ENOTDIR, E_OPEN, "no such file" },
227: { ENOTDIR, E_CREAT,"directory nonexistent" },
228: { ENOTDIR, E_EXEC, "not found" },
229: { EISDIR, ALL, "is a directory" },
230: #ifdef notdef
231: { EMFILE, ALL, "too many open files" },
232: #endif
233: { ENFILE, ALL, "file table overflow" },
234: { ENOSPC, ALL, "file system full" },
1.1 cgd 235: #ifdef EDQUOT
1.14 christos 236: { EDQUOT, ALL, "disk quota exceeded" },
1.1 cgd 237: #endif
238: #ifdef ENOSR
1.14 christos 239: { ENOSR, ALL, "no streams resources" },
1.1 cgd 240: #endif
1.14 christos 241: { ENXIO, ALL, "no such device or address" },
242: { EROFS, ALL, "read-only file system" },
243: { ETXTBSY, ALL, "text busy" },
1.1 cgd 244: #ifdef SYSV
1.14 christos 245: { EAGAIN, E_EXEC, "not enough memory" },
1.1 cgd 246: #endif
1.14 christos 247: { ENOMEM, ALL, "not enough memory" },
1.1 cgd 248: #ifdef ENOLINK
1.14 christos 249: { ENOLINK, ALL, "remote access failed" },
1.1 cgd 250: #endif
251: #ifdef EMULTIHOP
1.14 christos 252: { EMULTIHOP, ALL, "remote access failed" },
1.1 cgd 253: #endif
254: #ifdef ECOMM
1.14 christos 255: { ECOMM, ALL, "remote access failed" },
1.1 cgd 256: #endif
257: #ifdef ESTALE
1.14 christos 258: { ESTALE, ALL, "remote access failed" },
1.1 cgd 259: #endif
260: #ifdef ETIMEDOUT
1.14 christos 261: { ETIMEDOUT, ALL, "remote access failed" },
1.1 cgd 262: #endif
263: #ifdef ELOOP
1.14 christos 264: { ELOOP, ALL, "symbolic link loop" },
1.1 cgd 265: #endif
1.14 christos 266: { E2BIG, E_EXEC, "argument list too long" },
1.1 cgd 267: #ifdef ELIBACC
1.14 christos 268: { ELIBACC, E_EXEC, "shared library missing" },
1.1 cgd 269: #endif
1.14 christos 270: { 0, 0, NULL },
1.1 cgd 271: };
272:
273:
274: /*
275: * Return a string describing an error. The returned string may be a
276: * pointer to a static buffer that will be overwritten on the next call.
277: * Action describes the operation that got the error.
278: */
279:
280: char *
1.15 christos 281: errmsg(e, action)
1.10 cgd 282: int e;
283: int action;
284: {
1.1 cgd 285: struct errname const *ep;
286: static char buf[12];
287:
288: for (ep = errormsg ; ep->errcode ; ep++) {
289: if (ep->errcode == e && (ep->action & action) != 0)
290: return ep->msg;
291: }
292: fmtstr(buf, sizeof buf, "error %d", e);
293: return buf;
294: }
CVSweb <webmaster@jp.NetBSD.org>