Commit | Line | Data |
---|---|---|
7301366f BJ |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | #include "sh.h" | |
3 | ||
4 | /* | |
5 | * C Shell | |
6 | */ | |
7 | ||
8 | bool errspl; /* Argument to error was spliced by seterr2 */ | |
9 | char one[2] = { '1', 0 }; | |
10 | char *onev[2] = { one, NOSTR }; | |
11 | /* | |
12 | * Print error string s with optional argument arg. | |
13 | * This routine always resets or exits. The flag haderr | |
14 | * is set so the routine who catches the unwind can propogate | |
15 | * it if they want. | |
16 | * | |
17 | * Note that any open files at the point of error will eventually | |
18 | * be closed in the routine process in sh.c which is the only | |
19 | * place error unwinds are ever caught. | |
20 | */ | |
21 | error(s, arg) | |
22 | char *s; | |
23 | { | |
24 | register char **v; | |
25 | register char *ep; | |
26 | ||
27 | /* | |
28 | * Must flush before we print as we wish output before the error | |
29 | * to go on (some form of) standard output, while output after | |
30 | * goes on (some form of) diagnostic output. | |
31 | * If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG. | |
32 | * See flush in sh.print.c. | |
33 | */ | |
34 | flush(); | |
35 | haderr = 1; /* Now to diagnostic output */ | |
36 | timflg = 0; /* This isn't otherwise reset */ | |
37 | if (v = pargv) | |
38 | pargv = 0, blkfree(v); | |
39 | if (v = gargv) | |
40 | gargv = 0, blkfree(v); | |
41 | ||
42 | /* | |
43 | * A zero arguments causes no printing, else print | |
44 | * an error diagnostic here. | |
45 | */ | |
46 | if (s) | |
47 | printf(s, arg), printf(".\n"); | |
48 | ||
49 | didfds = 0; /* Forget about 0,1,2 */ | |
50 | if ((ep = err) && errspl) { | |
51 | errspl = 0; | |
52 | xfree(ep); | |
53 | } | |
54 | errspl = 0; | |
55 | ||
56 | /* | |
57 | * Reset the state of the input. | |
58 | * This buffered seek to end of file will also | |
59 | * clear the while/foreach stack. | |
60 | */ | |
61 | btoeof(); | |
62 | ||
63 | /* | |
64 | * Go away if -e or we are a child shell | |
65 | */ | |
66 | if (exiterr || child) | |
67 | exit(1); | |
68 | ||
69 | setq("status", onev, &shvhed); | |
70 | reset(); /* Unwind */ | |
71 | } | |
72 | ||
73 | /* | |
74 | * Perror is the shells version of perror which should otherwise | |
75 | * never be called. | |
76 | */ | |
77 | Perror(s) | |
78 | char *s; | |
79 | { | |
80 | ||
81 | /* | |
82 | * Perror uses unit 2, thus if we didn't set up the fd's | |
83 | * we must set up unit 2 now else the diagnostic will disappear | |
84 | */ | |
85 | if (!didfds) { | |
86 | register int oerrno = errno; | |
87 | ||
88 | dcopy(SHDIAG, 2); | |
89 | errno = oerrno; | |
90 | } | |
91 | perror(s); | |
92 | error(0); /* To exit or unwind */ | |
93 | } | |
94 | ||
95 | /* | |
96 | * For builtin functions, the routine bferr may be called | |
97 | * to print a diagnostic of the form: | |
98 | * name: Diagnostic. | |
99 | * where name has been setup by setname. | |
100 | * (Made into a macro to save space) | |
101 | * | |
102 | char *bname; | |
103 | ||
104 | setname(cp) | |
105 | char *cp; | |
106 | { | |
107 | ||
108 | bname = cp; | |
109 | } | |
110 | */ | |
111 | ||
112 | bferr(cp) | |
113 | char *cp; | |
114 | { | |
115 | ||
116 | flush(); | |
117 | haderr = 1; | |
118 | printf("%s: ", bname); | |
119 | error(cp); | |
120 | } | |
121 | ||
122 | /* | |
123 | * The parser and scanner set up errors for later by calling seterr, | |
124 | * which sets the variable err as a side effect; later to be tested, | |
125 | * e.g. in process. | |
126 | */ | |
127 | seterr(s) | |
128 | char *s; | |
129 | { | |
130 | ||
131 | if (err == 0) | |
132 | err = s, errspl = 0; | |
133 | } | |
134 | ||
135 | /* Set err to a splice of cp and dp, to be freed later in error() */ | |
136 | seterr2(cp, dp) | |
137 | char *cp, *dp; | |
138 | { | |
139 | ||
140 | if (err) | |
141 | return; | |
142 | err = strspl(cp, dp); | |
143 | errspl++; | |
144 | } | |
145 | ||
146 | /* Set err to a splice of cp with a string form of character d */ | |
147 | seterrc(cp, d) | |
148 | char *cp, d; | |
149 | { | |
150 | char chbuf[2]; | |
151 | ||
152 | chbuf[0] = d; | |
153 | chbuf[1] = 0; | |
154 | seterr2(cp, chbuf); | |
155 | } |