1 | /* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/sh.h,v 1.5 1998-10-04 01:39:29 danw Exp $ */ |
---|
2 | /* |
---|
3 | * sh.h: Catch it all globals and includes file! |
---|
4 | */ |
---|
5 | /*- |
---|
6 | * Copyright (c) 1980, 1991 The Regents of the University of California. |
---|
7 | * All rights reserved. |
---|
8 | * |
---|
9 | * Redistribution and use in source and binary forms, with or without |
---|
10 | * modification, are permitted provided that the following conditions |
---|
11 | * are met: |
---|
12 | * 1. Redistributions of source code must retain the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer. |
---|
14 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
15 | * notice, this list of conditions and the following disclaimer in the |
---|
16 | * documentation and/or other materials provided with the distribution. |
---|
17 | * 3. All advertising materials mentioning features or use of this software |
---|
18 | * must display the following acknowledgement: |
---|
19 | * This product includes software developed by the University of |
---|
20 | * California, Berkeley and its contributors. |
---|
21 | * 4. Neither the name of the University nor the names of its contributors |
---|
22 | * may be used to endorse or promote products derived from this software |
---|
23 | * without specific prior written permission. |
---|
24 | * |
---|
25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
35 | * SUCH DAMAGE. |
---|
36 | */ |
---|
37 | #ifndef _h_sh |
---|
38 | #define _h_sh |
---|
39 | |
---|
40 | #include "config.h" |
---|
41 | |
---|
42 | #ifndef EXTERN |
---|
43 | # define EXTERN extern |
---|
44 | #else /* !EXTERN */ |
---|
45 | # ifdef WINNT |
---|
46 | # define IZERO = 0 |
---|
47 | # define IZERO_STRUCT = {0} |
---|
48 | # endif /* WINNT */ |
---|
49 | #endif /* EXTERN */ |
---|
50 | |
---|
51 | #ifndef IZERO |
---|
52 | # define IZERO |
---|
53 | #endif /* IZERO */ |
---|
54 | #ifndef IZERO_STRUCT |
---|
55 | # define IZERO_STRUCT |
---|
56 | # endif /* IZERO_STRUCT */ |
---|
57 | |
---|
58 | #ifndef WINNT |
---|
59 | # define INIT_ZERO |
---|
60 | # define INIT_ZERO_STRUCT |
---|
61 | # define force_read read |
---|
62 | #endif /*!WINNT */ |
---|
63 | /* |
---|
64 | * Sanity |
---|
65 | */ |
---|
66 | #if defined(_POSIX_SOURCE) && !defined(POSIX) |
---|
67 | # define POSIX |
---|
68 | #endif |
---|
69 | |
---|
70 | #if defined(POSIXJOBS) && !defined(BSDJOBS) |
---|
71 | # define BSDJOBS |
---|
72 | #endif |
---|
73 | |
---|
74 | #if defined(POSIXSIGS) && !defined(BSDSIGS) |
---|
75 | # define BSDSIGS |
---|
76 | #endif |
---|
77 | |
---|
78 | #ifdef SHORT_STRINGS |
---|
79 | typedef short Char; |
---|
80 | typedef unsigned short uChar; |
---|
81 | # define SAVE(a) (Strsave(str2short(a))) |
---|
82 | #else |
---|
83 | typedef char Char; |
---|
84 | typedef unsigned char uChar; |
---|
85 | # define SAVE(a) (strsave(a)) |
---|
86 | #endif |
---|
87 | |
---|
88 | /* Elide unused argument warnings */ |
---|
89 | #define USE(a) (void) (a) |
---|
90 | /* |
---|
91 | * If your compiler complains, then you can either |
---|
92 | * throw it away and get gcc or, use the following define |
---|
93 | * and get rid of the typedef. |
---|
94 | * [The 4.2/3BSD vax compiler does not like that] |
---|
95 | * Both MULTIFLOW and PCC compilers exhbit this bug. -- sterling@netcom.com |
---|
96 | */ |
---|
97 | #ifdef SIGVOID |
---|
98 | # if (defined(vax) || defined(uts) || defined(MULTIFLOW) || defined(PCC)) && !defined(__GNUC__) |
---|
99 | # define sigret_t void |
---|
100 | # else /* !((vax || uts || MULTIFLOW || PCC) && !__GNUC__) */ |
---|
101 | typedef void sigret_t; |
---|
102 | # endif /* (vax || uts || MULTIFLOW || PCC) && !__GNUC__ */ |
---|
103 | #else /* !SIGVOID */ |
---|
104 | typedef int sigret_t; |
---|
105 | #endif /* SIGVOID */ |
---|
106 | |
---|
107 | /* |
---|
108 | * Return true if the path is absolute |
---|
109 | */ |
---|
110 | #ifndef WINNT |
---|
111 | # define ABSOLUTEP(p) (*(p) == '/') |
---|
112 | #else /* WINNT */ |
---|
113 | # define ABSOLUTEP(p) ((p)[0] == '/' || \ |
---|
114 | (Isalpha((p)[0]) && (p)[1] == ':' && (p)[2] == '/')) |
---|
115 | #endif /* WINNT */ |
---|
116 | |
---|
117 | /* |
---|
118 | * Fundamental definitions which may vary from system to system. |
---|
119 | * |
---|
120 | * BUFSIZE The i/o buffering size; also limits word size |
---|
121 | * MAILINTVL How often to mailcheck; more often is more expensive |
---|
122 | */ |
---|
123 | #ifdef BUFSIZE |
---|
124 | # if BUFSIZE < 1024 |
---|
125 | # undef BUFSIZE |
---|
126 | # define BUFSIZE 1024 /* buffer size should be no less than this */ |
---|
127 | # endif |
---|
128 | #else |
---|
129 | # define BUFSIZE 1024 |
---|
130 | #endif /* BUFSIZE */ |
---|
131 | |
---|
132 | #define FORKSLEEP 10 /* delay loop on non-interactive fork failure */ |
---|
133 | #define MAILINTVL 600 /* 10 minutes */ |
---|
134 | |
---|
135 | #ifndef INBUFSIZE |
---|
136 | # define INBUFSIZE 2*BUFSIZE /* Num input characters on the command line */ |
---|
137 | #endif /* INBUFSIZE */ |
---|
138 | |
---|
139 | |
---|
140 | /* |
---|
141 | * What our builtin echo looks like |
---|
142 | */ |
---|
143 | #define NONE_ECHO 0 |
---|
144 | #define BSD_ECHO 1 |
---|
145 | #define SYSV_ECHO 2 |
---|
146 | #define BOTH_ECHO (BSD_ECHO|SYSV_ECHO) |
---|
147 | |
---|
148 | #ifndef ECHO_STYLE |
---|
149 | # if SYSVREL > 0 |
---|
150 | # define ECHO_STYLE SYSV_ECHO |
---|
151 | # else /* SYSVREL == 0 */ |
---|
152 | # define ECHO_STYLE BSD_ECHO |
---|
153 | # endif /* SYSVREL */ |
---|
154 | #endif /* ECHO_STYLE */ |
---|
155 | |
---|
156 | /* |
---|
157 | * The shell moves std in/out/diag and the old std input away from units |
---|
158 | * 0, 1, and 2 so that it is easy to set up these standards for invoked |
---|
159 | * commands. |
---|
160 | */ |
---|
161 | #define FSHTTY 15 /* /dev/tty when manip pgrps */ |
---|
162 | #define FSHIN 16 /* Preferred desc for shell input */ |
---|
163 | #define FSHOUT 17 /* ... shell output */ |
---|
164 | #define FSHDIAG 18 /* ... shell diagnostics */ |
---|
165 | #define FOLDSTD 19 /* ... old std input */ |
---|
166 | |
---|
167 | #ifdef PROF |
---|
168 | #define xexit(n) done(n) |
---|
169 | #endif |
---|
170 | |
---|
171 | #ifdef cray |
---|
172 | # define word word_t /* sys/types.h defines word.. bad move! */ |
---|
173 | #endif |
---|
174 | |
---|
175 | #include <sys/types.h> |
---|
176 | |
---|
177 | #ifdef cray |
---|
178 | # undef word |
---|
179 | #endif |
---|
180 | |
---|
181 | /* |
---|
182 | * Path separator in environment variables |
---|
183 | */ |
---|
184 | #ifndef PATHSEP |
---|
185 | # if defined(__EMX__) || defined(WINNT) |
---|
186 | # define PATHSEP ';' |
---|
187 | # else /* unix */ |
---|
188 | # define PATHSEP ':' |
---|
189 | # endif /* __EMX__ || WINNT */ |
---|
190 | #endif /* !PATHSEP */ |
---|
191 | |
---|
192 | /* |
---|
193 | * This macro compares the st_dev field of struct stat. On aix on ibmESA |
---|
194 | * st_dev is a structure, so comparison does not work. |
---|
195 | */ |
---|
196 | #ifndef DEV_DEV_COMPARE |
---|
197 | # define DEV_DEV_COMPARE(x,y) ((x) == (y)) |
---|
198 | #endif /* DEV_DEV_COMPARE */ |
---|
199 | |
---|
200 | #ifdef _SEQUENT_ |
---|
201 | # include <sys/procstats.h> |
---|
202 | #endif /* _SEQUENT_ */ |
---|
203 | #if (defined(POSIX) || SYSVREL > 0) && !WINNT |
---|
204 | # include <sys/times.h> |
---|
205 | #endif /* (POSIX || SYSVREL > 0) && !WINNT */ |
---|
206 | |
---|
207 | #ifdef NLS |
---|
208 | # include <locale.h> |
---|
209 | #endif /* NLS */ |
---|
210 | |
---|
211 | |
---|
212 | #if !defined(_MINIX) && !defined(_VMS_POSIX) && !defined(WINNT) |
---|
213 | # include <sys/param.h> |
---|
214 | #endif /* !_MINIX && !_VMS_POSIX && !WINNT */ |
---|
215 | #include <sys/stat.h> |
---|
216 | |
---|
217 | #if defined(BSDTIMES) || defined(BSDLIMIT) |
---|
218 | # include <sys/time.h> |
---|
219 | # include <sys/resource.h> |
---|
220 | #endif /* BSDTIMES */ |
---|
221 | |
---|
222 | #ifndef WINNT |
---|
223 | # ifndef POSIX |
---|
224 | # ifdef TERMIO |
---|
225 | # include <termio.h> |
---|
226 | # else /* SGTTY */ |
---|
227 | # include <sgtty.h> |
---|
228 | # endif /* TERMIO */ |
---|
229 | # else /* POSIX */ |
---|
230 | # include <termios.h> |
---|
231 | # if SYSVREL > 3 |
---|
232 | # undef TIOCGLTC /* we don't need those, since POSIX has them */ |
---|
233 | # undef TIOCSLTC |
---|
234 | # undef CSWTCH |
---|
235 | # define CSWTCH _POSIX_VDISABLE /* So job control works */ |
---|
236 | # endif /* SYSVREL > 3 */ |
---|
237 | # endif /* POSIX */ |
---|
238 | #endif /* WINNT */ |
---|
239 | |
---|
240 | #ifdef sonyrisc |
---|
241 | # include <sys/ttold.h> |
---|
242 | #endif /* sonyrisc */ |
---|
243 | |
---|
244 | #if defined(POSIX) && !defined(WINNT) |
---|
245 | /* |
---|
246 | * We should be using setpgid and setpgid |
---|
247 | * by now, but in some systems we use the |
---|
248 | * old routines... |
---|
249 | */ |
---|
250 | # define getpgrp __getpgrp |
---|
251 | # define setpgrp __setpgrp |
---|
252 | # include <unistd.h> |
---|
253 | # undef getpgrp |
---|
254 | # undef setpgrp |
---|
255 | |
---|
256 | /* |
---|
257 | * the gcc+protoize version of <stdlib.h> |
---|
258 | * redefines malloc(), so we define the following |
---|
259 | * to avoid it. |
---|
260 | */ |
---|
261 | # if defined(linux) || defined(sgi) |
---|
262 | # define NO_FIX_MALLOC |
---|
263 | # include <stdlib.h> |
---|
264 | # else /* linux */ |
---|
265 | # define _GNU_STDLIB_H |
---|
266 | # define malloc __malloc |
---|
267 | # define free __free |
---|
268 | # define calloc __calloc |
---|
269 | # define realloc __realloc |
---|
270 | # include <stdlib.h> |
---|
271 | # undef malloc |
---|
272 | # undef free |
---|
273 | # undef calloc |
---|
274 | # undef realloc |
---|
275 | # endif /* linux || sgi */ |
---|
276 | # include <limits.h> |
---|
277 | #endif /* POSIX && !WINNT */ |
---|
278 | |
---|
279 | #if SYSVREL > 0 || defined(_IBMR2) || defined(_MINIX) |
---|
280 | # if !defined(pyr) && !defined(stellar) |
---|
281 | # include <time.h> |
---|
282 | # ifdef _MINIX |
---|
283 | # define HZ CLOCKS_PER_SEC |
---|
284 | # endif /* _MINIX */ |
---|
285 | # endif /* !pyr && !stellar */ |
---|
286 | #endif /* SYSVREL > 0 || _IBMR2 */ |
---|
287 | |
---|
288 | /* In the following ifdef the DECOSF1 has been commented so that later |
---|
289 | * versions of DECOSF1 will get TIOCGWINSZ. This might break older versions... |
---|
290 | */ |
---|
291 | #if !((defined(SUNOS4) || defined(_MINIX) /* || defined(DECOSF1) */) && defined(TERMIO)) |
---|
292 | # if !defined(COHERENT) && !defined(_VMS_POSIX) && !defined(WINNT) |
---|
293 | # include <sys/ioctl.h> |
---|
294 | # endif |
---|
295 | #endif |
---|
296 | |
---|
297 | #if (defined(__DGUX__) && defined(POSIX)) || defined(DGUX) |
---|
298 | #undef CSWTCH |
---|
299 | #define CSWTCH _POSIX_VDISABLE |
---|
300 | #endif |
---|
301 | |
---|
302 | #if (!defined(FIOCLEX) && defined(SUNOS4)) || ((SYSVREL == 4) && !defined(_SEQUENT_) && !defined(SCO)) |
---|
303 | # include <sys/filio.h> |
---|
304 | #endif /* (!FIOCLEX && SUNOS4) || (SYSVREL == 4 && !_SEQUENT_ && !SCO) */ |
---|
305 | |
---|
306 | #if !defined(_MINIX) && !defined(COHERENT) && !defined(supermax) && !defined(WINNT) |
---|
307 | # include <sys/file.h> |
---|
308 | #endif /* !_MINIX && !COHERENT && !supermax && !WINNT */ |
---|
309 | |
---|
310 | #if !defined(O_RDONLY) || !defined(O_NDELAY) |
---|
311 | # include <fcntl.h> |
---|
312 | #endif |
---|
313 | |
---|
314 | #include <errno.h> |
---|
315 | |
---|
316 | #include <setjmp.h> |
---|
317 | |
---|
318 | #if __STDC__ || defined(FUNCPROTO) |
---|
319 | # include <stdarg.h> |
---|
320 | #else |
---|
321 | #ifdef _MINIX |
---|
322 | # include "mi.varargs.h" |
---|
323 | #else |
---|
324 | # include <varargs.h> |
---|
325 | #endif /* _MINIX */ |
---|
326 | #endif |
---|
327 | |
---|
328 | #ifdef DIRENT |
---|
329 | # include <dirent.h> |
---|
330 | #else |
---|
331 | # ifdef hp9000s500 |
---|
332 | # include <ndir.h> |
---|
333 | # else |
---|
334 | # include <sys/dir.h> |
---|
335 | # endif |
---|
336 | # define dirent direct |
---|
337 | #endif /* DIRENT */ |
---|
338 | #if defined(hpux) || defined(sgi) || defined(OREO) || defined(COHERENT) |
---|
339 | # include <stdio.h> /* So the fgetpwent() prototypes work */ |
---|
340 | #endif /* hpux || sgi || OREO || COHERENT */ |
---|
341 | #ifndef WINNT |
---|
342 | #include <pwd.h> |
---|
343 | #include <grp.h> |
---|
344 | #endif /* WINNT */ |
---|
345 | #ifdef PW_SHADOW |
---|
346 | # include <shadow.h> |
---|
347 | #endif /* PW_SHADOW */ |
---|
348 | #ifdef PW_AUTH |
---|
349 | # include <auth.h> |
---|
350 | #endif /* PW_AUTH */ |
---|
351 | #if defined(BSD) && !defined(POSIX) |
---|
352 | # include <strings.h> |
---|
353 | # define strchr(a, b) index(a, b) |
---|
354 | # define strrchr(a, b) rindex(a, b) |
---|
355 | #else |
---|
356 | # include <string.h> |
---|
357 | #endif /* BSD */ |
---|
358 | |
---|
359 | /* |
---|
360 | * IRIX-5.0 has <sys/cdefs.h>, but most system include files do not |
---|
361 | * include it yet, so we include it here |
---|
362 | */ |
---|
363 | #if defined(sgi) && SYSVREL > 3 |
---|
364 | # include <sys/cdefs.h> |
---|
365 | #endif /* sgi && SYSVREL > 3 */ |
---|
366 | |
---|
367 | #ifdef REMOTEHOST |
---|
368 | # ifdef ISC |
---|
369 | # undef MAXHOSTNAMELEN /* Busted headers? */ |
---|
370 | # endif |
---|
371 | |
---|
372 | # include <netinet/in.h> |
---|
373 | # include <arpa/inet.h> |
---|
374 | # include <sys/socket.h> |
---|
375 | # include <sys/uio.h> /* For struct iovec */ |
---|
376 | #endif /* REMOTEHOST */ |
---|
377 | |
---|
378 | /* |
---|
379 | * ANSIisms... These must be *after* the system include and |
---|
380 | * *before* our includes, so that BSDreno has time to define __P |
---|
381 | */ |
---|
382 | #undef __P |
---|
383 | #ifndef __P |
---|
384 | # if __STDC__ || defined(FUNCPROTO) |
---|
385 | # ifndef FUNCPROTO |
---|
386 | # define FUNCPROTO |
---|
387 | # endif |
---|
388 | # define __P(a) a |
---|
389 | # else |
---|
390 | # define __P(a) () |
---|
391 | # if !__STDC__ |
---|
392 | # define const |
---|
393 | # ifndef apollo |
---|
394 | # define volatile /* Apollo 'c' extensions need this */ |
---|
395 | # endif /* apollo */ |
---|
396 | # endif |
---|
397 | # endif |
---|
398 | #endif |
---|
399 | |
---|
400 | |
---|
401 | #ifdef PURIFY |
---|
402 | /* exit normally, allowing purify to trace leaks */ |
---|
403 | # define _exit exit |
---|
404 | typedef int pret_t; |
---|
405 | #else /* !PURIFY */ |
---|
406 | /* |
---|
407 | * If your compiler complains, then you can either |
---|
408 | * throw it away and get gcc or, use the following define |
---|
409 | * and get rid of the typedef. |
---|
410 | * [The 4.2/3BSD vax compiler does not like that] |
---|
411 | * Both MULTIFLOW and PCC compilers exhbit this bug. -- sterling@netcom.com |
---|
412 | */ |
---|
413 | # if (defined(vax) || defined(uts) || defined(MULTIFLOW) || defined(PCC)) && !defined(__GNUC__) |
---|
414 | # define pret_t void |
---|
415 | # else /* !((vax || uts || MULTIFLOW || PCC) && !__GNUC__) */ |
---|
416 | typedef void pret_t; |
---|
417 | # endif /* (vax || uts || MULTIFLOW || PCC) && !__GNUC__ */ |
---|
418 | #endif /* PURIFY */ |
---|
419 | |
---|
420 | typedef int bool; |
---|
421 | |
---|
422 | #include "sh.types.h" |
---|
423 | |
---|
424 | #ifndef WINNT |
---|
425 | # ifndef POSIX |
---|
426 | extern pid_t getpgrp __P((int)); |
---|
427 | # else /* POSIX */ |
---|
428 | # if (defined(BSD) && !defined(BSD4_4)) || defined(SUNOS4) || defined(IRIS4D) || defined(DGUX) |
---|
429 | extern pid_t getpgrp __P((int)); |
---|
430 | # else /* !(BSD || SUNOS4 || IRIS4D || DGUX) */ |
---|
431 | extern pid_t getpgrp __P((void)); |
---|
432 | # endif /* BSD || SUNOS4 || IRISD || DGUX */ |
---|
433 | # endif /* POSIX */ |
---|
434 | extern pid_t setpgrp __P((pid_t, pid_t)); |
---|
435 | #endif /* !WINNT */ |
---|
436 | |
---|
437 | typedef sigret_t (*signalfun_t) __P((int)); |
---|
438 | |
---|
439 | #ifndef lint |
---|
440 | typedef ptr_t memalign_t; |
---|
441 | #else |
---|
442 | typedef union { |
---|
443 | char am_char, *am_char_p; |
---|
444 | short am_short, *am_short_p; |
---|
445 | int am_int, *am_int_p; |
---|
446 | long am_long, *am_long_p; |
---|
447 | float am_float, *am_float_p; |
---|
448 | double am_double, *am_double_p; |
---|
449 | } *memalign_t; |
---|
450 | |
---|
451 | # define malloc lint_malloc |
---|
452 | # define free lint_free |
---|
453 | # define realloc lint_realloc |
---|
454 | # define calloc lint_calloc |
---|
455 | #endif |
---|
456 | |
---|
457 | #ifdef MDEBUG |
---|
458 | extern memalign_t DebugMalloc __P((unsigned, char *, int)); |
---|
459 | extern memalign_t DebugRealloc __P((ptr_t, unsigned, char *, int)); |
---|
460 | extern memalign_t DebugCalloc __P((unsigned, unsigned, char *, int)); |
---|
461 | extern void DebugFree __P((ptr_t, char *, int)); |
---|
462 | # define xmalloc(i) DebugMalloc(i, __FILE__, __LINE__) |
---|
463 | # define xrealloc(p, i)((p) ? DebugRealloc(p, i, __FILE__, __LINE__) : \ |
---|
464 | DebugMalloc(i, __FILE__, __LINE__)) |
---|
465 | # define xcalloc(n, s) DebugCalloc(n, s, __FILE__, __LINE__) |
---|
466 | # define xfree(p) if (p) DebugFree(p, __FILE__, __LINE__) |
---|
467 | #else |
---|
468 | # ifdef SYSMALLOC |
---|
469 | # define xmalloc(i) smalloc(i) |
---|
470 | # define xrealloc(p, i) srealloc(p, i) |
---|
471 | # define xcalloc(n, s) scalloc(n, s) |
---|
472 | # define xfree(p) sfree(p) |
---|
473 | # else |
---|
474 | # define xmalloc(i) malloc(i) |
---|
475 | # define xrealloc(p, i) realloc(p, i) |
---|
476 | # define xcalloc(n, s) calloc(n, s) |
---|
477 | # define xfree(p) free(p) |
---|
478 | # endif /* SYSMALLOC */ |
---|
479 | #endif /* MDEBUG */ |
---|
480 | #include "sh.char.h" |
---|
481 | #include "sh.err.h" |
---|
482 | #include "sh.dir.h" |
---|
483 | #include "sh.proc.h" |
---|
484 | |
---|
485 | #include "pathnames.h" |
---|
486 | |
---|
487 | |
---|
488 | /* |
---|
489 | * C shell |
---|
490 | * |
---|
491 | * Bill Joy, UC Berkeley |
---|
492 | * October, 1978; May 1980 |
---|
493 | * |
---|
494 | * Jim Kulp, IIASA, Laxenburg Austria |
---|
495 | * April, 1980 |
---|
496 | */ |
---|
497 | |
---|
498 | #if !defined(MAXNAMLEN) && defined(_D_NAME_MAX) |
---|
499 | # define MAXNAMLEN _D_NAME_MAX |
---|
500 | #endif /* MAXNAMLEN */ |
---|
501 | |
---|
502 | #ifdef HESIOD |
---|
503 | # include <hesiod.h> |
---|
504 | #endif /* HESIOD */ |
---|
505 | |
---|
506 | #ifdef REMOTEHOST |
---|
507 | # include <netdb.h> |
---|
508 | #endif /* REMOTEHOST */ |
---|
509 | |
---|
510 | #ifndef MAXHOSTNAMELEN |
---|
511 | # if defined(SCO) && (SYSVREL > 3) |
---|
512 | # include <sys/socket.h> |
---|
513 | # else |
---|
514 | # define MAXHOSTNAMELEN 255 |
---|
515 | # endif |
---|
516 | #endif /* MAXHOSTNAMELEN */ |
---|
517 | |
---|
518 | |
---|
519 | |
---|
520 | #define eq(a, b) (Strcmp(a, b) == 0) |
---|
521 | |
---|
522 | /* globone() flags */ |
---|
523 | #define G_ERROR 0 /* default action: error if multiple words */ |
---|
524 | #define G_IGNORE 1 /* ignore the rest of the words */ |
---|
525 | #define G_APPEND 2 /* make a sentence by cat'ing the words */ |
---|
526 | |
---|
527 | /* |
---|
528 | * Global flags |
---|
529 | */ |
---|
530 | EXTERN bool chkstop IZERO; /* Warned of stopped jobs... allow exit */ |
---|
531 | |
---|
532 | #if (defined(FIOCLEX) && defined(FIONCLEX)) || defined(F_SETFD) |
---|
533 | # define CLOSE_ON_EXEC |
---|
534 | #else |
---|
535 | EXTERN bool didcch IZERO; /* Have closed unused fd's for child */ |
---|
536 | #endif /* (FIOCLEX && FIONCLEX) || F_SETFD */ |
---|
537 | |
---|
538 | EXTERN bool didfds IZERO; /* Have setup i/o fd's for child */ |
---|
539 | EXTERN bool doneinp IZERO; /* EOF indicator after reset from readc */ |
---|
540 | EXTERN bool exiterr IZERO; /* Exit if error or non-zero exit status */ |
---|
541 | EXTERN bool child IZERO; /* Child shell ... errors cause exit */ |
---|
542 | EXTERN bool haderr IZERO; /* Reset was because of an error */ |
---|
543 | EXTERN bool intty IZERO; /* Input is a tty */ |
---|
544 | EXTERN bool intact IZERO; /* We are interactive... therefore prompt */ |
---|
545 | EXTERN bool justpr IZERO; /* Just print because of :p hist mod */ |
---|
546 | EXTERN bool loginsh IZERO; /* We are a loginsh -> .login/.logout */ |
---|
547 | EXTERN bool neednote IZERO; /* Need to pnotify() */ |
---|
548 | EXTERN bool noexec IZERO; /* Don't execute, just syntax check */ |
---|
549 | EXTERN bool pjobs IZERO; /* want to print jobs if interrupted */ |
---|
550 | EXTERN bool setintr IZERO; /* Set interrupts on/off -> Wait intr... */ |
---|
551 | EXTERN bool timflg IZERO; /* Time the next waited for command */ |
---|
552 | EXTERN bool havhash IZERO; /* path hashing is available */ |
---|
553 | EXTERN bool editing IZERO; /* doing filename expansion and line editing */ |
---|
554 | EXTERN bool noediting IZERO; /* initial $term defaulted to noedit */ |
---|
555 | EXTERN bool bslash_quote IZERO;/* PWP: tcsh-style quoting? (in sh.c) */ |
---|
556 | EXTERN bool isoutatty IZERO; /* is SHOUT a tty */ |
---|
557 | EXTERN bool isdiagatty IZERO;/* is SHDIAG a tty */ |
---|
558 | EXTERN bool is1atty IZERO; /* is file descriptor 1 a tty (didfds mode) */ |
---|
559 | EXTERN bool is2atty IZERO; /* is file descriptor 2 a tty (didfds mode) */ |
---|
560 | EXTERN bool arun IZERO; /* Currently running multi-line-aliases */ |
---|
561 | EXTERN int implicit_cd IZERO;/* implicit cd enabled?(1=enabled,2=verbose) */ |
---|
562 | EXTERN bool inheredoc IZERO; /* Currently parsing a heredoc */ |
---|
563 | |
---|
564 | /* |
---|
565 | * Global i/o info |
---|
566 | */ |
---|
567 | EXTERN Char *arginp IZERO; /* Argument input for sh -c and internal `xx` */ |
---|
568 | EXTERN int onelflg IZERO; /* 2 -> need line for -t, 1 -> exit on read */ |
---|
569 | extern Char *ffile; /* Name of shell file for $0 */ |
---|
570 | extern bool dolzero; /* if $?0 should return true... */ |
---|
571 | |
---|
572 | extern char *seterr; /* Error message from scanner/parser */ |
---|
573 | extern int errno; /* Error from C library routines */ |
---|
574 | EXTERN Char *shtemp IZERO; /* Temp name for << shell files in /tmp */ |
---|
575 | |
---|
576 | #ifdef BSDTIMES |
---|
577 | EXTERN struct timeval time0; /* Time at which the shell started */ |
---|
578 | EXTERN struct sysrusage ru0; |
---|
579 | #else |
---|
580 | # ifdef _SEQUENT_ |
---|
581 | EXTERN timeval_t time0; /* time at which shell started */ |
---|
582 | EXTERN struct process_stats ru0; |
---|
583 | # else /* _SEQUENT_ */ |
---|
584 | # ifndef POSIX |
---|
585 | EXTERN time_t time0; /* time at which shell started */ |
---|
586 | # else /* POSIX */ |
---|
587 | EXTERN clock_t time0; /* time at which shell started */ |
---|
588 | EXTERN clock_t clk_tck; |
---|
589 | # endif /* POSIX */ |
---|
590 | EXTERN struct tms shtimes; /* shell and child times for process timing */ |
---|
591 | # endif /* _SEQUENT_ */ |
---|
592 | #endif /* BSDTIMES */ |
---|
593 | |
---|
594 | #ifndef HZ |
---|
595 | # define HZ 100 /* for division into seconds */ |
---|
596 | #endif |
---|
597 | |
---|
598 | /* |
---|
599 | * Miscellany |
---|
600 | */ |
---|
601 | EXTERN Char *doldol; /* Character pid for $$ */ |
---|
602 | EXTERN int backpid; /* pid of the last background job */ |
---|
603 | |
---|
604 | /* |
---|
605 | * Ideally these should be uid_t, gid_t, pid_t. I cannot do that right now |
---|
606 | * cause pid's could be unsigned and that would break our -1 flag, and |
---|
607 | * uid_t and gid_t are not defined in all the systems so I would have to |
---|
608 | * make special cases for them. In the future... |
---|
609 | */ |
---|
610 | EXTERN int uid, euid, /* Invokers real and effective */ |
---|
611 | gid, egid; /* User and group ids */ |
---|
612 | EXTERN int opgrp, /* Initial pgrp and tty pgrp */ |
---|
613 | shpgrp, /* Pgrp of shell */ |
---|
614 | tpgrp; /* Terminal process group */ |
---|
615 | /* If tpgrp is -1, leave tty alone! */ |
---|
616 | |
---|
617 | EXTERN Char PromptBuf[INBUFSIZE*2]; /* buffer for the actual printed prompt. |
---|
618 | * this must be large enough to contain |
---|
619 | * the input line and the prompt, in |
---|
620 | * case a correction occurred... |
---|
621 | */ |
---|
622 | EXTERN Char RPromptBuf[INBUFSIZE]; /* buffer for right-hand side prompt */ |
---|
623 | |
---|
624 | /* |
---|
625 | * To be able to redirect i/o for builtins easily, the shell moves the i/o |
---|
626 | * descriptors it uses away from 0,1,2. |
---|
627 | * Ideally these should be in units which are closed across exec's |
---|
628 | * (this saves work) but for version 6, this is not usually possible. |
---|
629 | * The desired initial values for these descriptors are defined in |
---|
630 | * sh.local.h. |
---|
631 | */ |
---|
632 | EXTERN int SHIN IZERO; /* Current shell input (script) */ |
---|
633 | EXTERN int SHOUT IZERO; /* Shell output */ |
---|
634 | EXTERN int SHDIAG IZERO; /* Diagnostic output... shell errs go here */ |
---|
635 | EXTERN int OLDSTD IZERO; /* Old standard input (def for cmds) */ |
---|
636 | |
---|
637 | |
---|
638 | #if SYSVREL == 4 && defined(_UTS) |
---|
639 | /* |
---|
640 | * From: fadden@uts.amdahl.com (Andy McFadden) |
---|
641 | * we need sigsetjmp for UTS4, but not UTS2.1 |
---|
642 | */ |
---|
643 | # define SIGSETJMP |
---|
644 | #endif |
---|
645 | |
---|
646 | /* |
---|
647 | * Error control |
---|
648 | * |
---|
649 | * Errors in scanning and parsing set up an error message to be printed |
---|
650 | * at the end and complete. Other errors always cause a reset. |
---|
651 | * Because of source commands and .cshrc we need nested error catches. |
---|
652 | */ |
---|
653 | |
---|
654 | #ifdef NO_STRUCT_ASSIGNMENT |
---|
655 | |
---|
656 | # ifdef SIGSETJMP |
---|
657 | typedef sigjmp_buf jmp_buf_t; |
---|
658 | /* bugfix by Jak Kirman @ Brown U.: remove the (void) cast here, see sh.c */ |
---|
659 | # define setexit() sigsetjmp(reslab) |
---|
660 | # define reset() siglongjmp(reslab, 1) |
---|
661 | # else |
---|
662 | typedef jmp_buf jmp_buf_t; |
---|
663 | /* bugfix by Jak Kirman @ Brown U.: remove the (void) cast here, see sh.c */ |
---|
664 | # define setexit() setjmp(reslab) |
---|
665 | # define reset() longjmp(reslab, 1) |
---|
666 | # endif |
---|
667 | # define getexit(a) (void) memmove((ptr_t)&(a), (ptr_t)&reslab, sizeof(reslab)) |
---|
668 | # define resexit(a) (void) memmove((ptr_t)&reslab, (ptr_t)&(a), sizeof(reslab)) |
---|
669 | |
---|
670 | # define cpybin(a, b) (void) memmove((ptr_t)&(a), (ptr_t)&(b), sizeof(Bin)) |
---|
671 | |
---|
672 | #else |
---|
673 | |
---|
674 | # ifdef SIGSETJMP |
---|
675 | typedef struct { sigjmp_buf j; } jmp_buf_t; |
---|
676 | # define setexit() sigsetjmp(reslab.j) |
---|
677 | # define reset() siglongjmp(reslab.j, 1) |
---|
678 | # else |
---|
679 | typedef struct { jmp_buf j; } jmp_buf_t; |
---|
680 | # define setexit() setjmp(reslab.j) |
---|
681 | # define reset() longjmp(reslab.j, 1) |
---|
682 | # endif |
---|
683 | |
---|
684 | # define getexit(a) (void) ((a) = reslab) |
---|
685 | # define resexit(a) (void) (reslab = (a)) |
---|
686 | |
---|
687 | # define cpybin(a, b) (void) ((a) = (b)) |
---|
688 | |
---|
689 | #endif /* NO_STRUCT_ASSIGNMENT */ |
---|
690 | |
---|
691 | extern jmp_buf_t reslab; |
---|
692 | |
---|
693 | EXTERN Char *gointr; /* Label for an onintr transfer */ |
---|
694 | |
---|
695 | extern signalfun_t parintr; /* Parents interrupt catch */ |
---|
696 | extern signalfun_t parterm; /* Parents terminate catch */ |
---|
697 | |
---|
698 | /* |
---|
699 | * Lexical definitions. |
---|
700 | * |
---|
701 | * All lexical space is allocated dynamically. |
---|
702 | * The eighth/sixteenth bit of characters is used to prevent recognition, |
---|
703 | * and eventually stripped. |
---|
704 | */ |
---|
705 | #define META 0200 |
---|
706 | #define ASCII 0177 |
---|
707 | #ifdef SHORT_STRINGS |
---|
708 | # define QUOTE ((Char) 0100000)/* 16nth char bit used for 'ing */ |
---|
709 | # define TRIM 0077777 /* Mask to strip quote bit */ |
---|
710 | # define UNDER 0040000 /* Underline flag */ |
---|
711 | # define BOLD 0020000 /* Bold flag */ |
---|
712 | # define STANDOUT 0010000 /* Standout flag */ |
---|
713 | # define LITERAL 0004000 /* Literal character flag */ |
---|
714 | # define ATTRIBUTES 0074000 /* The bits used for attributes */ |
---|
715 | # define CHAR 0000377 /* Mask to mask out the character */ |
---|
716 | #else |
---|
717 | # define QUOTE ((Char) 0200) /* Eighth char bit used for 'ing */ |
---|
718 | # define TRIM 0177 /* Mask to strip quote bit */ |
---|
719 | # define UNDER 0000000 /* No extra bits to do both */ |
---|
720 | # define BOLD 0000000 /* Bold flag */ |
---|
721 | # define STANDOUT META /* Standout flag */ |
---|
722 | # define LITERAL 0000000 /* Literal character flag */ |
---|
723 | # define ATTRIBUTES 0200 /* The bits used for attributes */ |
---|
724 | # define CHAR 0000177 /* Mask to mask out the character */ |
---|
725 | #endif |
---|
726 | |
---|
727 | EXTERN int AsciiOnly; /* If set only 7 bits expected in characters */ |
---|
728 | |
---|
729 | /* |
---|
730 | * Each level of input has a buffered input structure. |
---|
731 | * There are one or more blocks of buffered input for each level, |
---|
732 | * exactly one if the input is seekable and tell is available. |
---|
733 | * In other cases, the shell buffers enough blocks to keep all loops |
---|
734 | * in the buffer. |
---|
735 | */ |
---|
736 | EXTERN struct Bin { |
---|
737 | off_t Bfseekp; /* Seek pointer */ |
---|
738 | off_t Bfbobp; /* Seekp of beginning of buffers */ |
---|
739 | off_t Bfeobp; /* Seekp of end of buffers */ |
---|
740 | int Bfblocks; /* Number of buffer blocks */ |
---|
741 | Char **Bfbuf; /* The array of buffer blocks */ |
---|
742 | } B; |
---|
743 | |
---|
744 | /* |
---|
745 | * This structure allows us to seek inside aliases |
---|
746 | */ |
---|
747 | struct Ain { |
---|
748 | int type; |
---|
749 | #define I_SEEK -1 /* Invalid seek */ |
---|
750 | #define A_SEEK 0 /* Alias seek */ |
---|
751 | #define F_SEEK 1 /* File seek */ |
---|
752 | #define E_SEEK 2 /* Eval seek */ |
---|
753 | union { |
---|
754 | off_t _f_seek; |
---|
755 | Char* _c_seek; |
---|
756 | } fc; |
---|
757 | #define f_seek fc._f_seek |
---|
758 | #define c_seek fc._c_seek |
---|
759 | Char **a_seek; |
---|
760 | } ; |
---|
761 | |
---|
762 | extern int aret; /* Type of last char returned */ |
---|
763 | #define SEEKEQ(a, b) ((a)->type == (b)->type && \ |
---|
764 | (a)->f_seek == (b)->f_seek && \ |
---|
765 | (a)->a_seek == (b)->a_seek) |
---|
766 | |
---|
767 | #define fseekp B.Bfseekp |
---|
768 | #define fbobp B.Bfbobp |
---|
769 | #define feobp B.Bfeobp |
---|
770 | #define fblocks B.Bfblocks |
---|
771 | #define fbuf B.Bfbuf |
---|
772 | |
---|
773 | /* |
---|
774 | * The shell finds commands in loops by reseeking the input |
---|
775 | * For whiles, in particular, it reseeks to the beginning of the |
---|
776 | * line the while was on; hence the while placement restrictions. |
---|
777 | */ |
---|
778 | EXTERN struct Ain lineloc; |
---|
779 | |
---|
780 | EXTERN bool cantell; /* Is current source tellable ? */ |
---|
781 | |
---|
782 | /* |
---|
783 | * Input lines are parsed into doubly linked circular |
---|
784 | * lists of words of the following form. |
---|
785 | */ |
---|
786 | struct wordent { |
---|
787 | Char *word; |
---|
788 | struct wordent *prev; |
---|
789 | struct wordent *next; |
---|
790 | }; |
---|
791 | |
---|
792 | /* |
---|
793 | * During word building, both in the initial lexical phase and |
---|
794 | * when expanding $ variable substitutions, expansion by `!' and `$' |
---|
795 | * must be inhibited when reading ahead in routines which are themselves |
---|
796 | * processing `!' and `$' expansion or after characters such as `\' or in |
---|
797 | * quotations. The following flags are passed to the getC routines |
---|
798 | * telling them which of these substitutions are appropriate for the |
---|
799 | * next character to be returned. |
---|
800 | */ |
---|
801 | #define DODOL 1 |
---|
802 | #define DOEXCL 2 |
---|
803 | #define DOALL DODOL|DOEXCL |
---|
804 | |
---|
805 | /* |
---|
806 | * Labuf implements a general buffer for lookahead during lexical operations. |
---|
807 | * Text which is to be placed in the input stream can be stuck here. |
---|
808 | * We stick parsed ahead $ constructs during initial input, |
---|
809 | * process id's from `$$', and modified variable values (from qualifiers |
---|
810 | * during expansion in sh.dol.c) here. |
---|
811 | */ |
---|
812 | EXTERN Char *lap; |
---|
813 | |
---|
814 | /* |
---|
815 | * Parser structure |
---|
816 | * |
---|
817 | * Each command is parsed to a tree of command structures and |
---|
818 | * flags are set bottom up during this process, to be propagated down |
---|
819 | * as needed during the semantics/exeuction pass (sh.sem.c). |
---|
820 | */ |
---|
821 | struct command { |
---|
822 | unsigned char t_dtyp; /* Type of node */ |
---|
823 | #define NODE_COMMAND 1 /* t_dcom <t_dlef >t_drit */ |
---|
824 | #define NODE_PAREN 2 /* ( t_dspr ) <t_dlef >t_drit */ |
---|
825 | #define NODE_PIPE 3 /* t_dlef | t_drit */ |
---|
826 | #define NODE_LIST 4 /* t_dlef ; t_drit */ |
---|
827 | #define NODE_OR 5 /* t_dlef || t_drit */ |
---|
828 | #define NODE_AND 6 /* t_dlef && t_drit */ |
---|
829 | unsigned char t_nice; /* Nice value */ |
---|
830 | #ifdef apollo |
---|
831 | unsigned char t_systype; /* System environment */ |
---|
832 | #endif |
---|
833 | unsigned long t_dflg; /* Flags, e.g. F_AMPERSAND|... */ |
---|
834 | /* save these when re-doing */ |
---|
835 | #ifndef apollo |
---|
836 | #define F_SAVE (F_NICE|F_TIME|F_NOHUP|F_HUP) |
---|
837 | #else |
---|
838 | #define F_SAVE (F_NICE|F_TIME|F_NOHUP||F_HUP|F_VER) |
---|
839 | #endif |
---|
840 | #define F_AMPERSAND (1<<0) /* executes in background */ |
---|
841 | #define F_APPEND (1<<1) /* output is redirected >> */ |
---|
842 | #define F_PIPEIN (1<<2) /* input is a pipe */ |
---|
843 | #define F_PIPEOUT (1<<3) /* output is a pipe */ |
---|
844 | #define F_NOFORK (1<<4) /* don't fork, last ()ized cmd */ |
---|
845 | #define F_NOINTERRUPT (1<<5) /* should be immune from intr's */ |
---|
846 | /* spare */ |
---|
847 | #define F_STDERR (1<<7) /* redirect unit 2 with unit 1 */ |
---|
848 | #define F_OVERWRITE (1<<8) /* output was ! */ |
---|
849 | #define F_READ (1<<9) /* input redirection is << */ |
---|
850 | #define F_REPEAT (1<<10) /* reexec aft if, repeat,... */ |
---|
851 | #define F_NICE (1<<11) /* t_nice is meaningful */ |
---|
852 | #define F_NOHUP (1<<12) /* nohup this command */ |
---|
853 | #define F_TIME (1<<13) /* time this command */ |
---|
854 | #define F_BACKQ (1<<14) /* command is in `` */ |
---|
855 | #define F_HUP (1<<15) /* hup this command */ |
---|
856 | #ifdef apollo |
---|
857 | #define F_VER (1<<16) /* execute command under SYSTYPE */ |
---|
858 | #endif |
---|
859 | union { |
---|
860 | Char *T_dlef; /* Input redirect word */ |
---|
861 | struct command *T_dcar; /* Left part of list/pipe */ |
---|
862 | } L; |
---|
863 | union { |
---|
864 | Char *T_drit; /* Output redirect word */ |
---|
865 | struct command *T_dcdr; /* Right part of list/pipe */ |
---|
866 | } R; |
---|
867 | #define t_dlef L.T_dlef |
---|
868 | #define t_dcar L.T_dcar |
---|
869 | #define t_drit R.T_drit |
---|
870 | #define t_dcdr R.T_dcdr |
---|
871 | Char **t_dcom; /* Command/argument vector */ |
---|
872 | struct command *t_dspr; /* Pointer to ()'d subtree */ |
---|
873 | }; |
---|
874 | |
---|
875 | |
---|
876 | /* |
---|
877 | * The keywords for the parser |
---|
878 | */ |
---|
879 | #define TC_BREAK 0 |
---|
880 | #define TC_BRKSW 1 |
---|
881 | #define TC_CASE 2 |
---|
882 | #define TC_DEFAULT 3 |
---|
883 | #define TC_ELSE 4 |
---|
884 | #define TC_END 5 |
---|
885 | #define TC_ENDIF 6 |
---|
886 | #define TC_ENDSW 7 |
---|
887 | #define TC_EXIT 8 |
---|
888 | #define TC_FOREACH 9 |
---|
889 | #define TC_GOTO 10 |
---|
890 | #define TC_IF 11 |
---|
891 | #define TC_LABEL 12 |
---|
892 | #define TC_LET 13 |
---|
893 | #define TC_SET 14 |
---|
894 | #define TC_SWITCH 15 |
---|
895 | #define TC_TEST 16 |
---|
896 | #define TC_THEN 17 |
---|
897 | #define TC_WHILE 18 |
---|
898 | |
---|
899 | /* |
---|
900 | * These are declared here because they want to be |
---|
901 | * initialized in sh.init.c (to allow them to be made readonly) |
---|
902 | */ |
---|
903 | |
---|
904 | #if defined(hpux) && defined(__STDC__) && !defined(__GNUC__) |
---|
905 | /* Avoid hpux ansi mode spurious warnings */ |
---|
906 | typedef void (*bfunc_t) (); |
---|
907 | #else |
---|
908 | typedef void (*bfunc_t) __P((Char **, struct command *)); |
---|
909 | #endif /* hpux && __STDC__ && !__GNUC__ */ |
---|
910 | |
---|
911 | extern struct biltins { |
---|
912 | char *bname; |
---|
913 | bfunc_t bfunct; |
---|
914 | int minargs, maxargs; |
---|
915 | } bfunc[]; |
---|
916 | extern int nbfunc; |
---|
917 | #ifdef WINNT |
---|
918 | extern struct biltins nt_bfunc[]; |
---|
919 | extern int nt_nbfunc; |
---|
920 | #endif /* WINNT*/ |
---|
921 | |
---|
922 | extern struct srch { |
---|
923 | char *s_name; |
---|
924 | int s_value; |
---|
925 | } srchn[]; |
---|
926 | extern int nsrchn; |
---|
927 | |
---|
928 | /* |
---|
929 | * Structure defining the existing while/foreach loops at this |
---|
930 | * source level. Loops are implemented by seeking back in the |
---|
931 | * input. For foreach (fe), the word list is attached here. |
---|
932 | */ |
---|
933 | EXTERN struct whyle { |
---|
934 | struct Ain w_start; /* Point to restart loop */ |
---|
935 | struct Ain w_end; /* End of loop (0 if unknown) */ |
---|
936 | Char **w_fe, **w_fe0; /* Current/initial wordlist for fe */ |
---|
937 | Char *w_fename; /* Name for fe */ |
---|
938 | struct whyle *w_next; /* Next (more outer) loop */ |
---|
939 | } *whyles; |
---|
940 | |
---|
941 | /* |
---|
942 | * Variable structure |
---|
943 | * |
---|
944 | * Aliases and variables are stored in AVL balanced binary trees. |
---|
945 | */ |
---|
946 | EXTERN struct varent { |
---|
947 | Char **vec; /* Array of words which is the value */ |
---|
948 | Char *v_name; /* Name of variable/alias */ |
---|
949 | int v_flags; /* Flags */ |
---|
950 | #define VAR_ALL -1 |
---|
951 | #define VAR_READONLY 1 |
---|
952 | #define VAR_READWRITE 2 |
---|
953 | #define VAR_NOGLOB 4 |
---|
954 | #define VAR_FIRST 32 |
---|
955 | #define VAR_LAST 64 |
---|
956 | struct varent *v_link[3]; /* The links, see below */ |
---|
957 | int v_bal; /* Balance factor */ |
---|
958 | } shvhed IZERO_STRUCT, aliases IZERO_STRUCT; |
---|
959 | |
---|
960 | #define v_left v_link[0] |
---|
961 | #define v_right v_link[1] |
---|
962 | #define v_parent v_link[2] |
---|
963 | |
---|
964 | #define adrof(v) adrof1(v, &shvhed) |
---|
965 | #define varval(v) value1(v, &shvhed) |
---|
966 | |
---|
967 | /* |
---|
968 | * The following are for interfacing redo substitution in |
---|
969 | * aliases to the lexical routines. |
---|
970 | */ |
---|
971 | EXTERN struct wordent *alhistp IZERO_STRUCT;/* Argument list (first) */ |
---|
972 | EXTERN struct wordent *alhistt IZERO_STRUCT;/* Node after last in arg list */ |
---|
973 | EXTERN Char **alvec IZERO_STRUCT, |
---|
974 | *alvecp IZERO_STRUCT;/* The (remnants of) alias vector */ |
---|
975 | |
---|
976 | /* |
---|
977 | * Filename/command name expansion variables |
---|
978 | */ |
---|
979 | EXTERN int gflag; /* After tglob -> is globbing needed? */ |
---|
980 | |
---|
981 | #define MAXVARLEN 30 /* Maximum number of char in a variable name */ |
---|
982 | |
---|
983 | #ifndef MAXPATHLEN |
---|
984 | # define MAXPATHLEN 2048 |
---|
985 | #endif /* MAXPATHLEN */ |
---|
986 | |
---|
987 | #ifndef MAXNAMLEN |
---|
988 | # define MAXNAMLEN 512 |
---|
989 | #endif /* MAXNAMLEN */ |
---|
990 | |
---|
991 | #ifndef HAVENOLIMIT |
---|
992 | /* |
---|
993 | * resource limits |
---|
994 | */ |
---|
995 | extern struct limits { |
---|
996 | int limconst; |
---|
997 | char *limname; |
---|
998 | int limdiv; |
---|
999 | char *limscale; |
---|
1000 | } limits[]; |
---|
1001 | #endif /* !HAVENOLIMIT */ |
---|
1002 | |
---|
1003 | /* |
---|
1004 | * Variables for filename expansion |
---|
1005 | */ |
---|
1006 | extern Char **gargv; /* Pointer to the (stack) arglist */ |
---|
1007 | extern int gargc; /* Number args in gargv */ |
---|
1008 | |
---|
1009 | /* |
---|
1010 | * Variables for command expansion. |
---|
1011 | */ |
---|
1012 | extern Char **pargv; /* Pointer to the argv list space */ |
---|
1013 | EXTERN Char *pargs; /* Pointer to start current word */ |
---|
1014 | EXTERN long pnleft; /* Number of chars left in pargs */ |
---|
1015 | EXTERN Char *pargcp; /* Current index into pargs */ |
---|
1016 | |
---|
1017 | /* |
---|
1018 | * History list |
---|
1019 | * |
---|
1020 | * Each history list entry contains an embedded wordlist |
---|
1021 | * from the scanner, a number for the event, and a reference count |
---|
1022 | * to aid in discarding old entries. |
---|
1023 | * |
---|
1024 | * Essentially "invisible" entries are put on the history list |
---|
1025 | * when history substitution includes modifiers, and thrown away |
---|
1026 | * at the next discarding since their event numbers are very negative. |
---|
1027 | */ |
---|
1028 | EXTERN struct Hist { |
---|
1029 | struct wordent Hlex; |
---|
1030 | int Hnum; |
---|
1031 | int Href; |
---|
1032 | time_t Htime; |
---|
1033 | Char *histline; |
---|
1034 | struct Hist *Hnext; |
---|
1035 | } Histlist IZERO_STRUCT; |
---|
1036 | |
---|
1037 | EXTERN struct wordent paraml; /* Current lexical word list */ |
---|
1038 | EXTERN int eventno; /* Next events number */ |
---|
1039 | EXTERN int lastev; /* Last event reference (default) */ |
---|
1040 | |
---|
1041 | EXTERN Char HIST; /* history invocation character */ |
---|
1042 | EXTERN Char HISTSUB; /* auto-substitute character */ |
---|
1043 | EXTERN Char PRCH; /* Prompt symbol for regular users */ |
---|
1044 | EXTERN Char PRCHROOT; /* Prompt symbol for root */ |
---|
1045 | |
---|
1046 | /* |
---|
1047 | * For operating systems with single case filenames (OS/2) |
---|
1048 | */ |
---|
1049 | #ifdef CASE_INSENSITIVE |
---|
1050 | # define samecase(x) (isupper((unsigned char)(x)) ? \ |
---|
1051 | tolower((unsigned char)(x)) : (x)) |
---|
1052 | #else |
---|
1053 | # define samecase(x) (x) |
---|
1054 | #endif /* CASE_INSENSITIVE */ |
---|
1055 | |
---|
1056 | /* |
---|
1057 | * strings.h: |
---|
1058 | */ |
---|
1059 | #ifndef SHORT_STRINGS |
---|
1060 | #define Strchr(a, b) strchr(a, b) |
---|
1061 | #define Strrchr(a, b) strrchr(a, b) |
---|
1062 | #define Strcat(a, b) strcat(a, b) |
---|
1063 | #define Strncat(a, b, c) strncat(a, b, c) |
---|
1064 | #define Strcpy(a, b) strcpy(a, b) |
---|
1065 | #define Strncpy(a, b, c) strncpy(a, b, c) |
---|
1066 | #define Strlen(a) strlen(a) |
---|
1067 | #define Strcmp(a, b) strcmp(a, b) |
---|
1068 | #define Strncmp(a, b, c) strncmp(a, b, c) |
---|
1069 | |
---|
1070 | #define Strspl(a, b) strspl(a, b) |
---|
1071 | #define Strsave(a) strsave(a) |
---|
1072 | #define Strend(a) strend(a) |
---|
1073 | #define Strstr(a, b) strstr(a, b) |
---|
1074 | |
---|
1075 | #define str2short(a) (a) |
---|
1076 | #define blk2short(a) saveblk(a) |
---|
1077 | #define short2blk(a) saveblk(a) |
---|
1078 | #define short2str(a) strip(a) |
---|
1079 | #else |
---|
1080 | #define Strchr(a, b) s_strchr(a, b) |
---|
1081 | #define Strrchr(a, b) s_strrchr(a, b) |
---|
1082 | #define Strcat(a, b) s_strcat(a, b) |
---|
1083 | #define Strncat(a, b, c) s_strncat(a, b, c) |
---|
1084 | #define Strcpy(a, b) s_strcpy(a, b) |
---|
1085 | #define Strncpy(a, b, c) s_strncpy(a, b, c) |
---|
1086 | #define Strlen(a) s_strlen(a) |
---|
1087 | #define Strcmp(a, b) s_strcmp(a, b) |
---|
1088 | #define Strncmp(a, b, c) s_strncmp(a, b, c) |
---|
1089 | |
---|
1090 | #define Strspl(a, b) s_strspl(a, b) |
---|
1091 | #define Strsave(a) s_strsave(a) |
---|
1092 | #define Strend(a) s_strend(a) |
---|
1093 | #define Strstr(a, b) s_strstr(a, b) |
---|
1094 | #endif |
---|
1095 | |
---|
1096 | /* |
---|
1097 | * setname is a macro to save space (see sh.err.c) |
---|
1098 | */ |
---|
1099 | EXTERN char *bname; |
---|
1100 | |
---|
1101 | #define setname(a) (bname = (a)) |
---|
1102 | |
---|
1103 | #ifdef VFORK |
---|
1104 | EXTERN Char *Vsav; |
---|
1105 | EXTERN Char *Vdp; |
---|
1106 | EXTERN Char *Vexpath; |
---|
1107 | EXTERN char **Vt; |
---|
1108 | #endif /* VFORK */ |
---|
1109 | |
---|
1110 | EXTERN Char **evalvec; |
---|
1111 | EXTERN Char *evalp; |
---|
1112 | |
---|
1113 | extern struct mesg { |
---|
1114 | char *iname; /* name from /usr/include */ |
---|
1115 | char *pname; /* print name */ |
---|
1116 | } mesg[]; |
---|
1117 | |
---|
1118 | /* word_chars is set by default to WORD_CHARS but can be overridden by |
---|
1119 | the worchars variable--if unset, reverts to WORD_CHARS */ |
---|
1120 | |
---|
1121 | EXTERN Char *word_chars; |
---|
1122 | |
---|
1123 | #define WORD_CHARS "*?_-.[]~=" /* default chars besides alnums in words */ |
---|
1124 | |
---|
1125 | EXTERN Char *STR_SHELLPATH; |
---|
1126 | |
---|
1127 | #ifdef _PATH_BSHELL |
---|
1128 | EXTERN Char *STR_BSHELL; |
---|
1129 | #endif |
---|
1130 | EXTERN Char *STR_WORD_CHARS; |
---|
1131 | EXTERN Char **STR_environ IZERO; |
---|
1132 | |
---|
1133 | extern int dont_free; /* Tell free that we are in danger if we free */ |
---|
1134 | |
---|
1135 | extern Char *INVPTR; |
---|
1136 | extern Char **INVPPTR; |
---|
1137 | |
---|
1138 | extern char *progname; |
---|
1139 | extern int tcsh; |
---|
1140 | |
---|
1141 | #include "tc.h" |
---|
1142 | #include "sh.decls.h" |
---|
1143 | |
---|
1144 | /* |
---|
1145 | * To print system call errors... |
---|
1146 | */ |
---|
1147 | #ifdef __NetBSD__ |
---|
1148 | # include <errno.h> |
---|
1149 | #else |
---|
1150 | # ifndef linux |
---|
1151 | # ifdef NEEDstrerror |
---|
1152 | extern char *sys_errlist[]; |
---|
1153 | # endif |
---|
1154 | extern int errno, sys_nerr; |
---|
1155 | # endif /* !linux */ |
---|
1156 | #endif |
---|
1157 | |
---|
1158 | #ifndef WINNT |
---|
1159 | # ifdef NLS_CATALOGS |
---|
1160 | # ifdef linux |
---|
1161 | # include <locale.h> |
---|
1162 | # ifdef notdef |
---|
1163 | # include <localeinfo.h> /* Has this changed ? */ |
---|
1164 | # endif |
---|
1165 | # include <features.h> |
---|
1166 | # endif |
---|
1167 | # ifdef SUNOS4 |
---|
1168 | /* Who stole my nl_types.h? :-( |
---|
1169 | * All this stuff is in the man pages, but nowhere else? |
---|
1170 | * This does not link right now... |
---|
1171 | */ |
---|
1172 | typedef void *nl_catd; |
---|
1173 | extern const char * catgets __P((nl_catd, int, int, const char *)); |
---|
1174 | nl_catd catopen __P((const char *, int)); |
---|
1175 | int catclose __P((nl_catd)); |
---|
1176 | # else |
---|
1177 | # ifdef __uxps__ |
---|
1178 | # define gettxt gettxt_ds |
---|
1179 | # endif |
---|
1180 | # include <nl_types.h> |
---|
1181 | # ifdef __uxps__ |
---|
1182 | # undef gettxt |
---|
1183 | # endif |
---|
1184 | # endif |
---|
1185 | # ifndef MCLoadBySet |
---|
1186 | # define MCLoadBySet 0 |
---|
1187 | # endif |
---|
1188 | EXTERN nl_catd catd; |
---|
1189 | # define CGETS(b, c, d) catgets(catd, b, c, d) |
---|
1190 | # define CSAVS(b, c, d) strsave(CGETS(b, c, d)) |
---|
1191 | # else |
---|
1192 | # define CGETS(b, c, d) d |
---|
1193 | # define CSAVS(b, c, d) d |
---|
1194 | # endif |
---|
1195 | #else /* WINNT */ |
---|
1196 | # define CGETS(b, c, d) nt_cgets( b, c, d) |
---|
1197 | # define CSAVS(b, c, d) strsave(CGETS(b, c, d)) |
---|
1198 | #endif /* WINNT */ |
---|
1199 | |
---|
1200 | /* |
---|
1201 | * Since on some machines characters are unsigned, and the signed |
---|
1202 | * keyword is not universally implemented, we treat all characters |
---|
1203 | * as unsigned and sign extend them where we need. |
---|
1204 | */ |
---|
1205 | #define SIGN_EXTEND_CHAR(a) (((a) & 0x80) ? ((a) | ~0x7f) : (a)) |
---|
1206 | |
---|
1207 | #endif /* _h_sh */ |
---|