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