Commit | Line | Data |
---|---|---|
41c680d7 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 | blkfree(v), pargv = 0; | |
39 | if (v = gargv) | |
40 | blkfree(v), gargv = 0; | |
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 | xfree(ep); | |
52 | errspl = 0; | |
53 | ||
54 | /* | |
55 | * Reset the state of the input. | |
56 | * This buffered seek to end of file will also | |
57 | * clear the while/foreach stack. | |
58 | */ | |
59 | btoeof(); | |
60 | ||
61 | /* | |
62 | * Go away if -e or we are a child shell | |
63 | */ | |
64 | if (exiterr || child) | |
65 | exit(1); | |
66 | ||
67 | setq("status", onev, &shvhed); | |
68 | reset(); /* Unwind */ | |
69 | } | |
70 | ||
71 | /* | |
72 | * Perror is the shells version of perror which should otherwise | |
73 | * never be called. | |
74 | */ | |
75 | Perror(s) | |
76 | char *s; | |
77 | { | |
78 | ||
79 | /* | |
80 | * Perror uses unit 2, thus if we didn't set up the fd's | |
81 | * we must set up unit 2 now else the diagnostic will disappear | |
82 | */ | |
83 | if (!didfds) { | |
84 | register int oerrno = errno; | |
85 | ||
86 | dcopy(SHDIAG, 2); | |
87 | errno = oerrno; | |
88 | } | |
89 | perror(s); | |
90 | error(0); /* To exit or unwind */ | |
91 | } | |
92 | ||
93 | /* | |
94 | * For builtin functions, the routine bferr may be called | |
95 | * to print a diagnostic of the form: | |
96 | * name: Diagnostic. | |
97 | * where name has been setup by setname. | |
98 | * (Made into a macro to save space) | |
99 | * | |
100 | char *bname; | |
101 | ||
102 | setname(cp) | |
103 | char *cp; | |
104 | { | |
105 | ||
106 | bname = cp; | |
107 | } | |
108 | */ | |
109 | ||
110 | bferr(cp) | |
111 | char *cp; | |
112 | { | |
113 | ||
114 | flush(); | |
115 | haderr = 1; | |
116 | printf("%s: ", bname); | |
117 | error(cp); | |
118 | } | |
119 | ||
120 | /* | |
121 | * The parser and scanner set up errors for later by calling seterr, | |
122 | * which sets the variable err as a side effect; later to be tested, | |
123 | * e.g. in process. | |
124 | */ | |
125 | seterr(s) | |
126 | char *s; | |
127 | { | |
128 | ||
129 | if (err == 0) | |
130 | err = s, errspl = 0; | |
131 | } | |
132 | ||
133 | /* Set err to a splice of cp and dp, to be freed later in error() */ | |
134 | seterr2(cp, dp) | |
135 | char *cp, *dp; | |
136 | { | |
137 | ||
138 | if (err) | |
139 | return; | |
140 | err = strspl(cp, dp); | |
141 | errspl++; | |
142 | } | |
143 | ||
144 | /* Set err to a splice of cp with a string form of character d */ | |
145 | seterrc(cp, d) | |
146 | char *cp, d; | |
147 | { | |
148 | char chbuf[2]; | |
149 | ||
150 | chbuf[0] = d; | |
151 | chbuf[1] = 0; | |
152 | seterr2(cp, chbuf); | |
153 | } |