xref: /titanic_53/usr/src/cmd/csh/sh.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
8*7c478bd9Sstevel@tonic-gate 
9*7c478bd9Sstevel@tonic-gate /*
10*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
11*7c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
12*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
13*7c478bd9Sstevel@tonic-gate  */
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include <stdlib.h>	 /* MB_xxx, mbxxx(), wcxxx() etc. */
18*7c478bd9Sstevel@tonic-gate #include <limits.h>
19*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
20*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
21*7c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
22*7c478bd9Sstevel@tonic-gate #include <sys/ucontext.h>
23*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
24*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
25*7c478bd9Sstevel@tonic-gate #include <sys/termios.h>
26*7c478bd9Sstevel@tonic-gate #include <sys/ttold.h>
27*7c478bd9Sstevel@tonic-gate #include <errno.h>
28*7c478bd9Sstevel@tonic-gate #include <signal.h>	/* std sysV signal.h */
29*7c478bd9Sstevel@tonic-gate #include <setjmp.h>
30*7c478bd9Sstevel@tonic-gate #include <sys/resource.h>
31*7c478bd9Sstevel@tonic-gate #include "signal.h"	/* mainly BSD related signal.h */
32*7c478bd9Sstevel@tonic-gate #include "sh.local.h"
33*7c478bd9Sstevel@tonic-gate #include "sh.char.h"
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate /*
36*7c478bd9Sstevel@tonic-gate  * MAXHOSTNAMELEN is defined in param.h under SunOS
37*7c478bd9Sstevel@tonic-gate  */
38*7c478bd9Sstevel@tonic-gate #define	MAXHOSTNAMELEN	64
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #ifdef MBCHAR
41*7c478bd9Sstevel@tonic-gate # if !defined(MB_LEN_MAX) || !defined(MB_CUR_MAX)
42*7c478bd9Sstevel@tonic-gate 	Error: I need both ANSI macros!
43*7c478bd9Sstevel@tonic-gate # endif
44*7c478bd9Sstevel@tonic-gate #else
45*7c478bd9Sstevel@tonic-gate # if !defined(MB_LEN_MAX)
46*7c478bd9Sstevel@tonic-gate #  define MB_LEN_MAX	1
47*7c478bd9Sstevel@tonic-gate # endif
48*7c478bd9Sstevel@tonic-gate # if !defined(MB_CUR_MAX)
49*7c478bd9Sstevel@tonic-gate #  define MB_CUR_MAX	1
50*7c478bd9Sstevel@tonic-gate # endif
51*7c478bd9Sstevel@tonic-gate #endif
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #ifndef MBCHAR /* Let's replace the ANSI functions with our own macro
54*7c478bd9Sstevel@tonic-gate 		* for efficiency!
55*7c478bd9Sstevel@tonic-gate 		*/
56*7c478bd9Sstevel@tonic-gate #define	mbtowc(pwc, pmb, n_is_ignored)	((*(pwc)=*(pmb)), 1)
57*7c478bd9Sstevel@tonic-gate #define	wctomb(pmb, wc)			((*(pmb)=((char)wc)), 1)
58*7c478bd9Sstevel@tonic-gate #endif/*!MBCHAR*/
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate /*
61*7c478bd9Sstevel@tonic-gate  * C shell
62*7c478bd9Sstevel@tonic-gate  *
63*7c478bd9Sstevel@tonic-gate  * Bill Joy, UC Berkeley
64*7c478bd9Sstevel@tonic-gate  * October, 1978; May 1980
65*7c478bd9Sstevel@tonic-gate  *
66*7c478bd9Sstevel@tonic-gate  * Jim Kulp, IIASA, Laxenburg Austria
67*7c478bd9Sstevel@tonic-gate  * April, 1980
68*7c478bd9Sstevel@tonic-gate  */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*If we are setting the $cwd variable becuz we did a
71*7c478bd9Sstevel@tonic-gate   cd, chdir, pushd, popd command, then set didchdir to
72*7c478bd9Sstevel@tonic-gate   1.  This prevents globbing down when setting $cwd.
73*7c478bd9Sstevel@tonic-gate   However, if the user set $cwd, we want the globbing
74*7c478bd9Sstevel@tonic-gate   done; so, didchdir would be equal to 0 in that case.
75*7c478bd9Sstevel@tonic-gate  */
76*7c478bd9Sstevel@tonic-gate int didchdir;
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate #define	isdir(d)	((d.st_mode & S_IFMT) == S_IFDIR)
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate typedef	char	bool;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate /* tchar (Tagged CHARacter) is a place holder to keep a QUOTE bit and
83*7c478bd9Sstevel@tonic-gate  * a character.
84*7c478bd9Sstevel@tonic-gate  * For European language handling, lower 8 bits of tchar is used
85*7c478bd9Sstevel@tonic-gate  * to store a character.  For other languages, especially Asian, 16 bits
86*7c478bd9Sstevel@tonic-gate  * are used to store a character.
87*7c478bd9Sstevel@tonic-gate  * Following typedef's assume short int is a 16-bit entity and long int is
88*7c478bd9Sstevel@tonic-gate  * a 32-bit entity.
89*7c478bd9Sstevel@tonic-gate  * The QUOTE bit tells whether the character is subject to further
90*7c478bd9Sstevel@tonic-gate  * interpretation such as history substitution, file mathing, command
91*7c478bd9Sstevel@tonic-gate  * subsitution.  TRIM is a mask to strip off the QUOTE bit.
92*7c478bd9Sstevel@tonic-gate  */
93*7c478bd9Sstevel@tonic-gate #ifdef MBCHAR		/* For multibyte character handling. */
94*7c478bd9Sstevel@tonic-gate typedef long int	tchar;
95*7c478bd9Sstevel@tonic-gate #define QUOTE	0x80000000
96*7c478bd9Sstevel@tonic-gate #define	TRIM	0x7fffffff
97*7c478bd9Sstevel@tonic-gate #else/*!MBCHAR*/	/* European language requires only 8 bits. */
98*7c478bd9Sstevel@tonic-gate typedef unsigned short int	tchar;
99*7c478bd9Sstevel@tonic-gate #define	QUOTE	0x8000
100*7c478bd9Sstevel@tonic-gate #define	TRIM	0x00ff
101*7c478bd9Sstevel@tonic-gate #endif/*!MBCHAR*/
102*7c478bd9Sstevel@tonic-gate #define	eq(a, b)	(strcmp_(a, b) == 0)
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate extern	int	Putchar(tchar);
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate  * Global flags
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate bool	chkstop;		/* Warned of stopped jobs... allow exit */
110*7c478bd9Sstevel@tonic-gate bool	didfds;			/* Have setup i/o fd's for child */
111*7c478bd9Sstevel@tonic-gate bool	doneinp;		/* EOF indicator after reset from readc */
112*7c478bd9Sstevel@tonic-gate bool	exiterr;		/* Exit if error or non-zero exit status */
113*7c478bd9Sstevel@tonic-gate bool	child;			/* Child shell ... errors cause exit */
114*7c478bd9Sstevel@tonic-gate bool	haderr;			/* Reset was because of an error */
115*7c478bd9Sstevel@tonic-gate bool	intty;			/* Input is a tty */
116*7c478bd9Sstevel@tonic-gate bool	cflg;			/* invoked with -c option */
117*7c478bd9Sstevel@tonic-gate bool	intact;			/* We are interactive... therefore prompt */
118*7c478bd9Sstevel@tonic-gate bool	justpr;			/* Just print because of :p hist mod */
119*7c478bd9Sstevel@tonic-gate bool	loginsh;		/* We are a loginsh -> .login/.logout */
120*7c478bd9Sstevel@tonic-gate bool	neednote;		/* Need to pnotify() */
121*7c478bd9Sstevel@tonic-gate bool	noexec;			/* Don't execute, just syntax check */
122*7c478bd9Sstevel@tonic-gate bool	pjobs;			/* want to print jobs if interrupted */
123*7c478bd9Sstevel@tonic-gate bool	pfcshflag;		/* set to 0 for pfcsh */
124*7c478bd9Sstevel@tonic-gate bool	setintr;		/* Set interrupts on/off -> Wait intr... */
125*7c478bd9Sstevel@tonic-gate bool	timflg;			/* Time the next waited for command */
126*7c478bd9Sstevel@tonic-gate bool	havhash;		/* path hashing is available */
127*7c478bd9Sstevel@tonic-gate bool	havhash2;		/* cdpath hashing is available */
128*7c478bd9Sstevel@tonic-gate #ifdef FILEC
129*7c478bd9Sstevel@tonic-gate bool	filec;			/* doing filename expansion */
130*7c478bd9Sstevel@tonic-gate #endif
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate /*
133*7c478bd9Sstevel@tonic-gate  * Global i/o info
134*7c478bd9Sstevel@tonic-gate  */
135*7c478bd9Sstevel@tonic-gate tchar	*arginp;		/* Argument input for sh -c and internal `xx` */
136*7c478bd9Sstevel@tonic-gate int	onelflg;		/* 2 -> need line for -t, 1 -> exit on read */
137*7c478bd9Sstevel@tonic-gate tchar	*file;			/* Name of shell file for $0 */
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate char	*err;			/* Error message from scanner/parser */
140*7c478bd9Sstevel@tonic-gate struct	timeval time0;		/* Time at which the shell started */
141*7c478bd9Sstevel@tonic-gate struct	rusage ru0;
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate /*
144*7c478bd9Sstevel@tonic-gate  * Miscellany
145*7c478bd9Sstevel@tonic-gate  */
146*7c478bd9Sstevel@tonic-gate tchar	*doldol;		/* Character pid for $$ */
147*7c478bd9Sstevel@tonic-gate int	uid;			/* Invokers uid */
148*7c478bd9Sstevel@tonic-gate time_t	chktim;			/* Time mail last checked */
149*7c478bd9Sstevel@tonic-gate int	shpgrp;			/* Pgrp of shell */
150*7c478bd9Sstevel@tonic-gate int	tpgrp;			/* Terminal process group */
151*7c478bd9Sstevel@tonic-gate /* If tpgrp is -1, leave tty alone! */
152*7c478bd9Sstevel@tonic-gate int	opgrp;			/* Initial pgrp and tty pgrp */
153*7c478bd9Sstevel@tonic-gate int	oldisc;			/* Initial line discipline or -1 */
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate /*
156*7c478bd9Sstevel@tonic-gate  * These are declared here because they want to be
157*7c478bd9Sstevel@tonic-gate  * initialized in sh.init.c (to allow them to be made readonly)
158*7c478bd9Sstevel@tonic-gate  */
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate extern struct	biltins {
161*7c478bd9Sstevel@tonic-gate 	tchar	*bname;
162*7c478bd9Sstevel@tonic-gate 	int	(*bfunct)();
163*7c478bd9Sstevel@tonic-gate 	short	minargs, maxargs;
164*7c478bd9Sstevel@tonic-gate } bfunc[];
165*7c478bd9Sstevel@tonic-gate extern int nbfunc;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate extern struct srch {
168*7c478bd9Sstevel@tonic-gate 	tchar	*s_name;
169*7c478bd9Sstevel@tonic-gate 	short	s_value;
170*7c478bd9Sstevel@tonic-gate } srchn[];
171*7c478bd9Sstevel@tonic-gate extern int nsrchn;
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate /*
174*7c478bd9Sstevel@tonic-gate  * To be able to redirect i/o for builtins easily, the shell moves the i/o
175*7c478bd9Sstevel@tonic-gate  * descriptors it uses away from 0,1,2.
176*7c478bd9Sstevel@tonic-gate  * Ideally these should be in units which are closed across exec's
177*7c478bd9Sstevel@tonic-gate  * (this saves work) but for version 6, this is not usually possible.
178*7c478bd9Sstevel@tonic-gate  * The desired initial values for these descriptors are defined in
179*7c478bd9Sstevel@tonic-gate  * sh.local.h.
180*7c478bd9Sstevel@tonic-gate  */
181*7c478bd9Sstevel@tonic-gate short	SHIN;			/* Current shell input (script) */
182*7c478bd9Sstevel@tonic-gate short	SHOUT;			/* Shell output */
183*7c478bd9Sstevel@tonic-gate short	SHDIAG;			/* Diagnostic output... shell errs go here */
184*7c478bd9Sstevel@tonic-gate short	OLDSTD;			/* Old standard input (def for cmds) */
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate /*
187*7c478bd9Sstevel@tonic-gate  * Error control
188*7c478bd9Sstevel@tonic-gate  *
189*7c478bd9Sstevel@tonic-gate  * Errors in scanning and parsing set up an error message to be printed
190*7c478bd9Sstevel@tonic-gate  * at the end and complete.  Other errors always cause a reset.
191*7c478bd9Sstevel@tonic-gate  * Because of source commands and .cshrc we need nested error catches.
192*7c478bd9Sstevel@tonic-gate  */
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate jmp_buf	reslab;
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate #define	setexit()	((void) setjmp(reslab))
197*7c478bd9Sstevel@tonic-gate #define	reset()		longjmp(reslab, 0)
198*7c478bd9Sstevel@tonic-gate 	/* Should use structure assignment here */
199*7c478bd9Sstevel@tonic-gate #define	getexit(a)	copy((void *)(a), (void *)reslab, sizeof reslab)
200*7c478bd9Sstevel@tonic-gate #define	resexit(a)	copy((void *)reslab, ((void *)(a)), sizeof reslab)
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate tchar	*gointr;		/* Label for an onintr transfer */
203*7c478bd9Sstevel@tonic-gate void	(*parintr)();		/* Parents interrupt catch */
204*7c478bd9Sstevel@tonic-gate void	(*parterm)();		/* Parents terminate catch */
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate /*
208*7c478bd9Sstevel@tonic-gate  * Each level of input has a buffered input structure.
209*7c478bd9Sstevel@tonic-gate  * There are one or more blocks of buffered input for each level,
210*7c478bd9Sstevel@tonic-gate  * exactly one if the input is seekable and tell is available.
211*7c478bd9Sstevel@tonic-gate  * In other cases, the shell buffers enough blocks to keep all loops
212*7c478bd9Sstevel@tonic-gate  * in the buffer.
213*7c478bd9Sstevel@tonic-gate  */
214*7c478bd9Sstevel@tonic-gate struct	Bin {
215*7c478bd9Sstevel@tonic-gate 	off_t	Bfseekp;		/* Seek pointer */
216*7c478bd9Sstevel@tonic-gate 	off_t	Bfbobp;			/* Seekp of beginning of buffers */
217*7c478bd9Sstevel@tonic-gate 	off_t	Bfeobp;			/* Seekp of end of buffers */
218*7c478bd9Sstevel@tonic-gate 	short	Bfblocks;		/* Number of buffer blocks */
219*7c478bd9Sstevel@tonic-gate 	tchar	**Bfbuf;		/* The array of buffer blocks */
220*7c478bd9Sstevel@tonic-gate } B;
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate #define	fseekp	B.Bfseekp
223*7c478bd9Sstevel@tonic-gate #define	fbobp	B.Bfbobp
224*7c478bd9Sstevel@tonic-gate #define	feobp	B.Bfeobp
225*7c478bd9Sstevel@tonic-gate #define	fblocks	B.Bfblocks
226*7c478bd9Sstevel@tonic-gate #define	fbuf	B.Bfbuf
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate #define btell()	fseekp
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate #ifndef btell
231*7c478bd9Sstevel@tonic-gate off_t	btell();
232*7c478bd9Sstevel@tonic-gate #endif
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate /*
235*7c478bd9Sstevel@tonic-gate  * The shell finds commands in loops by reseeking the input
236*7c478bd9Sstevel@tonic-gate  * For whiles, in particular, it reseeks to the beginning of the
237*7c478bd9Sstevel@tonic-gate  * line the while was on; hence the while placement restrictions.
238*7c478bd9Sstevel@tonic-gate  */
239*7c478bd9Sstevel@tonic-gate off_t	lineloc;
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate #ifdef	TELL
242*7c478bd9Sstevel@tonic-gate bool	cantell;			/* Is current source tellable ? */
243*7c478bd9Sstevel@tonic-gate #endif
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate /*
246*7c478bd9Sstevel@tonic-gate  * Input lines are parsed into doubly linked circular
247*7c478bd9Sstevel@tonic-gate  * lists of words of the following form.
248*7c478bd9Sstevel@tonic-gate  */
249*7c478bd9Sstevel@tonic-gate struct	wordent {
250*7c478bd9Sstevel@tonic-gate 	tchar	*word;
251*7c478bd9Sstevel@tonic-gate 	struct	wordent *prev;
252*7c478bd9Sstevel@tonic-gate 	struct	wordent *next;
253*7c478bd9Sstevel@tonic-gate };
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate /*
256*7c478bd9Sstevel@tonic-gate  * During word building, both in the initial lexical phase and
257*7c478bd9Sstevel@tonic-gate  * when expanding $ variable substitutions, expansion by `!' and `$'
258*7c478bd9Sstevel@tonic-gate  * must be inhibited when reading ahead in routines which are themselves
259*7c478bd9Sstevel@tonic-gate  * processing `!' and `$' expansion or after characters such as `\' or in
260*7c478bd9Sstevel@tonic-gate  * quotations.  The following flags are passed to the getC routines
261*7c478bd9Sstevel@tonic-gate  * telling them which of these substitutions are appropriate for the
262*7c478bd9Sstevel@tonic-gate  * next character to be returned.
263*7c478bd9Sstevel@tonic-gate  */
264*7c478bd9Sstevel@tonic-gate #define	DODOL	1
265*7c478bd9Sstevel@tonic-gate #define	DOEXCL	2
266*7c478bd9Sstevel@tonic-gate #define	DOALL	DODOL|DOEXCL
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate /*
269*7c478bd9Sstevel@tonic-gate  * Labuf implements a general buffer for lookahead during lexical operations.
270*7c478bd9Sstevel@tonic-gate  * Text which is to be placed in the input stream can be stuck here.
271*7c478bd9Sstevel@tonic-gate  * We stick parsed ahead $ constructs during initial input,
272*7c478bd9Sstevel@tonic-gate  * process id's from `$$', and modified variable values (from qualifiers
273*7c478bd9Sstevel@tonic-gate  * during expansion in sh.dol.c) here.
274*7c478bd9Sstevel@tonic-gate  */
275*7c478bd9Sstevel@tonic-gate tchar	*labuf;
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate tchar	*lap;
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate /*
280*7c478bd9Sstevel@tonic-gate  * Parser structure
281*7c478bd9Sstevel@tonic-gate  *
282*7c478bd9Sstevel@tonic-gate  * Each command is parsed to a tree of command structures and
283*7c478bd9Sstevel@tonic-gate  * flags are set bottom up during this process, to be propagated down
284*7c478bd9Sstevel@tonic-gate  * as needed during the semantics/exeuction pass (sh.sem.c).
285*7c478bd9Sstevel@tonic-gate  */
286*7c478bd9Sstevel@tonic-gate struct	command {
287*7c478bd9Sstevel@tonic-gate 	short	t_dtyp;				/* Type of node */
288*7c478bd9Sstevel@tonic-gate 	short	t_dflg;				/* Flags, e.g. FAND|... */
289*7c478bd9Sstevel@tonic-gate 	union {
290*7c478bd9Sstevel@tonic-gate 		tchar	*T_dlef;		/* Input redirect word */
291*7c478bd9Sstevel@tonic-gate 		struct	command *T_dcar;	/* Left part of list/pipe */
292*7c478bd9Sstevel@tonic-gate 	} L;
293*7c478bd9Sstevel@tonic-gate 	union {
294*7c478bd9Sstevel@tonic-gate 		tchar	*T_drit;		/* Output redirect word */
295*7c478bd9Sstevel@tonic-gate 		struct	command *T_dcdr;	/* Right part of list/pipe */
296*7c478bd9Sstevel@tonic-gate 	} R;
297*7c478bd9Sstevel@tonic-gate #define	t_dlef	L.T_dlef
298*7c478bd9Sstevel@tonic-gate #define	t_dcar	L.T_dcar
299*7c478bd9Sstevel@tonic-gate #define	t_drit	R.T_drit
300*7c478bd9Sstevel@tonic-gate #define	t_dcdr	R.T_dcdr
301*7c478bd9Sstevel@tonic-gate 	tchar	**t_dcom;			/* Command/argument vector */
302*7c478bd9Sstevel@tonic-gate 	char	*cfname;			/* char pathname for execv */
303*7c478bd9Sstevel@tonic-gate 	char	**cargs;			/* char arg vec  for execv */
304*7c478bd9Sstevel@tonic-gate 	struct	command *t_dspr;		/* Pointer to ()'d subtree */
305*7c478bd9Sstevel@tonic-gate 	short	t_nice;
306*7c478bd9Sstevel@tonic-gate };
307*7c478bd9Sstevel@tonic-gate 
308*7c478bd9Sstevel@tonic-gate #define	TCOM	1		/* t_dcom <t_dlef >t_drit	*/
309*7c478bd9Sstevel@tonic-gate #define	TPAR	2		/* ( t_dspr ) <t_dlef >t_drit	*/
310*7c478bd9Sstevel@tonic-gate #define	TFIL	3		/* t_dlef | t_drit		*/
311*7c478bd9Sstevel@tonic-gate #define	TLST	4		/* t_dlef ; t_drit		*/
312*7c478bd9Sstevel@tonic-gate #define	TOR	5		/* t_dlef || t_drit		*/
313*7c478bd9Sstevel@tonic-gate #define	TAND	6		/* t_dlef && t_drit		*/
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate #define	FSAVE	(FNICE|FTIME|FNOHUP)	/* save these when re-doing */
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate #define	FAND	(1<<0)		/* executes in background	*/
318*7c478bd9Sstevel@tonic-gate #define	FCAT	(1<<1)		/* output is redirected >>	*/
319*7c478bd9Sstevel@tonic-gate #define	FPIN	(1<<2)		/* input is a pipe		*/
320*7c478bd9Sstevel@tonic-gate #define	FPOU	(1<<3)		/* output is a pipe		*/
321*7c478bd9Sstevel@tonic-gate #define	FPAR	(1<<4)		/* don't fork, last ()ized cmd	*/
322*7c478bd9Sstevel@tonic-gate #define	FINT	(1<<5)		/* should be immune from intr's */
323*7c478bd9Sstevel@tonic-gate /* spare */
324*7c478bd9Sstevel@tonic-gate #define	FDIAG	(1<<7)		/* redirect unit 2 with unit 1	*/
325*7c478bd9Sstevel@tonic-gate #define	FANY	(1<<8)		/* output was !			*/
326*7c478bd9Sstevel@tonic-gate #define	FHERE	(1<<9)		/* input redirection is <<	*/
327*7c478bd9Sstevel@tonic-gate #define	FREDO	(1<<10)		/* reexec aft if, repeat,...	*/
328*7c478bd9Sstevel@tonic-gate #define	FNICE	(1<<11)		/* t_nice is meaningful */
329*7c478bd9Sstevel@tonic-gate #define	FNOHUP	(1<<12)		/* nohup this command */
330*7c478bd9Sstevel@tonic-gate #define	FTIME	(1<<13)		/* time this command */
331*7c478bd9Sstevel@tonic-gate 
332*7c478bd9Sstevel@tonic-gate /*
333*7c478bd9Sstevel@tonic-gate  * The keywords for the parser
334*7c478bd9Sstevel@tonic-gate  */
335*7c478bd9Sstevel@tonic-gate #define	ZBREAK		0
336*7c478bd9Sstevel@tonic-gate #define	ZBRKSW		1
337*7c478bd9Sstevel@tonic-gate #define	ZCASE		2
338*7c478bd9Sstevel@tonic-gate #define	ZDEFAULT 	3
339*7c478bd9Sstevel@tonic-gate #define	ZELSE		4
340*7c478bd9Sstevel@tonic-gate #define	ZEND		5
341*7c478bd9Sstevel@tonic-gate #define	ZENDIF		6
342*7c478bd9Sstevel@tonic-gate #define	ZENDSW		7
343*7c478bd9Sstevel@tonic-gate #define	ZEXIT		8
344*7c478bd9Sstevel@tonic-gate #define	ZFOREACH	9
345*7c478bd9Sstevel@tonic-gate #define	ZGOTO		10
346*7c478bd9Sstevel@tonic-gate #define	ZIF		11
347*7c478bd9Sstevel@tonic-gate #define	ZLABEL		12
348*7c478bd9Sstevel@tonic-gate #define	ZLET		13
349*7c478bd9Sstevel@tonic-gate #define	ZSET		14
350*7c478bd9Sstevel@tonic-gate #define	ZSWITCH		15
351*7c478bd9Sstevel@tonic-gate #define	ZTEST		16
352*7c478bd9Sstevel@tonic-gate #define	ZTHEN		17
353*7c478bd9Sstevel@tonic-gate #define	ZWHILE		18
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate /*
356*7c478bd9Sstevel@tonic-gate  * Structure defining the existing while/foreach loops at this
357*7c478bd9Sstevel@tonic-gate  * source level.  Loops are implemented by seeking back in the
358*7c478bd9Sstevel@tonic-gate  * input.  For foreach (fe), the word list is attached here.
359*7c478bd9Sstevel@tonic-gate  */
360*7c478bd9Sstevel@tonic-gate struct	whyle {
361*7c478bd9Sstevel@tonic-gate 	off_t	w_start;		/* Point to restart loop */
362*7c478bd9Sstevel@tonic-gate 	off_t	w_end;			/* End of loop (0 if unknown) */
363*7c478bd9Sstevel@tonic-gate 	tchar	**w_fe, **w_fe0;	/* Current/initial wordlist for fe */
364*7c478bd9Sstevel@tonic-gate 	tchar	*w_fename;		/* Name for fe */
365*7c478bd9Sstevel@tonic-gate 	struct	whyle *w_next;		/* Next (more outer) loop */
366*7c478bd9Sstevel@tonic-gate } *whyles;
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate /*
369*7c478bd9Sstevel@tonic-gate  * Variable structure
370*7c478bd9Sstevel@tonic-gate  *
371*7c478bd9Sstevel@tonic-gate  * Aliases and variables are stored in AVL balanced binary trees.
372*7c478bd9Sstevel@tonic-gate  */
373*7c478bd9Sstevel@tonic-gate struct	varent {
374*7c478bd9Sstevel@tonic-gate 	tchar	**vec;		/* Array of words which is the value */
375*7c478bd9Sstevel@tonic-gate 	tchar	*v_name;	/* Name of variable/alias */
376*7c478bd9Sstevel@tonic-gate 	struct	varent *v_link[3];	/* The links, see below */
377*7c478bd9Sstevel@tonic-gate 	int	v_bal;		/* Balance factor */
378*7c478bd9Sstevel@tonic-gate } shvhed, aliases;
379*7c478bd9Sstevel@tonic-gate #define v_left		v_link[0]
380*7c478bd9Sstevel@tonic-gate #define v_right		v_link[1]
381*7c478bd9Sstevel@tonic-gate #define v_parent	v_link[2]
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate struct varent *adrof1();
384*7c478bd9Sstevel@tonic-gate #define adrof(v)	adrof1(v, &shvhed)
385*7c478bd9Sstevel@tonic-gate #define value(v)	value1(v, &shvhed)
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate /*
388*7c478bd9Sstevel@tonic-gate  * MAX_VAR_LEN - maximum variable name defined by csh man page to be 20
389*7c478bd9Sstevel@tonic-gate  */
390*7c478bd9Sstevel@tonic-gate #define MAX_VAR_LEN           20
391*7c478bd9Sstevel@tonic-gate 
392*7c478bd9Sstevel@tonic-gate /*
393*7c478bd9Sstevel@tonic-gate  * MAX_VREF_LEN - maximum variable reference $name[...]
394*7c478bd9Sstevel@tonic-gate  * it can be as big as a csh word, which is 1024
395*7c478bd9Sstevel@tonic-gate  */
396*7c478bd9Sstevel@tonic-gate #define MAX_VREF_LEN  1024
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate /*
400*7c478bd9Sstevel@tonic-gate  * The following are for interfacing redo substitution in
401*7c478bd9Sstevel@tonic-gate  * aliases to the lexical routines.
402*7c478bd9Sstevel@tonic-gate  */
403*7c478bd9Sstevel@tonic-gate struct	wordent *alhistp;		/* Argument list (first) */
404*7c478bd9Sstevel@tonic-gate struct	wordent *alhistt;		/* Node after last in arg list */
405*7c478bd9Sstevel@tonic-gate tchar	**alvec;			/* The (remnants of) alias vector */
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate /*
408*7c478bd9Sstevel@tonic-gate  * Filename/command name expansion variables
409*7c478bd9Sstevel@tonic-gate  */
410*7c478bd9Sstevel@tonic-gate short	gflag;				/* After tglob -> is globbing needed? */
411*7c478bd9Sstevel@tonic-gate 
412*7c478bd9Sstevel@tonic-gate /*
413*7c478bd9Sstevel@tonic-gate  * A reasonable limit on number of arguments would seem to be
414*7c478bd9Sstevel@tonic-gate  * the maximum number of characters in an arg list / 6.
415*7c478bd9Sstevel@tonic-gate  *
416*7c478bd9Sstevel@tonic-gate  * XXX:	With the new VM system, NCARGS has become enormous, making
417*7c478bd9Sstevel@tonic-gate  *	it impractical to allocate arrays with NCARGS / 6 entries on
418*7c478bd9Sstevel@tonic-gate  *	the stack.  The proper fix is to revamp code elsewhere (in
419*7c478bd9Sstevel@tonic-gate  *	sh.dol.c and sh.glob.c) to use a different technique for handling
420*7c478bd9Sstevel@tonic-gate  *	command line arguments.  In the meantime, we simply fall back
421*7c478bd9Sstevel@tonic-gate  *	on using the old value of NCARGS.
422*7c478bd9Sstevel@tonic-gate  */
423*7c478bd9Sstevel@tonic-gate #ifdef	notyet
424*7c478bd9Sstevel@tonic-gate #define	GAVSIZ	(NCARGS / 6)
425*7c478bd9Sstevel@tonic-gate #else	notyet
426*7c478bd9Sstevel@tonic-gate #define	GAVSIZ	(10240 / 6)
427*7c478bd9Sstevel@tonic-gate #endif	notyet
428*7c478bd9Sstevel@tonic-gate 
429*7c478bd9Sstevel@tonic-gate /*
430*7c478bd9Sstevel@tonic-gate  * Variables for filename expansion
431*7c478bd9Sstevel@tonic-gate  */
432*7c478bd9Sstevel@tonic-gate tchar	**gargv;			/* Pointer to the (stack) arglist */
433*7c478bd9Sstevel@tonic-gate long	gargc;				/* Number args in gargv */
434*7c478bd9Sstevel@tonic-gate long	gnleft;
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate /*
437*7c478bd9Sstevel@tonic-gate  * Variables for command expansion.
438*7c478bd9Sstevel@tonic-gate  */
439*7c478bd9Sstevel@tonic-gate tchar	**pargv;			/* Pointer to the argv list space */
440*7c478bd9Sstevel@tonic-gate tchar	*pargs;				/* Pointer to start current word */
441*7c478bd9Sstevel@tonic-gate long	pargc;				/* Count of arguments in pargv */
442*7c478bd9Sstevel@tonic-gate long	pnleft;				/* Number of chars left in pargs */
443*7c478bd9Sstevel@tonic-gate tchar	*pargcp;			/* Current index into pargs */
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate /*
446*7c478bd9Sstevel@tonic-gate  * History list
447*7c478bd9Sstevel@tonic-gate  *
448*7c478bd9Sstevel@tonic-gate  * Each history list entry contains an embedded wordlist
449*7c478bd9Sstevel@tonic-gate  * from the scanner, a number for the event, and a reference count
450*7c478bd9Sstevel@tonic-gate  * to aid in discarding old entries.
451*7c478bd9Sstevel@tonic-gate  *
452*7c478bd9Sstevel@tonic-gate  * Essentially "invisible" entries are put on the history list
453*7c478bd9Sstevel@tonic-gate  * when history substitution includes modifiers, and thrown away
454*7c478bd9Sstevel@tonic-gate  * at the next discarding since their event numbers are very negative.
455*7c478bd9Sstevel@tonic-gate  */
456*7c478bd9Sstevel@tonic-gate struct	Hist {
457*7c478bd9Sstevel@tonic-gate 	struct	wordent Hlex;
458*7c478bd9Sstevel@tonic-gate 	int	Hnum;
459*7c478bd9Sstevel@tonic-gate 	int	Href;
460*7c478bd9Sstevel@tonic-gate 	struct	Hist *Hnext;
461*7c478bd9Sstevel@tonic-gate } Histlist;
462*7c478bd9Sstevel@tonic-gate 
463*7c478bd9Sstevel@tonic-gate struct	wordent	paraml;			/* Current lexical word list */
464*7c478bd9Sstevel@tonic-gate int	eventno;			/* Next events number */
465*7c478bd9Sstevel@tonic-gate int	lastev;				/* Last event reference (default) */
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate tchar	HIST;				/* history invocation character */
468*7c478bd9Sstevel@tonic-gate tchar	HISTSUB;			/* auto-substitute character */
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate /*
471*7c478bd9Sstevel@tonic-gate  * In lines for frequently called functions
472*7c478bd9Sstevel@tonic-gate  *
473*7c478bd9Sstevel@tonic-gate  * WARNING: changes here also need to occur in the xfree() function in
474*7c478bd9Sstevel@tonic-gate  *	    sh.misc.c.
475*7c478bd9Sstevel@tonic-gate  */
476*7c478bd9Sstevel@tonic-gate #if defined(sparc)
477*7c478bd9Sstevel@tonic-gate #define XFREE(cp) { \
478*7c478bd9Sstevel@tonic-gate 	extern char end[]; \
479*7c478bd9Sstevel@tonic-gate 	char stack; \
480*7c478bd9Sstevel@tonic-gate /*??*/	if (((char *)(cp)) >= end && ((char *)(cp)) < &stack) \
481*7c478bd9Sstevel@tonic-gate /*??*/		free((void *)(cp)); \
482*7c478bd9Sstevel@tonic-gate }
483*7c478bd9Sstevel@tonic-gate #elif defined(i386)
484*7c478bd9Sstevel@tonic-gate #define XFREE(cp) { \
485*7c478bd9Sstevel@tonic-gate 	extern char end[]; \
486*7c478bd9Sstevel@tonic-gate 	if (((char *)(cp)) >= end) \
487*7c478bd9Sstevel@tonic-gate 		free((void *)(cp)); \
488*7c478bd9Sstevel@tonic-gate }
489*7c478bd9Sstevel@tonic-gate #else
490*7c478bd9Sstevel@tonic-gate #error XFREE macro is machine dependant and no machine type is recognized
491*7c478bd9Sstevel@tonic-gate #endif
492*7c478bd9Sstevel@tonic-gate void	*alloctmp;
493*7c478bd9Sstevel@tonic-gate #define xalloc(i) ((alloctmp = (void *)malloc(i)) ? alloctmp : (void *)nomem(i))/*??*/
494*7c478bd9Sstevel@tonic-gate #define	xrealloc(buf, i) ((alloctmp = (void *)realloc(buf, i)) ? alloctmp : \
495*7c478bd9Sstevel@tonic-gate 				(void *)nomem(i))
496*7c478bd9Sstevel@tonic-gate 
497*7c478bd9Sstevel@tonic-gate tchar	*Dfix1();
498*7c478bd9Sstevel@tonic-gate tchar	**blkcat();
499*7c478bd9Sstevel@tonic-gate tchar	**blkcpy();
500*7c478bd9Sstevel@tonic-gate tchar	**blkend();
501*7c478bd9Sstevel@tonic-gate tchar	**blkspl();
502*7c478bd9Sstevel@tonic-gate char	**blkspl_();
503*7c478bd9Sstevel@tonic-gate void	*malloc();
504*7c478bd9Sstevel@tonic-gate tchar	*cname();
505*7c478bd9Sstevel@tonic-gate tchar	**copyblk();
506*7c478bd9Sstevel@tonic-gate tchar	**dobackp();
507*7c478bd9Sstevel@tonic-gate tchar	*domod();
508*7c478bd9Sstevel@tonic-gate struct	wordent *dosub();
509*7c478bd9Sstevel@tonic-gate tchar	*exp3();
510*7c478bd9Sstevel@tonic-gate tchar	*exp3a();
511*7c478bd9Sstevel@tonic-gate tchar	*exp4();
512*7c478bd9Sstevel@tonic-gate tchar	*exp5();
513*7c478bd9Sstevel@tonic-gate tchar	*exp6();
514*7c478bd9Sstevel@tonic-gate struct	Hist *enthist();
515*7c478bd9Sstevel@tonic-gate struct	Hist *findev();
516*7c478bd9Sstevel@tonic-gate struct	wordent *freenod();
517*7c478bd9Sstevel@tonic-gate char	*getenv();
518*7c478bd9Sstevel@tonic-gate tchar	*getenv_(/* tchar * */);
519*7c478bd9Sstevel@tonic-gate tchar	*getenvs_(/* char * */);
520*7c478bd9Sstevel@tonic-gate tchar	*getinx();
521*7c478bd9Sstevel@tonic-gate struct	varent *getvx();
522*7c478bd9Sstevel@tonic-gate struct	passwd *getpwnam();
523*7c478bd9Sstevel@tonic-gate struct	wordent *gethent();
524*7c478bd9Sstevel@tonic-gate struct	wordent *getsub();
525*7c478bd9Sstevel@tonic-gate char	*getwd();
526*7c478bd9Sstevel@tonic-gate tchar	*getwd_();
527*7c478bd9Sstevel@tonic-gate tchar	**glob();
528*7c478bd9Sstevel@tonic-gate tchar	*globone();
529*7c478bd9Sstevel@tonic-gate char	*index();
530*7c478bd9Sstevel@tonic-gate tchar	*index_();
531*7c478bd9Sstevel@tonic-gate struct	biltins *isbfunc();
532*7c478bd9Sstevel@tonic-gate off_t	lseek();
533*7c478bd9Sstevel@tonic-gate tchar	*operate();
534*7c478bd9Sstevel@tonic-gate void	phup();
535*7c478bd9Sstevel@tonic-gate void	pintr();
536*7c478bd9Sstevel@tonic-gate void	pchild();
537*7c478bd9Sstevel@tonic-gate tchar	*putn();
538*7c478bd9Sstevel@tonic-gate char	*rindex();
539*7c478bd9Sstevel@tonic-gate tchar	*rindex_();
540*7c478bd9Sstevel@tonic-gate tchar	**saveblk();
541*7c478bd9Sstevel@tonic-gate tchar	*savestr();
542*7c478bd9Sstevel@tonic-gate char	*strcat();
543*7c478bd9Sstevel@tonic-gate tchar	*strcat_();
544*7c478bd9Sstevel@tonic-gate int		strlen_(tchar *);
545*7c478bd9Sstevel@tonic-gate char	*strcpy();
546*7c478bd9Sstevel@tonic-gate tchar	*strcpy_();
547*7c478bd9Sstevel@tonic-gate tchar	*strend();
548*7c478bd9Sstevel@tonic-gate tchar	*strip();
549*7c478bd9Sstevel@tonic-gate tchar	*strspl();
550*7c478bd9Sstevel@tonic-gate tchar	*subword();
551*7c478bd9Sstevel@tonic-gate struct	command *syntax();
552*7c478bd9Sstevel@tonic-gate struct	command *syn0();
553*7c478bd9Sstevel@tonic-gate struct	command *syn1();
554*7c478bd9Sstevel@tonic-gate struct	command *syn1a();
555*7c478bd9Sstevel@tonic-gate struct	command *syn1b();
556*7c478bd9Sstevel@tonic-gate struct	command *syn2();
557*7c478bd9Sstevel@tonic-gate struct	command *syn3();
558*7c478bd9Sstevel@tonic-gate tchar	*value1();
559*7c478bd9Sstevel@tonic-gate tchar	*xhome();
560*7c478bd9Sstevel@tonic-gate tchar	*xname();
561*7c478bd9Sstevel@tonic-gate tchar	*xset();
562*7c478bd9Sstevel@tonic-gate 
563*7c478bd9Sstevel@tonic-gate #define	NOSTR	((tchar *) 0)
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate /*
566*7c478bd9Sstevel@tonic-gate  * setname is a macro to copy the path in bname. (see sh.err.c)
567*7c478bd9Sstevel@tonic-gate  * Here we are dynamically reallocating the bname to the new length
568*7c478bd9Sstevel@tonic-gate  * to store the new path
569*7c478bd9Sstevel@tonic-gate  */
570*7c478bd9Sstevel@tonic-gate tchar	*bname;
571*7c478bd9Sstevel@tonic-gate #define	setname(a)	 { \
572*7c478bd9Sstevel@tonic-gate 	bname = xrealloc(bname, (strlen_(a)+1) * sizeof (tchar)); \
573*7c478bd9Sstevel@tonic-gate 	strcpy_(bname, a); \
574*7c478bd9Sstevel@tonic-gate 	bname[strlen_(a)] = '\0'; \
575*7c478bd9Sstevel@tonic-gate }
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate #ifdef VFORK
578*7c478bd9Sstevel@tonic-gate tchar	*Vsav;
579*7c478bd9Sstevel@tonic-gate tchar	**Vav;
580*7c478bd9Sstevel@tonic-gate tchar	*Vdp;
581*7c478bd9Sstevel@tonic-gate #endif
582*7c478bd9Sstevel@tonic-gate 
583*7c478bd9Sstevel@tonic-gate tchar	**evalvec;
584*7c478bd9Sstevel@tonic-gate tchar	*evalp;
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate /* Conversion functions between char and tchar strings. */
587*7c478bd9Sstevel@tonic-gate tchar	*strtots(/* tchar * , char * */);
588*7c478bd9Sstevel@tonic-gate char	*tstostr(/* char *  , tchar * */);
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate #ifndef NULL
591*7c478bd9Sstevel@tonic-gate #define	NULL	0
592*7c478bd9Sstevel@tonic-gate #endif
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate /*
596*7c478bd9Sstevel@tonic-gate  * Xhash is an array of HSHSIZ bits (HSHSIZ / 8 chars), which are used
597*7c478bd9Sstevel@tonic-gate  * to hash execs.  If it is allocated (havhash true), then to tell
598*7c478bd9Sstevel@tonic-gate  * whether ``name'' is (possibly) present in the i'th component
599*7c478bd9Sstevel@tonic-gate  * of the variable path, you look at the bit in xhash indexed by
600*7c478bd9Sstevel@tonic-gate  * hash(hashname("name"), i).  This is setup automatically
601*7c478bd9Sstevel@tonic-gate  * after .login is executed, and recomputed whenever ``path'' is
602*7c478bd9Sstevel@tonic-gate  * changed.
603*7c478bd9Sstevel@tonic-gate  * The two part hash function is designed to let texec() call the
604*7c478bd9Sstevel@tonic-gate  * more expensive hashname() only once and the simple hash() several
605*7c478bd9Sstevel@tonic-gate  * times (once for each path component checked).
606*7c478bd9Sstevel@tonic-gate  * Byte size is assumed to be 8.
607*7c478bd9Sstevel@tonic-gate  */
608*7c478bd9Sstevel@tonic-gate #define HSHSIZ          (32*1024)       /* 4k bytes */
609*7c478bd9Sstevel@tonic-gate #define HSHMASK         (HSHSIZ - 1)
610*7c478bd9Sstevel@tonic-gate #define HSHMUL          243
611*7c478bd9Sstevel@tonic-gate 
612*7c478bd9Sstevel@tonic-gate /*
613*7c478bd9Sstevel@tonic-gate  * The following two arrays are used for caching.  xhash
614*7c478bd9Sstevel@tonic-gate  * is for caching path variable and xhash2 is for cdpath
615*7c478bd9Sstevel@tonic-gate  * variable.
616*7c478bd9Sstevel@tonic-gate  */
617*7c478bd9Sstevel@tonic-gate 
618*7c478bd9Sstevel@tonic-gate char xhash[HSHSIZ / 8];
619*7c478bd9Sstevel@tonic-gate char xhash2[HSHSIZ / 8];
620*7c478bd9Sstevel@tonic-gate #define hash(a, b)      ((a) * HSHMUL + (b) & HSHMASK)
621*7c478bd9Sstevel@tonic-gate #define bit(h, b)       ((h)[(b) >> 3] & 1 << ((b) & 7))        /* bit test */
622*7c478bd9Sstevel@tonic-gate #define bis(h, b)       ((h)[(b) >> 3] |= 1 << ((b) & 7))       /* bit set */
623*7c478bd9Sstevel@tonic-gate #ifdef VFORK
624*7c478bd9Sstevel@tonic-gate int     hits, misses;
625*7c478bd9Sstevel@tonic-gate #endif
626*7c478bd9Sstevel@tonic-gate 
627*7c478bd9Sstevel@tonic-gate 
628