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