147823Sbostic /*- 247823Sbostic * Copyright (c) 1980, 1991 The Regents of the University of California. 347823Sbostic * All rights reserved. 447823Sbostic * 547823Sbostic * %sccs.include.redist.c% 621929Sdist */ 721929Sdist 817510Sedward #ifndef lint 9*50439Schristos static char sccsid[] = "@(#)err.c 5.11 (Berkeley) 07/19/91"; 1047823Sbostic #endif /* not lint */ 111291Sbill 1250028Sbostic #include <sys/types.h> 1350028Sbostic #include <stdlib.h> 1450028Sbostic #include <unistd.h> 1550023Sbostic #if __STDC__ 1650033Schristos # include <stdarg.h> 1750023Sbostic #else 1850033Schristos # include <varargs.h> 1950023Sbostic #endif 201291Sbill 2150033Schristos #include "csh.h" 2250033Schristos #include "extern.h" 2350033Schristos 2450023Sbostic char *seterr = NULL; /* Holds last error if there was one */ 2549992Sbostic 2649992Sbostic #define ERR_FLAGS 0xf0000000 2749992Sbostic #define ERR_NAME 0x10000000 2849992Sbostic #define ERR_SILENT 0x20000000 2949992Sbostic #define ERR_OLD 0x40000000 3049992Sbostic 3149992Sbostic static char *errorlist[] = 3249992Sbostic { 3349992Sbostic #define ERR_SYNTAX 0 3449992Sbostic "Syntax Error", 3549992Sbostic #define ERR_NOTALLOWED 1 3649992Sbostic "%s is not allowed", 3749992Sbostic #define ERR_WTOOLONG 2 3849992Sbostic "Word too long", 3949992Sbostic #define ERR_LTOOLONG 3 4049992Sbostic "$< line too long", 4149992Sbostic #define ERR_DOLZERO 4 4249992Sbostic "No file for $0", 4349992Sbostic #define ERR_DOLQUEST 5 4449992Sbostic "$? not allowed here", 4549992Sbostic #define ERR_INCBR 6 4649992Sbostic "Incomplete [] modifier", 4749992Sbostic #define ERR_EXPORD 7 4849992Sbostic "$ expansion must end before ]", 4949992Sbostic #define ERR_BADMOD 8 5049992Sbostic "Bad : modifier in $ (%c)", 5149992Sbostic #define ERR_SUBSCRIPT 9 5249992Sbostic "Subscript error", 5349992Sbostic #define ERR_BADNUM 10 5449992Sbostic "Badly formed number", 5549992Sbostic #define ERR_NOMORE 11 5649992Sbostic "No more words", 5749992Sbostic #define ERR_FILENAME 12 5849992Sbostic "Missing file name", 5949992Sbostic #define ERR_GLOB 13 6049992Sbostic "Internal glob error", 6149992Sbostic #define ERR_COMMAND 14 6249992Sbostic "Command not found", 6349992Sbostic #define ERR_TOOFEW 15 6449992Sbostic "Too few arguments", 6549992Sbostic #define ERR_TOOMANY 16 6649992Sbostic "Too many arguments", 6749992Sbostic #define ERR_DANGER 17 6849992Sbostic "Too dangerous to alias that", 6949992Sbostic #define ERR_EMPTYIF 18 7049992Sbostic "Empty if", 7149992Sbostic #define ERR_IMPRTHEN 19 7249992Sbostic "Improper then", 7349992Sbostic #define ERR_NOPAREN 20 7449992Sbostic "Words not parenthesized", 7549992Sbostic #define ERR_NOTFOUND 21 7649992Sbostic "%s not found", 7749992Sbostic #define ERR_MASK 22 7849992Sbostic "Improper mask", 7949992Sbostic #define ERR_LIMIT 23 8049992Sbostic "No such limit", 8149992Sbostic #define ERR_TOOLARGE 24 8249992Sbostic "Argument too large", 8349992Sbostic #define ERR_SCALEF 25 8449992Sbostic "Improper or unknown scale factor", 8549992Sbostic #define ERR_UNDVAR 26 8649992Sbostic "Undefined variable", 8749992Sbostic #define ERR_DEEP 27 8849992Sbostic "Directory stack not that deep", 8949992Sbostic #define ERR_BADSIG 28 9049992Sbostic "Bad signal number", 9149992Sbostic #define ERR_UNKSIG 29 9249992Sbostic "Unknown signal; kill -l lists signals", 9349992Sbostic #define ERR_VARBEGIN 30 9449992Sbostic "Variable name must begin with a letter", 9549992Sbostic #define ERR_VARTOOLONG 31 9649992Sbostic "Variable name too long", 9749992Sbostic #define ERR_VARALNUM 32 9849992Sbostic "Variable name must contain alphanumeric characters", 9949992Sbostic #define ERR_JOBCONTROL 33 10049992Sbostic "No job control in this shell", 10149992Sbostic #define ERR_EXPRESSION 34 10249992Sbostic "Expression Syntax", 10349992Sbostic #define ERR_NOHOMEDIR 35 10449992Sbostic "No home directory", 10549992Sbostic #define ERR_CANTCHANGE 36 10649992Sbostic "Can't change to home directory", 10749992Sbostic #define ERR_NULLCOM 37 10849992Sbostic "Invalid null command", 10949992Sbostic #define ERR_ASSIGN 38 11049992Sbostic "Assignment missing expression", 11149992Sbostic #define ERR_UNKNOWNOP 39 11249992Sbostic "Unknown operator", 11349992Sbostic #define ERR_AMBIG 40 11449992Sbostic "Ambiguous", 11549992Sbostic #define ERR_EXISTS 41 11649992Sbostic "%s: File exists", 11749992Sbostic #define ERR_INTR 42 11849992Sbostic "Interrupted", 11949992Sbostic #define ERR_RANGE 43 12049992Sbostic "Subscript out of range", 12149992Sbostic #define ERR_OVERFLOW 44 12249992Sbostic "Line overflow", 12349992Sbostic #define ERR_VARMOD 45 12449992Sbostic "Unknown variable modifier", 12549992Sbostic #define ERR_NOSUCHJOB 46 12649992Sbostic "No such job", 12749992Sbostic #define ERR_TERMINAL 47 12849992Sbostic "Can't from terminal", 12949992Sbostic #define ERR_NOTWHILE 48 13049992Sbostic "Not in while/foreach", 13149992Sbostic #define ERR_NOPROC 49 13249992Sbostic "No more processes", 13349992Sbostic #define ERR_NOMATCH 50 13449992Sbostic "No match", 13549992Sbostic #define ERR_MISSING 51 13649992Sbostic "Missing %c", 13749992Sbostic #define ERR_UNMATCHED 52 13849992Sbostic "Unmatched %c", 13949992Sbostic #define ERR_NOMEM 53 14049992Sbostic "Out of memory", 14149992Sbostic #define ERR_PIPE 54 14249992Sbostic "Can't make pipe", 14349992Sbostic #define ERR_SYSTEM 55 14449992Sbostic "%s: %s", 14549992Sbostic #define ERR_STRING 56 14649992Sbostic "%s", 14749992Sbostic #define ERR_JOBS 57 14849992Sbostic "Usage: jobs [ -l ]", 14949992Sbostic #define ERR_JOBARGS 58 15049992Sbostic "Arguments should be jobs or process id's", 15149992Sbostic #define ERR_JOBCUR 59 15249992Sbostic "No current job", 15349992Sbostic #define ERR_JOBPREV 60 15449992Sbostic "No previous job", 15549992Sbostic #define ERR_JOBPAT 61 15649992Sbostic "No job matches pattern", 15749992Sbostic #define ERR_NESTING 62 15849992Sbostic "Fork nesting > %d; maybe `...` loop", 15949992Sbostic #define ERR_JOBCTRLSUB 63 16049992Sbostic "No job control in subshells", 16149992Sbostic #define ERR_BADPLPS 64 16249992Sbostic "Badly placed ()'s", 16349992Sbostic #define ERR_STOPPED 65 16449992Sbostic "%sThere are suspended jobs", 16549992Sbostic #define ERR_NODIR 66 16649992Sbostic "No other directory", 16749992Sbostic #define ERR_EMPTY 67 16849992Sbostic "Directory stack empty", 16949992Sbostic #define ERR_BADDIR 68 17049992Sbostic "Bad directory", 17149992Sbostic #define ERR_DIRUS 69 17249992Sbostic "Usage: %s [-lvn]%s", 17349992Sbostic #define ERR_HFLAG 70 17449992Sbostic "No operand for -h flag", 17549992Sbostic #define ERR_NOTLOGIN 71 17649992Sbostic "Not a login shell", 17749992Sbostic #define ERR_DIV0 72 17849992Sbostic "Division by 0", 17949992Sbostic #define ERR_MOD0 73 18049992Sbostic "Mod by 0", 18149992Sbostic #define ERR_BADSCALE 74 18249992Sbostic "Bad scaling; did you mean \"%s\"?", 18349992Sbostic #define ERR_SUSPLOG 75 18449992Sbostic "Can't suspend a login shell (yet)", 18549992Sbostic #define ERR_UNKUSER 76 18649992Sbostic "Unknown user: %s", 18749992Sbostic #define ERR_NOHOME 77 18849992Sbostic "No $home variable set", 18949992Sbostic #define ERR_HISTUS 78 190*50439Schristos "Usage: history [-rh] [# number of events]", 19149992Sbostic #define ERR_SPDOLLT 79 19249992Sbostic "$ or < not allowed with $# or $?", 19349992Sbostic #define ERR_NEWLINE 80 19449992Sbostic "Newline in variable name", 19549992Sbostic #define ERR_SPSTAR 81 19649992Sbostic "* not allowed with $# or $?", 19749992Sbostic #define ERR_DIGIT 82 19849992Sbostic "$?<digit> or $#<digit> not allowed", 19949992Sbostic #define ERR_VARILL 83 20049992Sbostic "Illegal variable name", 20149992Sbostic #define ERR_NLINDEX 84 20249992Sbostic "Newline in variable index", 20349992Sbostic #define ERR_EXPOVFL 85 20449992Sbostic "Expansion buffer overflow", 20549992Sbostic #define ERR_VARSYN 86 20649992Sbostic "Variable syntax", 20749992Sbostic #define ERR_BADBANG 87 20849992Sbostic "Bad ! form", 20949992Sbostic #define ERR_NOSUBST 88 21049992Sbostic "No previous substitute", 21149992Sbostic #define ERR_BADSUBST 89 21249992Sbostic "Bad substitute", 21349992Sbostic #define ERR_LHS 90 21449992Sbostic "No previous left hand side", 21549992Sbostic #define ERR_RHSLONG 91 21649992Sbostic "Right hand side too long", 21749992Sbostic #define ERR_BADBANGMOD 92 21849992Sbostic "Bad ! modifier: %c", 21949992Sbostic #define ERR_MODFAIL 93 22049992Sbostic "Modifier failed", 22149992Sbostic #define ERR_SUBOVFL 94 22249992Sbostic "Substitution buffer overflow", 22349992Sbostic #define ERR_BADBANGARG 95 22449992Sbostic "Bad ! arg selector", 22549992Sbostic #define ERR_NOSEARCH 96 22649992Sbostic "No prev search", 22749992Sbostic #define ERR_NOEVENT 97 22849992Sbostic "%s: Event not found", 22949992Sbostic #define ERR_TOOMANYRP 98 23049992Sbostic "Too many )'s", 23149992Sbostic #define ERR_TOOMANYLP 99 23249992Sbostic "Too many ('s", 23349992Sbostic #define ERR_BADPLP 100 23449992Sbostic "Badly placed (", 23549992Sbostic #define ERR_MISRED 101 23649992Sbostic "Missing name for redirect", 23749992Sbostic #define ERR_OUTRED 102 23849992Sbostic "Ambiguous output redirect", 23949992Sbostic #define ERR_REDPAR 103 24049992Sbostic "Can't << within ()'s", 24149992Sbostic #define ERR_INRED 104 24249992Sbostic "Ambiguous input redirect", 24349992Sbostic #define ERR_ALIASLOOP 105 24449992Sbostic "Alias loop", 24549992Sbostic #define ERR_HISTLOOP 106 24649992Sbostic "!# History loop", 24749992Sbostic #define ERR_ARCH 107 24849992Sbostic "%s: %s. Wrong Architecture", 24949992Sbostic #define ERR_FILEINQ 108 25049992Sbostic "Malformed file inquiry", 25149992Sbostic #define ERR_SELOVFL 109 25249992Sbostic "Selector overflow", 25349992Sbostic #define ERR_INVALID 110 25449992Sbostic "Invalid Error" 25549992Sbostic }; 25649992Sbostic 2571291Sbill /* 25849992Sbostic * The parser and scanner set up errors for later by calling seterr, 25949992Sbostic * which sets the variable err as a side effect; later to be tested, 26049992Sbostic * e.g. in process. 2611291Sbill */ 26249992Sbostic void 26350023Sbostic #if __STDC__ 26450023Sbostic seterror(int id, ...) 26550023Sbostic #else 26649992Sbostic seterror(id, va_alist) 26750023Sbostic int id; 26850023Sbostic va_dcl 26950023Sbostic #endif 27049992Sbostic { 27149992Sbostic if (seterr == 0) { 27250023Sbostic char berr[BUFSIZ]; 27349992Sbostic va_list va; 27449992Sbostic 27550023Sbostic #if __STDC__ 27650023Sbostic va_start(va, id); 27750023Sbostic #else 27850023Sbostic va_start(va); 27950023Sbostic #endif 28049992Sbostic if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0])) 28149992Sbostic id = ERR_INVALID; 282*50439Schristos vsprintf(berr, errorlist[id], va); 28349992Sbostic va_end(va); 28449992Sbostic 28549992Sbostic seterr = strsave(berr); 28649992Sbostic } 28749992Sbostic } 28849992Sbostic 2891291Sbill /* 29049992Sbostic * Print the error with the given id. 29149992Sbostic * 29249992Sbostic * Special ids: 29349992Sbostic * ERR_SILENT: Print nothing. 29449992Sbostic * ERR_OLD: Print the previously set error if one was there. 29549992Sbostic * otherwise return. 29649992Sbostic * ERR_NAME: If this bit is set, print the name of the function 29749992Sbostic * in bname 29849992Sbostic * 2991291Sbill * This routine always resets or exits. The flag haderr 3001291Sbill * is set so the routine who catches the unwind can propogate 3011291Sbill * it if they want. 3021291Sbill * 3031291Sbill * Note that any open files at the point of error will eventually 3041291Sbill * be closed in the routine process in sh.c which is the only 3051291Sbill * place error unwinds are ever caught. 3061291Sbill */ 30749992Sbostic void 30850023Sbostic #if __STDC__ 30950023Sbostic stderror(int id, ...) 31050023Sbostic #else 31149992Sbostic stderror(id, va_alist) 31249992Sbostic int id; 31350023Sbostic va_dcl 31450023Sbostic #endif 3151291Sbill { 31649992Sbostic va_list va; 31749992Sbostic register Char **v; 31849992Sbostic int flags = id & ERR_FLAGS; 3191291Sbill 32049992Sbostic id &= ~ERR_FLAGS; 3211291Sbill 32250024Schristos if ((flags & ERR_OLD) && seterr == NULL) 32349992Sbostic return; 3241291Sbill 32549992Sbostic if (id < 0 || id > sizeof(errorlist) / sizeof(errorlist[0])) 32649992Sbostic id = ERR_INVALID; 3271291Sbill 328*50439Schristos (void) fflush(cshout); 329*50439Schristos (void) fflush(csherr); 33049992Sbostic haderr = 1; /* Now to diagnostic output */ 33149992Sbostic timflg = 0; /* This isn't otherwise reset */ 33228049Slepreau 3331291Sbill 33449992Sbostic if (!(flags & ERR_SILENT)) { 33549992Sbostic if (flags & ERR_NAME) 336*50439Schristos (void) fprintf(csherr, "%s: ", bname); 33749992Sbostic if ((flags & ERR_OLD)) 33849992Sbostic /* Old error. */ 339*50439Schristos (void) fprintf(csherr, "%s.\n", seterr); 34049992Sbostic else { 34150023Sbostic #if __STDC__ 34250023Sbostic va_start(va, id); 34350023Sbostic #else 34449992Sbostic va_start(va); 34550023Sbostic #endif 346*50439Schristos (void) vfprintf(csherr, errorlist[id], va); 34749992Sbostic va_end(va); 348*50439Schristos (void) fprintf(csherr, ".\n"); 3491291Sbill } 35049992Sbostic } 3511291Sbill 35249992Sbostic if (seterr) { 35349992Sbostic xfree((ptr_t) seterr); 35450024Schristos seterr = NULL; 35549992Sbostic } 3561291Sbill 35749992Sbostic if (v = pargv) 35849992Sbostic pargv = 0, blkfree(v); 35949992Sbostic if (v = gargv) 36049992Sbostic gargv = 0, blkfree(v); 3611291Sbill 362*50439Schristos (void) fflush(cshout); 363*50439Schristos (void) fflush(csherr); 36449992Sbostic didfds = 0; /* Forget about 0,1,2 */ 36549992Sbostic /* 36649992Sbostic * Go away if -e or we are a child shell 36749992Sbostic */ 36849992Sbostic if (exiterr || child) 36949992Sbostic xexit(1); 3701291Sbill 37149992Sbostic /* 37249992Sbostic * Reset the state of the input. This buffered seek to end of file will 37349992Sbostic * also clear the while/foreach stack. 37449992Sbostic */ 37549992Sbostic btoeof(); 3761291Sbill 37749992Sbostic set(STRstatus, Strsave(STR1)); 37849992Sbostic if (tpgrp > 0) 37949992Sbostic (void) tcsetpgrp(FSHTTY, tpgrp); 38049992Sbostic reset(); /* Unwind */ 3811291Sbill } 382