error.c

Go to the documentation of this file.
00001 /*-
00002  * Copyright (c) 1991 The Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * This code is derived from software contributed to Berkeley by
00006  * Kenneth Almquist.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  * 3. All advertising materials mentioning features or use of this software
00017  *    must display the following acknowledgement:
00018  *      This product includes software developed by the University of
00019  *      California, Berkeley and its contributors.
00020  * 4. Neither the name of the University nor the names of its contributors
00021  *    may be used to endorse or promote products derived from this software
00022  *    without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00025  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00027  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00028  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00030  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00031  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00033  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00034  * SUCH DAMAGE.
00035  */
00036 
00037 #ifndef lint
00038 static char sccsid[] = "@(#)error.c     5.1 (Berkeley) 3/7/91";
00039 #endif /* not lint */
00040 
00041 /*
00042  * Errors and exceptions.
00043  */
00044 
00045 #include "shell.h"
00046 #include "main.h"
00047 #include "options.h"
00048 #include "output.h"
00049 #include "error.h"
00050 #include <sys/types.h>
00051 #include <signal.h>
00052 #ifdef __STDC__
00053 #include "stdarg.h"
00054 #else
00055 #include <varargs.h>    
00056 #endif
00057 #include <errno.h>
00058 
00059 
00060 /*
00061  * Code to handle exceptions in C.
00062  */
00063 
00064 struct jmploc *handler;
00065 int exception;
00066 volatile int suppressint;
00067 volatile int intpending;
00068 char *commandname;
00069 
00070 
00071 /*
00072  * Called to raise an exception.  Since C doesn't include exceptions, we
00073  * just do a longjmp to the exception handler.  The type of exception is
00074  * stored in the global variable "exception".
00075  */
00076 
00077 void
00078 exraise(e) {
00079         if (handler == NULL)
00080                 abort();
00081         exception = e;
00082         longjmp(handler->loc, 1);
00083 }
00084 
00085 
00086 /*
00087  * Called from trap.c when a SIGINT is received.  (If the user specifies
00088  * that SIGINT is to be trapped or ignored using the trap builtin, then
00089  * this routine is not called.)  Suppressint is nonzero when interrupts
00090  * are held using the INTOFF macro.  The call to _exit is necessary because
00091  * there is a short period after a fork before the signal handlers are
00092  * set to the appropriate value for the child.  (The test for iflag is
00093  * just defensive programming.)
00094  */
00095 
00096 void
00097 onint() {
00098         if (suppressint) {
00099                 intpending++;
00100                 return;
00101         }
00102         intpending = 0;
00103 #ifdef BSD
00104         sigsetmask(0);
00105 #endif
00106         if (rootshell && iflag)
00107                 exraise(EXINT);
00108         else
00109                 _exit(128 + SIGINT);
00110 }
00111 
00112 
00113 
00114 void
00115 error2(a, b)
00116         char *a, *b;
00117         {
00118         error("%s: %s", a, b);
00119 }
00120 
00121 
00122 /*
00123  * Error is called to raise the error exception.  If the first argument
00124  * is not NULL then error prints an error message using printf style
00125  * formatting.  It then raises the error exception.
00126  */
00127 
00128 #ifdef __STDC__
00129 void
00130 error(char *msg, ...) {
00131 #else
00132 void
00133 error(va_alist)
00134         va_dcl
00135         {
00136         char *msg;
00137 #endif
00138         va_list ap;
00139 
00140         CLEAR_PENDING_INT;
00141         INTOFF;
00142 #ifdef __STDC__
00143         va_start(ap, msg);
00144 #else
00145         va_start(ap);
00146         msg = va_arg(ap, char *);
00147 #endif
00148 #if DEBUG
00149         if (msg)
00150                 TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
00151         else
00152                 TRACE(("error(NULL) pid=%d\n", getpid()));
00153 #endif
00154         if (msg) {
00155                 if (commandname)
00156                         outfmt(&errout, "%s: ", commandname);
00157                 doformat(&errout, msg, ap);
00158                 out2c('\n');
00159         }
00160         va_end(ap);
00161         flushall();
00162         exraise(EXERROR);
00163 }
00164 
00165 
00166 #ifdef notdef   /* These strange error messages only confuse. -- kjb */
00167 /*
00168  * Table of error messages.
00169  */
00170 
00171 struct errname {
00172         short errcode;          /* error number */
00173         short action;           /* operation which encountered the error */
00174         char *msg;              /* text describing the error */
00175 };
00176 
00177 
00178 #define ALL (E_OPEN|E_CREAT|E_EXEC)
00179 
00180 STATIC const struct errname errormsg[] = {
00181         EINTR, ALL,     "interrupted",
00182         EACCES, ALL,    "permission denied",
00183         EIO, ALL,               "I/O error",
00184         ENOENT, E_OPEN, "no such file",
00185         ENOENT, E_CREAT,        "directory nonexistent",
00186         ENOENT, E_EXEC, "not found",
00187         ENOTDIR, E_OPEN,        "no such file",
00188         ENOTDIR, E_CREAT,       "directory nonexistent",
00189         ENOTDIR, E_EXEC,        "not found",
00190         ENOEXEC, ALL,   "not an executable",
00191         EISDIR, ALL,    "is a directory",
00192 /*    EMFILE, ALL,      "too many open files", */
00193         ENFILE, ALL,    "file table overflow",
00194         ENOSPC, ALL,    "file system full",
00195 #ifdef EDQUOT
00196         EDQUOT, ALL,    "disk quota exceeded",
00197 #endif
00198 #ifdef ENOSR
00199         ENOSR, ALL,     "no streams resources",
00200 #endif
00201         ENXIO, ALL,     "no such device or address",
00202         EROFS, ALL,     "read-only file system",
00203         ETXTBSY, ALL,   "text busy",
00204 #ifdef SYSV
00205         EAGAIN, E_EXEC, "not enough memory",
00206 #endif
00207         ENOMEM, ALL,    "not enough memory",
00208 #ifdef ENOLINK
00209         ENOLINK, ALL,   "remote access failed",
00210 #endif
00211 #ifdef EMULTIHOP
00212         EMULTIHOP, ALL, "remote access failed",
00213 #endif
00214 #ifdef ECOMM
00215         ECOMM, ALL,     "remote access failed",
00216 #endif
00217 #ifdef ESTALE
00218         ESTALE, ALL,    "remote access failed",
00219 #endif
00220 #ifdef ETIMEDOUT
00221         ETIMEDOUT, ALL, "remote access failed",
00222 #endif
00223 #ifdef ELOOP
00224         ELOOP, ALL,     "symbolic link loop",
00225 #endif
00226         E2BIG, E_EXEC,  "argument list too long",
00227 #ifdef ELIBACC
00228         ELIBACC, E_EXEC,        "shared library missing",
00229 #endif
00230         0, 0,           NULL
00231 };
00232 
00233 
00234 /*
00235  * Return a string describing an error.  The returned string may be a
00236  * pointer to a static buffer that will be overwritten on the next call.
00237  * Action describes the operation that got the error.
00238  */
00239 
00240 char *
00241 errmsg(e, action) {
00242         const struct errname *ep;
00243         static char buf[12];
00244 
00245         for (ep = errormsg ; ep->errcode ; ep++) {
00246                 if (ep->errcode == e && (ep->action & action) != 0)
00247                         return ep->msg;
00248         }
00249         fmtstr(buf, sizeof buf, "error %d", e);
00250         return buf;
00251 }
00252 #endif

Generated on Fri Apr 14 22:56:39 2006 for minix by  doxygen 1.4.6