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