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