xref: /csrg-svn/bin/csh/err.c (revision 60765)
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