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