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