home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / ASH / ASH-LINU.2 / ASH-LINU / ash-linux-0.2 / error.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-06  |  6.1 KB  |  251 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * 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.  
  37. #ifndef lint
  38. /*static char sccsid[] = "from: @(#)error.c    5.1 (Berkeley) 3/7/91";*/
  39. static char rcsid[] = "error.c,v 1.5 1993/09/05 17:32:05 mycroft Exp";
  40. #endif /* not lint */
  41.  
  42. /*
  43.  * Errors and exceptions.
  44.  */
  45.  
  46. #include "shell.h"
  47. #include "main.h"
  48. #include "options.h"
  49. #include "output.h"
  50. #include "error.h"
  51. #include <signal.h>
  52. #ifdef __STDC__
  53. #include "stdarg.h"
  54. #else
  55. #include <varargs.h>    
  56. #endif
  57. #include <errno.h>
  58.  
  59.  
  60. /*
  61.  * Code to handle exceptions in C.
  62.  */
  63.  
  64. struct jmploc *handler;
  65. int exception;
  66. volatile int suppressint;
  67. volatile int intpending;
  68. char *commandname;
  69.  
  70.  
  71. /*
  72.  * Called to raise an exception.  Since C doesn't include exceptions, we
  73.  * just do a longjmp to the exception handler.  The type of exception is
  74.  * stored in the global variable "exception".
  75.  */
  76.  
  77. void
  78. exraise(e) {
  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.  
  96. void
  97. onint() {
  98.     if (suppressint) {
  99.         intpending++;
  100.         return;
  101.     }
  102.     intpending = 0;
  103. #ifdef BSD
  104.     sigsetmask(0);
  105. #endif
  106.     if (rootshell && iflag)
  107.         exraise(EXINT);
  108.     else
  109.         _exit(128 + SIGINT);
  110. }
  111.  
  112.  
  113.  
  114. void
  115. error2(a, b)
  116.     char *a, *b;
  117.     {
  118.     error("%s: %s", a, b);
  119. }
  120.  
  121.  
  122. /*
  123.  * Error is called to raise the error exception.  If the first argument
  124.  * is not NULL then error prints an error message using printf style
  125.  * formatting.  It then raises the error exception.
  126.  */
  127.  
  128. #ifdef __STDC__
  129. void
  130. error(char *msg, ...) {
  131. #else
  132. void
  133. error(va_alist)
  134.     va_dcl
  135.     {
  136.     char *msg;
  137. #endif
  138.     va_list ap;
  139.  
  140.     CLEAR_PENDING_INT;
  141.     INTOFF;
  142. #ifdef __STDC__
  143.     va_start(ap, msg);
  144. #else
  145.     va_start(ap);
  146.     msg = va_arg(ap, char *);
  147. #endif
  148. #ifdef DEBUG
  149.     if (msg)
  150.         TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
  151.     else
  152.         TRACE(("error(NULL) pid=%d\n", getpid()));
  153. #endif
  154.     if (msg) {
  155.         if (commandname)
  156.             outfmt(&errout, "%s: ", commandname);
  157.         doformat(&errout, msg, ap);
  158.         out2c('\n');
  159.     }
  160.     va_end(ap);
  161.     flushall();
  162.     exraise(EXERROR);
  163. }
  164.  
  165.  
  166.  
  167. /*
  168.  * Table of error messages.
  169.  */
  170.  
  171. struct errname {
  172.     short errcode;        /* error number */
  173.     short action;        /* operation which encountered the error */
  174.     char *msg;        /* text describing the error */
  175. };
  176.  
  177.  
  178. #define ALL (E_OPEN|E_CREAT|E_EXEC)
  179.  
  180. STATIC const struct errname errormsg[] = {
  181.     EINTR, ALL,        "interrupted",
  182.     EACCES, ALL,        "permission denied",
  183.     EIO, ALL,        "I/O error",
  184.     ENOENT, E_OPEN,        "no such file",
  185.     ENOENT, E_CREAT,    "directory nonexistent",
  186.     ENOENT, E_EXEC,        "not found",
  187.     ENOTDIR, E_OPEN,    "no such file",
  188.     ENOTDIR, E_CREAT,    "directory nonexistent",
  189.     ENOTDIR, E_EXEC,    "not found",
  190.     EISDIR, ALL,        "is a directory",
  191. /*    EMFILE, ALL,        "too many open files", */
  192.     ENFILE, ALL,        "file table overflow",
  193.     ENOSPC, ALL,        "file system full",
  194. #ifdef EDQUOT
  195.     EDQUOT, ALL,        "disk quota exceeded",
  196. #endif
  197. #ifdef ENOSR
  198.     ENOSR, ALL,        "no streams resources",
  199. #endif
  200.     ENXIO, ALL,        "no such device or address",
  201.     EROFS, ALL,        "read-only file system",
  202.     ETXTBSY, ALL,        "text busy",
  203. #ifdef SYSV
  204.     EAGAIN, E_EXEC,        "not enough memory",
  205. #endif
  206.     ENOMEM, ALL,        "not enough memory",
  207. #ifdef ENOLINK
  208.     ENOLINK, ALL,        "remote access failed",
  209. #endif
  210. #ifdef EMULTIHOP
  211.     EMULTIHOP, ALL,        "remote access failed",
  212. #endif
  213. #ifdef ECOMM
  214.     ECOMM, ALL,        "remote access failed",
  215. #endif
  216. #ifdef ESTALE
  217.     ESTALE, ALL,        "remote access failed",
  218. #endif
  219. #ifdef ETIMEDOUT
  220.     ETIMEDOUT, ALL,        "remote access failed",
  221. #endif
  222. #ifdef ELOOP
  223.     ELOOP, ALL,        "symbolic link loop",
  224. #endif
  225.     E2BIG, E_EXEC,        "argument list too long",
  226. #ifdef ELIBACC
  227.     ELIBACC, E_EXEC,    "shared library missing",
  228. #endif
  229.     0, 0,            NULL
  230. };
  231.  
  232.  
  233. /*
  234.  * Return a string describing an error.  The returned string may be a
  235.  * pointer to a static buffer that will be overwritten on the next call.
  236.  * Action describes the operation that got the error.
  237.  */
  238.  
  239. char *
  240. errmsg(e, action) {
  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. }
  251.