147823Sbostic /*-
2*60765Sbostic * Copyright (c) 1980, 1991, 1993
3*60765Sbostic * The Regents of the University of California. All rights reserved.
447823Sbostic *
547823Sbostic * %sccs.include.redist.c%
621929Sdist */
721929Sdist
817510Sedward #ifndef lint
9*60765Sbostic static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 05/31/93";
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
19050439Schristos "Usage: history [-rh] [# number of events]",
19149992Sbostic #define ERR_SPDOLLT 79
19251525Schristos "$, ! 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__
seterror(int id,...)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;
28250439Schristos 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__
stderror(int id,...)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
32850439Schristos (void) fflush(cshout);
32950439Schristos (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)
33650439Schristos (void) fprintf(csherr, "%s: ", bname);
33749992Sbostic if ((flags & ERR_OLD))
33849992Sbostic /* Old error. */
33950439Schristos (void) fprintf(csherr, "%s.\n", seterr);
34049992Sbostic else {
34150023Sbostic #if __STDC__
34250023Sbostic va_start(va, id);
34350023Sbostic #else
34449992Sbostic va_start(va);
34550023Sbostic #endif
34650439Schristos (void) vfprintf(csherr, errorlist[id], va);
34749992Sbostic va_end(va);
34850439Schristos (void) fprintf(csherr, ".\n");
3491291Sbill }
35049992Sbostic }
3511291Sbill
35249992Sbostic if (seterr) {
35349992Sbostic xfree((ptr_t) seterr);
35450024Schristos seterr = NULL;
35549992Sbostic }
3561291Sbill
35760237Schristos if ((v = pargv) != NULL)
35849992Sbostic pargv = 0, blkfree(v);
35960237Schristos if ((v = gargv) != NULL)
36049992Sbostic gargv = 0, blkfree(v);
3611291Sbill
36250439Schristos (void) fflush(cshout);
36350439Schristos (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