1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                  David Korn <dgk@research.att.com>                   *
18 *                                                                      *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22  * David Korn
23  * AT&T Labs
24  *
25  * Shell interface private definitions
26  *
27  */
28 #ifndef defs_h_defined
29 #define defs_h_defined
30 
31 #include	<ast.h>
32 #include	<sfio.h>
33 #include	<error.h>
34 #include	"FEATURE/externs"
35 #include	"FEATURE/options"
36 #include	<cdt.h>
37 #include	<history.h>
38 #include	"fault.h"
39 #include	"argnod.h"
40 #include	"name.h"
41 #include	<ctype.h>
42 
43 #ifndef pointerof
44 #define pointerof(x)		((void*)((char*)0+(x)))
45 #endif
46 
47 #define Empty			((char*)(e_sptbnl+3))
48 
49 #define	env_change()		(++ast.env_serial)
50 #if SHOPT_ENV
51 #   include	<env.h>
52 #else
53 #   define Env_t		void
54 #   define sh_envput(e,p)	env_change()
55 #   define env_delete(e,p)	env_change()
56 #endif
57 
58 extern char*	sh_getenv(const char*);
59 extern char*	sh_setenviron(const char*);
60 
61 /*
62  * note that the first few fields have to be the same as for
63  * Shscoped_t in <shell.h>
64  */
65 
66 
67 struct sh_scoped
68 {
69 	struct sh_scoped *prevst;	/* pointer to previous state */
70 	int		dolc;
71 	char		**dolv;
72 	char		*cmdname;
73 	char		*filename;
74 	char		*funname;
75 	int		lineno;
76 	Dt_t		*save_tree;	/* var_tree for calling function */
77 	struct sh_scoped *self;		/* pointer to copy of this scope*/
78 	Dt_t		*var_local;	/* local level variables for name() */
79 	struct slnod	*staklist;	/* link list of function stacks */
80 	int		states;
81 	int		breakcnt;
82 	int		execbrk;
83 	int		loopcnt;
84 	int		firstline;
85 	int32_t		optindex;
86 	int32_t		optnum;
87 	int32_t		tmout;		/* value for TMOUT */
88 	short		optchar;
89 	short		opterror;
90 	int		ioset;
91 	unsigned short	trapmax;
92 	char		*trap[SH_DEBUGTRAP+1];
93 	char		**otrap;
94 	char		**trapcom;
95 	char		**otrapcom;
96 	void		*timetrap;
97 	struct Ufunction *real_fun;	/* current 'function name' function */
98 	int             repl_index;
99 	char            *repl_arg;
100 };
101 
102 struct limits
103 {
104 	long		arg_max;	/* max arg+env exec() size */
105 	int		open_max;	/* maximum number of file descriptors */
106 	int		clk_tck;	/* number of ticks per second */
107 	int		child_max;	/* maxumum number of children */
108 	int		ngroups_max;	/* maximum number of process groups */
109 	unsigned char	posix_version;	/* posix version number */
110 	unsigned char	posix_jobcontrol;/* non-zero for job control systems */
111 	unsigned char	fs3d;		/* non-zero for 3-d file system */
112 };
113 
114 #ifndef SH_wait_f_defined
115     typedef int (*Shwait_f)(int, long, int);
116 #   define     SH_wait_f_defined
117 #endif
118 
119 
120 struct shared
121 {
122 	struct limits	lim;
123 	uid_t		userid;
124 	uid_t		euserid;
125 	gid_t		groupid;
126 	gid_t		egroupid;
127 	pid_t		pid;
128 	int32_t		ppid;
129 	unsigned char	sigruntime[2];
130 	Namval_t	*bltin_nodes;
131 	Namval_t	*bltin_cmds;
132 	History_t	*hist_ptr;
133 	char		*shpath;
134 	char		*user;
135 	char		**sigmsg;
136 	char		*rcfile;
137 	char		**login_files;
138 	void		*ed_context;
139 	void		*init_context;
140 	void		*job_context;
141 	int		*stats;
142 	int		bltin_nnodes;	/* number of bltins nodes */
143 	int		sigmax;
144 	int		nforks;
145 	Shwait_f	waitevent;
146 };
147 
148 #define _SH_PRIVATE \
149 	struct shared	*gd;		/* global data */ \
150 	struct sh_scoped st;		/* scoped information */ \
151 	Stk_t		*stk;		/* stack poiter */ \
152 	Sfio_t		*heredocs;	/* current here-doc temp file */ \
153 	Sfio_t		*funlog;	/* for logging function definitions */ \
154 	int		**fdptrs;	/* pointer to file numbers */ \
155 	int		savexit; \
156 	char		*lastarg; \
157 	char		*lastpath;	/* last alsolute path found */ \
158 	int		path_err;	/* last error on path search */ \
159 	Dt_t		*track_tree;	/* for tracked aliases*/ \
160 	Dt_t		*var_base;	/* global level variables */ \
161 	Dt_t		*openmatch; \
162 	Namval_t	*namespace;	/* current active namespace*/ \
163 	Namval_t	*last_table;	/* last table used in last nv_open  */ \
164 	Namval_t	*prev_table;	/* previous table used in nv_open  */ \
165 	Sfio_t		*outpool;	/* ouput stream pool */ \
166 	long		timeout;	/* read timeout */ \
167 	short		curenv;		/* current subshell number */ \
168 	short		jobenv;		/* subshell number for jobs */ \
169 	int		infd;		/* input file descriptor */ \
170 	short		nextprompt;	/* next prompt is PS<nextprompt> */ \
171 	short		poolfiles; \
172 	Namval_t	*posix_fun;	/* points to last name() function */ \
173 	char		*outbuff;	/* pointer to output buffer */ \
174 	char		*errbuff;	/* pointer to stderr buffer */ \
175 	char		*prompt;	/* pointer to prompt string */ \
176 	char		*shname;	/* shell name */ \
177 	char		*comdiv;	/* points to sh -c argument */ \
178 	char		*prefix;	/* prefix for compound assignment */ \
179 	sigjmp_buf	*jmplist;	/* longjmp return stack */ \
180 	char		*fifo;		/* fifo name for process sub */ \
181 	int		oldexit; \
182 	pid_t		bckpid;		/* background process id */ \
183 	pid_t		cpid; \
184 	pid_t		spid; 		/* subshell process id */ \
185 	pid_t		pipepid; \
186 	pid_t		outpipepid; \
187 	int		topfd; \
188 	int		savesig; \
189 	unsigned char	*sigflag;	/* pointer to signal states */ \
190 	char		intrap; \
191 	char		login_sh; \
192 	char		lastbase; \
193 	char		forked;	\
194 	char		binscript; \
195 	char		deftype; \
196 	char		funload; \
197 	char		used_pos;	/* used postional parameter */\
198 	char		universe; \
199 	char		winch; \
200 	char		inarith; 	/* set when in ((...)) */ \
201 	char		indebug; 	/* set when in debug trap */ \
202 	unsigned char	ignsig;		/* ignored signal in subshell */ \
203 	unsigned char	lastsig;	/* last signal received */ \
204 	char		pathinit;	/* pathinit called from subshell */ \
205 	char		comsub;		/* set when in $() comsub */ \
206 	char		subshare;	/* set when in ${..} comsub */ \
207 	char		toomany;	/* set when out of fd's */ \
208 	char		instance;	/* in set_instance */ \
209 	char		decomma;	/* decimal_point=',' */ \
210 	char		redir0;		/* redirect of 0 */ \
211 	char		*readscript;	/* set before reading a script */ \
212 	int		subdup;		/* bitmask for dups of 1 */ \
213 	int		*inpipe;	/* input pipe pointer */ \
214 	int		*outpipe;	/* output pipe pointer */ \
215 	int		cpipe[3]; \
216 	int		coutpipe; \
217 	int		inuse_bits; \
218 	struct argnod	*envlist; \
219 	struct dolnod	*arglist; \
220 	int		fn_depth; \
221 	int		fn_reset; \
222 	int		dot_depth; \
223 	int		hist_depth; \
224 	int		xargmin; \
225 	int		xargmax; \
226 	int		xargexit; \
227 	int		nenv; \
228 	mode_t		mask; \
229 	Env_t		*env; \
230 	void		*init_context; \
231 	void		*mac_context; \
232 	void		*lex_context; \
233 	void		*arg_context; \
234 	void		*job_context; \
235 	void		*pathlist; \
236 	void		*defpathlist; \
237 	void		*cdpathlist; \
238 	char		**argaddr; \
239 	void		*optlist; \
240 	struct sh_scoped global; \
241 	struct checkpt	checkbase; \
242 	Shinit_f	userinit; \
243 	Shbltin_f	bltinfun; \
244 	Shbltin_t	bltindata; \
245 	char		*cur_line; \
246 	int		offsets[10]; \
247 	Sfio_t		**sftable; \
248 	unsigned char	*fdstatus; \
249 	const char	*pwd; \
250 	void		*jmpbuffer; \
251 	void		*mktype; \
252 	Sfio_t		*strbuf; \
253 	Sfio_t		*strbuf2; \
254 	Dt_t		*first_root; \
255 	Dt_t		*prefix_root; \
256 	Dt_t		*last_root; \
257 	Dt_t		*prev_root; \
258 	Dt_t		*fpathdict; \
259 	Dt_t		*typedict; \
260 	Dt_t		*inpool; \
261 	Dt_t		*transdict; \
262 	char		ifstable[256]; \
263 	unsigned long	test; \
264 	Shopt_t		offoptions; \
265 	Shopt_t		glob_options; \
266 	Namval_t	*typeinit; \
267 	Namfun_t	nvfun; \
268 	char		*mathnodes; \
269 	void		*coshell; \
270 	char		*bltin_dir; \
271 	struct Regress_s*regress; \
272 	char 		exittrap; \
273 	char 		errtrap; \
274 	char 		end_fn;
275 
276 #include	<shell.h>
277 
278 #include	"shtable.h"
279 #include	"regress.h"
280 
281 /* error exits from various parts of shell */
282 #define	NIL(type)	((type)0)
283 
284 #define new_of(type,x)	((type*)malloc((unsigned)sizeof(type)+(x)))
285 
286 #define exitset()	(sh.savexit=sh.exitval)
287 
288 #ifndef SH_DICT
289 #define SH_DICT		(void*)e_dict
290 #endif
291 
292 #ifndef SH_CMDLIB_DIR
293 #define SH_CMDLIB_DIR	"/opt/ast/bin"
294 #endif
295 
296 /* states */
297 /* low numbered states are same as options */
298 #define SH_NOFORK	0	/* set when fork not necessary */
299 #define	SH_FORKED	7	/* set when process has been forked */
300 #define	SH_PROFILE	8	/* set when processing profiles */
301 #define SH_NOALIAS	9	/* do not expand non-exported aliases */
302 #define SH_NOTRACK	10	/* set to disable sftrack() function */
303 #define SH_STOPOK	11	/* set for stopable builtins */
304 #define SH_GRACE	12	/* set for timeout grace period */
305 #define SH_TIMING	13	/* set while timing pipelines */
306 #define SH_DEFPATH	14	/* set when using default path */
307 #define SH_INIT		15	/* set when initializing the shell */
308 #define SH_TTYWAIT	16	/* waiting for keyboard input */
309 #define	SH_FCOMPLETE	17	/* set for filename completion */
310 #define	SH_PREINIT	18	/* set with SH_INIT before parsing options */
311 #define SH_COMPLETE	19	/* set for command completion */
312 
313 #define SH_BASH			41
314 #define SH_BRACEEXPAND		42
315 #define SH_POSIX		46
316 #define SH_MULTILINE    	47
317 
318 #define SH_NOPROFILE		78
319 #define SH_NOUSRPROFILE		79
320 #define SH_LOGIN_SHELL		67
321 #define SH_COMMANDLINE		0x100
322 #define SH_BASHEXTRA		0x200
323 #define SH_BASHOPT		0x400
324 
325 #define SH_ID			"ksh"	/* ksh id */
326 #define SH_STD			"sh"	/* standard sh id */
327 
328 /* defines for sh_type() */
329 
330 #define SH_TYPE_SH		001
331 #define SH_TYPE_KSH		002
332 #define SH_TYPE_BASH		004
333 #define SH_TYPE_LOGIN		010
334 #define SH_TYPE_PROFILE		020
335 #define SH_TYPE_RESTRICTED	040
336 
337 #if SHOPT_BASH
338 #   ifndef SHOPT_HISTEXPAND
339 #	define SHOPT_HISTEXPAND	1
340 #   endif
341 /*
342  *  define for all the bash options
343  */
344 #   define SH_CDABLE_VARS	51
345 #   define SH_CDSPELL		52
346 #   define SH_CHECKHASH		53
347 #   define SH_CHECKWINSIZE	54
348 #   define SH_CMDHIST		55
349 #   define SH_DOTGLOB		56
350 #   define SH_EXECFAIL		57
351 #   define SH_EXPAND_ALIASES	58
352 #   define SH_EXTGLOB		59
353 #   define SH_HOSTCOMPLETE	63
354 #   define SH_HUPONEXIT		64
355 #   define SH_INTERACTIVE_COMM	65
356 #   define SH_LITHIST		66
357 #   define SH_MAILWARN		68
358 #   define SH_NOEMPTYCMDCOMPL	69
359 #   define SH_NOCASEGLOB	70
360 #   define SH_NULLGLOB		71
361 #   define SH_PHYSICAL		45
362 #   define SH_PROGCOMP		72
363 #   define SH_PROMPTVARS	73
364 #   define SH_RESTRICTED2	74
365 #   define SH_SHIFT_VERBOSE	75
366 #   define SH_SOURCEPATH	76
367 #   define SH_XPG_ECHO		77
368 #endif
369 
370 #if SHOPT_HISTEXPAND
371 #   define SH_HISTAPPEND	60
372 #   define SH_HISTEXPAND	43
373 #   define SH_HISTORY2		44
374 #   define SH_HISTREEDIT	61
375 #   define SH_HISTVERIFY	62
376 #endif
377 
378 #ifndef PIPE_BUF
379 #   define PIPE_BUF		512
380 #endif
381 
382 #if SHOPT_PFSH && ( !_lib_getexecuser || !_lib_free_execattr )
383 #   undef SHOPT_PFSH
384 #endif
385 
386 #define MATCH_MAX		64
387 
388 #define SH_READEVAL		0x4000	/* for sh_eval */
389 #define SH_FUNEVAL		0x10000	/* for sh_eval for function load */
390 
391 extern struct shared	*shgd;
392 extern Shell_t		*nv_shell(Namval_t*);
393 extern void		sh_applyopts(Shell_t*,Shopt_t);
394 extern char 		**sh_argbuild(Shell_t*,int*,const struct comnod*,int);
395 extern struct dolnod	*sh_argfree(Shell_t *, struct dolnod*,int);
396 extern struct dolnod	*sh_argnew(Shell_t*,char*[],struct dolnod**);
397 extern void 		*sh_argopen(Shell_t*);
398 extern struct argnod	*sh_argprocsub(Shell_t*,struct argnod*);
399 extern void 		sh_argreset(Shell_t*,struct dolnod*,struct dolnod*);
400 extern Namval_t		*sh_assignok(Namval_t*,int);
401 extern struct dolnod	*sh_arguse(Shell_t*);
402 extern char		*sh_checkid(char*,char*);
403 extern void		sh_chktrap(Shell_t*);
404 extern void		sh_deparse(Sfio_t*,const Shnode_t*,int);
405 extern int		sh_debug(Shell_t *shp,const char*,const char*,const char*,char *const[],int);
406 extern int 		sh_echolist(Shell_t*,Sfio_t*, int, char**);
407 extern struct argnod	*sh_endword(Shell_t*,int);
408 extern char 		**sh_envgen(void);
409 #if SHOPT_ENV
410 extern void 		sh_envput(Env_t*, Namval_t*);
411 #endif
412 extern void 		sh_envnolocal(Namval_t*,void*);
413 extern Sfdouble_t	sh_arith(Shell_t*,const char*);
414 extern void		*sh_arithcomp(Shell_t *,char*);
415 extern pid_t 		sh_fork(Shell_t*,int,int*);
416 extern pid_t		_sh_fork(Shell_t*,pid_t, int ,int*);
417 extern char 		*sh_mactrim(Shell_t*,char*,int);
418 extern int 		sh_macexpand(Shell_t*,struct argnod*,struct argnod**,int);
419 extern int		sh_macfun(Shell_t*,const char*,int);
420 extern void 		sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*);
421 extern void 		*sh_macopen(Shell_t*);
422 extern char 		*sh_macpat(Shell_t*,struct argnod*,int);
423 extern Sfdouble_t	sh_mathfun(Shell_t*, void*, int, Sfdouble_t*);
424 extern int		sh_outtype(Shell_t*, Sfio_t*);
425 extern char 		*sh_mactry(Shell_t*,char*);
426 extern int		sh_mathstd(const char*);
427 extern void		sh_printopts(Shopt_t,int,Shopt_t*);
428 extern int 		sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long);
429 extern Sfio_t		*sh_sfeval(char*[]);
430 extern void		sh_setmatch(Shell_t*,const char*,int,int,int[],int);
431 extern Dt_t		*sh_subaliastree(int);
432 extern void             sh_scope(Shell_t*, struct argnod*, int);
433 extern Namval_t		*sh_scoped(Shell_t*, Namval_t*);
434 extern Dt_t		*sh_subfuntree(int);
435 extern void		sh_subjobcheck(pid_t);
436 extern int		sh_subsavefd(int);
437 extern void		sh_subtmpfile(Shell_t*);
438 extern char 		*sh_substitute(const char*,const char*,char*);
439 extern void		sh_timetraps(Shell_t*);
440 extern const char	*_sh_translate(const char*);
441 extern int		sh_trace(Shell_t*,char*[],int);
442 extern void		sh_trim(char*);
443 extern int		sh_type(const char*);
444 extern void             sh_unscope(Shell_t*);
445 extern void		sh_utol(const char*, char*);
446 extern int 		sh_whence(char**,int);
447 #if SHOPT_COSHELL
448    extern int		sh_coaddfile(Shell_t*,char*);
449    extern int		sh_copipe(Shell_t*, int[], int);
450    extern int		sh_coaccept(Shell_t*,int[],int);
451 #endif /* SHOPT_COSHELL */
452 #if SHOPT_NAMESPACE
453     extern Namval_t	*sh_fsearch(Shell_t*,const char *,int);
454 #endif /* SHOPT_NAMESPACE */
455 
456 #ifndef ERROR_dictionary
457 #   define ERROR_dictionary(s)	(s)
458 #endif
459 #define sh_translate(s)	_sh_translate(ERROR_dictionary(s))
460 
461 #define WBITS		(sizeof(long)*8)
462 #define WMASK		(0xff)
463 
464 #define is_option(s,x)	((s)->v[((x)&WMASK)/WBITS] & (1L << ((x) % WBITS)))
465 #define on_option(s,x)	((s)->v[((x)&WMASK)/WBITS] |= (1L << ((x) % WBITS)))
466 #define off_option(s,x)	((s)->v[((x)&WMASK)/WBITS] &= ~(1L << ((x) % WBITS)))
467 #define sh_isoption(x)	is_option(&sh.options,x)
468 #define sh_onoption(x)	on_option(&sh.options,x)
469 #define sh_offoption(x)	off_option(&sh.options,x)
470 
471 
472 #define sh_state(x)	( 1<<(x))
473 #define	sh_isstate(x)	(sh.st.states&sh_state(x))
474 #define	sh_onstate(x)	(sh.st.states |= sh_state(x))
475 #define	sh_offstate(x)	(sh.st.states &= ~sh_state(x))
476 #define	sh_getstate()	(sh.st.states)
477 #define	sh_setstate(x)	(sh.st.states = (x))
478 
479 #define sh_sigcheck(shp) do{if(shp->trapnote&SH_SIGSET)sh_exit(SH_EXITSIG);} while(0)
480 
481 extern int32_t		sh_mailchk;
482 extern const char	e_dict[];
483 
484 /* sh_printopts() mode flags -- set --[no]option by default */
485 
486 #define PRINT_VERBOSE	0x01	/* option on|off list		*/
487 #define PRINT_ALL	0x02	/* list unset options too	*/
488 #define PRINT_NO_HEADER	0x04	/* omit listing header		*/
489 #define PRINT_SHOPT	0x08	/* shopt -s|-u			*/
490 #define PRINT_TABLE	0x10	/* table of all options		*/
491 
492 #ifdef SHOPT_STATS
493     /* performance statistics */
494 #   define	STAT_ARGHITS	0
495 #   define	STAT_ARGEXPAND	1
496 #   define	STAT_COMSUB	2
497 #   define	STAT_FORKS	3
498 #   define	STAT_FUNCT	4
499 #   define	STAT_GLOBS	5
500 #   define	STAT_READS	6
501 #   define	STAT_NVHITS	7
502 #   define	STAT_NVOPEN	8
503 #   define	STAT_PATHS	9
504 #   define	STAT_SVFUNCT	10
505 #   define	STAT_SCMDS	11
506 #   define	STAT_SPAWN	12
507 #   define	STAT_SUBSHELL	13
508     extern const Shtable_t shtab_stats[];
509 #   define sh_stats(x)	(shgd->stats[(x)]++)
510 #else
511 #   define sh_stats(x)
512 #endif /* SHOPT_STATS */
513 
514 
515 #endif
516