xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/sh/bash.c (revision b30d1939)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2011 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
18da2e3ebdSchin *                                                                      *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin /*
21da2e3ebdSchin  * bash specific extensions
22da2e3ebdSchin  * originally provided by Karsten Fleischer
23da2e3ebdSchin  */
24da2e3ebdSchin 
25da2e3ebdSchin #include "defs.h"
26da2e3ebdSchin #include "path.h"
27da2e3ebdSchin #include "io.h"
28da2e3ebdSchin #include "builtins.h"
29da2e3ebdSchin #include "name.h"
30da2e3ebdSchin 
31da2e3ebdSchin #ifndef BASH_MAJOR
32da2e3ebdSchin #   define BASH_MAJOR	"1"
33da2e3ebdSchin #   define BASH_MINOR	"0"
34da2e3ebdSchin #   define BASH_PATCH	"0"
35da2e3ebdSchin #   define BASH_BUILD	"0"
36da2e3ebdSchin #   define BASH_RELEASE	"experimental"
37da2e3ebdSchin #endif
38da2e3ebdSchin #define BASH_VERSION	BASH_MAJOR "." BASH_MINOR "." BASH_PATCH "(" BASH_BUILD ")-" BASH_RELEASE
39da2e3ebdSchin 
40da2e3ebdSchin 
41da2e3ebdSchin extern const char	bash_pre_rc[];
42da2e3ebdSchin 
43da2e3ebdSchin static char *login_files[4];
44da2e3ebdSchin 
45da2e3ebdSchin const char sh_bash1[] =
46da2e3ebdSchin 	"[B?Enable brace group expansion. This option is only availabe in bash "
47da2e3ebdSchin 	"compatibility mode. In ksh mode, brace group expansion is always on.]"
48da2e3ebdSchin 	"[P?Do not follow symbolic links, use physical directory structure "
49da2e3ebdSchin 	"instead. Only available in bash compatibility mode.]";
50da2e3ebdSchin const char sh_bash2[] =
51da2e3ebdSchin "[O]:?[shopt_option?\ashopt_option\a is one of the shell options accepted by "
52da2e3ebdSchin 	"the \bshopt\b builtin. If \ashopt_option\a is present, \b-O\b sets "
53da2e3ebdSchin 	"the value of that option; \b+O\b unsets it. If \ashopt_option\a is "
54da2e3ebdSchin 	"not supplied, the names and values of the shell options accepted by "
55da2e3ebdSchin 	"\bshopt\b are printed on the standard output. If the invocation "
56da2e3ebdSchin 	"option is \b+O\b, the output is displayed in a format that may be "
57da2e3ebdSchin 	"reused as input. Only available if invoked as \bbash\b.]"
58da2e3ebdSchin "[01:init-file|rcfile]:[file?Execute commands from \afile\a instead of the "
59da2e3ebdSchin 	"standard personal initialization file ~/.bashrc if the shell is "
60da2e3ebdSchin 	"interactive. Only available if invoked as \bbash\b.]"
61da2e3ebdSchin "[02:editing?For option compatibility with \bbash\b only. Ignored.]"
62da2e3ebdSchin "[03:profile?Read either the system-wide startup file or any of the "
63da2e3ebdSchin 	"personal initialization files. On by default for interactive "
64da2e3ebdSchin 	"shells. Only available if invoked as \bbash\b.]"
657c2fbfb3SApril Chin "[04:posix?If invoked as \bbash\b, turn on POSIX compatibility. \bBash\b in "
66da2e3ebdSchin 	"POSIX mode is not the same as \bksh\b.]"
677c2fbfb3SApril Chin "[05:version?Print version number and exit.]";
68da2e3ebdSchin 
69da2e3ebdSchin const char sh_optshopt[] =
70da2e3ebdSchin "+[-1c?\n@(#)$Id: shopt (AT&T Research) 2003-02-13 $\n]"
71da2e3ebdSchin "[-author?Karsten Fleischer <K.Fleischer@omnium.de>]"
72da2e3ebdSchin USAGE_LICENSE
73da2e3ebdSchin "[+NAME?shopt - set/unset variables controlling optional shell behavior]"
74da2e3ebdSchin "[+DESCRIPTION?\bshopt\b sets or unsets variables controlling optional shell "
75da2e3ebdSchin 	"behavior. With no options, or with the \b-p\b option, a list of all "
76da2e3ebdSchin 	"settable options is displayed, with an indication of whether or not "
77da2e3ebdSchin 	"each is set.]"
78da2e3ebdSchin "[p?Causes output to be displayed in a form that may be reused as input.]"
79da2e3ebdSchin "[s?Set each \aoptname\a.]"
80da2e3ebdSchin "[u?Unset each \aoptname\a.]"
81da2e3ebdSchin "[q?Suppress output (quiet mode). The return status indicates whether the "
82da2e3ebdSchin 	"\aoptname\a is set or unset. If multiple \aoptname\a arguments are "
83da2e3ebdSchin 	"given with \b-q\b, the return status is zero if all \aoptname\as are "
84da2e3ebdSchin 	"enabled; non-zero otherwise.]"
85da2e3ebdSchin "[o?Restricts the values of \aoptname\a to be those defined for the \b-o\b "
86da2e3ebdSchin 	"option to the set builtin.]"
87da2e3ebdSchin "[+?If either \b-s\b or \b-u\b is used with no \aoptname\a arguments, the "
88da2e3ebdSchin 	"display is limited to those options which are set or unset.]"
89da2e3ebdSchin "[+?\bshopt\b supports all bash options. Some settings do not have any effect "
90da2e3ebdSchin 	"or are are always on and cannot be changed.]"
91da2e3ebdSchin "[+?The value of \aoptname\a must be one of the following:]{"
92da2e3ebdSchin 		"[+cdable_vars?If set, arguments to the \bcd\b command are "
93da2e3ebdSchin 			"assumed to be names of variables whose values are to "
94da2e3ebdSchin 			"be used if the usual \bcd\b proceeding fails.]"
95da2e3ebdSchin 		"[+cdspell?Currently ignored.]"
96da2e3ebdSchin 		"[+checkhash?Always on.]"
97da2e3ebdSchin 		"[+checkwinsize?Currently ignored.]"
98da2e3ebdSchin 		"[+cmdhist?Always on.]"
99da2e3ebdSchin 		"[+dotglob?If set, include filenames beginning with a \b.\b "
100da2e3ebdSchin 			"in the results of pathname expansion.]"
101da2e3ebdSchin 		"[+execfail?Always on.]"
102da2e3ebdSchin 		"[+expand_aliases?Always on.]"
103da2e3ebdSchin 		"[+extglob?Enable extended pattern matching features.]"
104da2e3ebdSchin 		"[+histappend?Always on.]"
105da2e3ebdSchin 		"[+histreedit?If set and an edit mode is selected, the user "
106da2e3ebdSchin 			"is given the opportunity to re-edit a failed history "
107da2e3ebdSchin 			"substitution.]"
108da2e3ebdSchin 		"[+histverify?If set and an edit mode is selected, the result "
109da2e3ebdSchin 			"of a history substitution will not be executed "
110da2e3ebdSchin 			"immediately but be placed in the edit buffer for "
111da2e3ebdSchin 			"further modifications.]"
112da2e3ebdSchin 		"[+hostcomplete?Currently ignored.]"
113da2e3ebdSchin 		"[+huponexit?Currently ignored.]"
114da2e3ebdSchin 		"[+interactive_comments?Always on.]"
115da2e3ebdSchin 		"[+lithist?Always on.]"
116da2e3ebdSchin 		"[+login_shell?This option is set if the shell is started as "
117da2e3ebdSchin 			"a login shell. The value cannot be changed.]"
118da2e3ebdSchin 		"[+mailwarn?Currently ignored.]"
119da2e3ebdSchin 		"[+no_empty_cmd_completion?Always on.]"
120da2e3ebdSchin 		"[+nocaseglob?Match filenames in a case-insensitive fashion "
121da2e3ebdSchin 			"when performing filename expansion.]"
122da2e3ebdSchin 		"[+nullglob?Allows filename patterns which match no files to "
123da2e3ebdSchin 			"expand to a null string, rather than themselves.]"
124da2e3ebdSchin 		"[+progcomp?Currently ignored.]"
125da2e3ebdSchin 		"[+promptvars?Currently ignored.]"
126da2e3ebdSchin 		"[+restricted_shell?This option is set if the shell is started "
127da2e3ebdSchin 			"as a restricted shell. The value cannot be changed. "
128da2e3ebdSchin 			"It is not reset during execution of startup files, "
129da2e3ebdSchin 			"allowing the startup files to determine whether the "
130da2e3ebdSchin 			"shell is restricted.]"
131da2e3ebdSchin 		"[+shift_verbose?Currently ignored.]"
132da2e3ebdSchin 		"[+sourcepath?If set, the \b.\b builtin uses the value of PATH "
133da2e3ebdSchin 			"to find the directory containing the file supplied "
134da2e3ebdSchin 			"as an argument.]"
135da2e3ebdSchin 		"[+xpg_echo?If set, the \becho\b and \bprint\b builtins "
136da2e3ebdSchin 			"expand backslash-escape sequences.]"
137da2e3ebdSchin "}"
138da2e3ebdSchin "\n"
139da2e3ebdSchin "\n[optname ...]\n"
140da2e3ebdSchin "\n"
141da2e3ebdSchin "[+EXIT STATUS?]{"
142da2e3ebdSchin 	"[+?The return status when listing options is zero if all \aoptnames\a "
143da2e3ebdSchin 	"are enabled, non-zero otherwise. When setting or unsetting options, "
144da2e3ebdSchin 	"the return status is zero unless an \aoptname\a is not a valid shell "
145da2e3ebdSchin 	"option.]"
146da2e3ebdSchin "}"
147da2e3ebdSchin 
148da2e3ebdSchin "[+SEE ALSO?\bset\b(1)]"
149da2e3ebdSchin ;
150da2e3ebdSchin 
151da2e3ebdSchin /* GLOBIGNORE discipline. Turn on SH_DOTGLOB on set, turn off on unset. */
152da2e3ebdSchin 
put_globignore(register Namval_t * np,const char * val,int flags,Namfun_t * fp)153da2e3ebdSchin static void put_globignore(register Namval_t* np, const char *val, int flags, Namfun_t *fp)
154da2e3ebdSchin {
155da2e3ebdSchin 	if(val)
156da2e3ebdSchin 		sh_onoption(SH_DOTGLOB);
157da2e3ebdSchin 	else
158da2e3ebdSchin 		sh_offoption(SH_DOTGLOB);
159da2e3ebdSchin 
160da2e3ebdSchin 	nv_putv(np,val,flags,fp);
161da2e3ebdSchin }
162da2e3ebdSchin 
163da2e3ebdSchin const Namdisc_t SH_GLOBIGNORE_disc  = { sizeof(Namfun_t), put_globignore };
164da2e3ebdSchin 
165da2e3ebdSchin /* FUNCNAME discipline */
166da2e3ebdSchin 
167da2e3ebdSchin struct	funcname
168da2e3ebdSchin {
169da2e3ebdSchin 	Namfun_t	hdr;
170da2e3ebdSchin };
171da2e3ebdSchin 
put_funcname(register Namval_t * np,const char * val,int flags,Namfun_t * fp)172da2e3ebdSchin static void put_funcname(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
173da2e3ebdSchin {
174da2e3ebdSchin 	/* bash silently returns with an error when FUNCNAME is set,
175da2e3ebdSchin 	   unsetting FUNCNAME is allowed */
176da2e3ebdSchin 	if(val && !(flags&NV_RDONLY))
177da2e3ebdSchin 		error_info.exit(1);
178da2e3ebdSchin 
179da2e3ebdSchin 	nv_putv(np,val,flags,fp);
180da2e3ebdSchin }
181da2e3ebdSchin 
182da2e3ebdSchin const Namdisc_t SH_FUNCNAME_disc  = { sizeof(struct funcname), put_funcname };
183da2e3ebdSchin 
184da2e3ebdSchin #define	SET_SET		1
185da2e3ebdSchin #define	SET_UNSET	2
186da2e3ebdSchin #define	SET_NOARGS	4
187da2e3ebdSchin 
188da2e3ebdSchin /* shopt builtin */
189da2e3ebdSchin 
b_shopt(int argc,register char * argv[],void * extra)190da2e3ebdSchin int     b_shopt(int argc,register char *argv[],void *extra)
191da2e3ebdSchin {
192da2e3ebdSchin         Shell_t *shp = (Shell_t*)extra;
193da2e3ebdSchin 	int n, f, ret=0;
194da2e3ebdSchin 	Shopt_t newflags=shp->options, opt;
195da2e3ebdSchin 	int verbose=PRINT_SHOPT|PRINT_ALL|PRINT_NO_HEADER|PRINT_VERBOSE;
196da2e3ebdSchin 	int setflag=0, quietflag=0, oflag=0;
197da2e3ebdSchin 	memset(&opt,0,sizeof(opt));
198da2e3ebdSchin #if SHOPT_RAWONLY
199da2e3ebdSchin 	on_option(&newflags,SH_VIRAW);
200da2e3ebdSchin #endif
201da2e3ebdSchin 	while((n = optget(argv,sh_optshopt)))
202da2e3ebdSchin 	{
203da2e3ebdSchin 		switch(n)
204da2e3ebdSchin 		{
205da2e3ebdSchin 		case 'p':
206da2e3ebdSchin 			verbose&=~PRINT_VERBOSE;
207da2e3ebdSchin 			break;
208da2e3ebdSchin 		case 's':
209da2e3ebdSchin 		case 'u':
210da2e3ebdSchin 			setflag|=n=='s'?SET_SET:SET_UNSET;
211da2e3ebdSchin 			if(setflag==(SET_SET|SET_UNSET))
212da2e3ebdSchin 			{
213da2e3ebdSchin 				errormsg(SH_DICT,ERROR_ERROR,"cannot set and unset options simultaneously");
214da2e3ebdSchin 				error_info.errors++;
215da2e3ebdSchin 			}
216da2e3ebdSchin 			break;
217da2e3ebdSchin 		case 'q':
218da2e3ebdSchin 			quietflag=1;
219da2e3ebdSchin 			break;
220da2e3ebdSchin 		case 'o':
221da2e3ebdSchin 			oflag=1;
222da2e3ebdSchin 			verbose&=~PRINT_SHOPT;
223da2e3ebdSchin 			break;
224da2e3ebdSchin 		case ':':
225da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
226da2e3ebdSchin 			continue;
227da2e3ebdSchin 		case '?':
228da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
229da2e3ebdSchin 			return(-1);
230da2e3ebdSchin 		}
231da2e3ebdSchin 	}
232da2e3ebdSchin 	if(error_info.errors)
233da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
234da2e3ebdSchin 	argc -= opt_info.index;
235da2e3ebdSchin 	if(argc==0)
236da2e3ebdSchin 	{
237da2e3ebdSchin 		/* no args, -s => mask=current options, -u mask=~(current options)
238da2e3ebdSchin 		   else mask=all bits */
239da2e3ebdSchin 		if(setflag&SET_SET)
240da2e3ebdSchin 			opt=newflags;
241da2e3ebdSchin 		else if(setflag&SET_UNSET)
242da2e3ebdSchin 			for(n=0;n<4;n++)
243da2e3ebdSchin 				opt.v[n]=~newflags.v[n];
244da2e3ebdSchin 		else
245da2e3ebdSchin 			memset(&opt,0xff,sizeof(opt));
246da2e3ebdSchin 		setflag=SET_NOARGS;
247da2e3ebdSchin 	}
248da2e3ebdSchin 	while(argc>0)
249da2e3ebdSchin 	{
250da2e3ebdSchin 		f=1;
251da2e3ebdSchin 		n=sh_lookopt(argv[opt_info.index],&f);
252da2e3ebdSchin 		if(n<=0||(setflag
253da2e3ebdSchin 			&& (is_option(&opt,SH_INTERACTIVE)
254da2e3ebdSchin 			    || is_option(&opt,SH_RESTRICTED)
255da2e3ebdSchin 			    || is_option(&opt,SH_RESTRICTED2)
256da2e3ebdSchin 			    || is_option(&opt,SH_BASH)
257da2e3ebdSchin 			    || is_option(&opt,SH_LOGIN_SHELL)))
258da2e3ebdSchin 			||(oflag&&(n&SH_BASHOPT)))
259da2e3ebdSchin 		{
260da2e3ebdSchin 			errormsg(SH_DICT,ERROR_ERROR, e_option, argv[opt_info.index]);
261da2e3ebdSchin 			error_info.errors++;
262da2e3ebdSchin 			ret=1;
263da2e3ebdSchin 		}
264da2e3ebdSchin 		else if(f)
265da2e3ebdSchin 			on_option(&opt,n&0xff);
266da2e3ebdSchin 		else
267da2e3ebdSchin 			off_option(&opt,n&0xff);
268da2e3ebdSchin 		opt_info.index++;
269da2e3ebdSchin 		argc--;
270da2e3ebdSchin 	}
271da2e3ebdSchin 	if(setflag&(SET_SET|SET_UNSET))
272da2e3ebdSchin 	{
273da2e3ebdSchin 		if(setflag&SET_SET)
274da2e3ebdSchin 		{
275da2e3ebdSchin 			if(sh_isoption(SH_INTERACTIVE))
276da2e3ebdSchin 				off_option(&opt,SH_NOEXEC);
277da2e3ebdSchin 			if(is_option(&opt,SH_VI)||is_option(&opt,SH_EMACS)||is_option(&opt,SH_GMACS))
278da2e3ebdSchin 			{
279da2e3ebdSchin 				off_option(&newflags,SH_VI);
280da2e3ebdSchin 				off_option(&newflags,SH_EMACS);
281da2e3ebdSchin 				off_option(&newflags,SH_GMACS);
282da2e3ebdSchin 			}
283da2e3ebdSchin 			for(n=0;n<4;n++)
284da2e3ebdSchin 				newflags.v[n] |= opt.v[n];
285da2e3ebdSchin 		}
286da2e3ebdSchin 		else if(setflag&SET_UNSET)
287da2e3ebdSchin 			for(n=0;n<4;n++)
288da2e3ebdSchin 				newflags.v[n] &= ~opt.v[n];
2897c2fbfb3SApril Chin 		sh_applyopts(shp,newflags);
290da2e3ebdSchin 		shp->options = newflags;
291da2e3ebdSchin 		if(is_option(&newflags,SH_XTRACE))
292*b30d1939SAndy Fiddaman 			sh_trace(shp,argv,1);
293da2e3ebdSchin 	}
294da2e3ebdSchin 	else if(!(setflag&SET_NOARGS)) /* no -s,-u but args, ret=0 if opt&mask==mask */
295da2e3ebdSchin 	{
296da2e3ebdSchin 		for(n=0;n<4;n++)
297da2e3ebdSchin 			ret+=((newflags.v[n]&opt.v[n])!=opt.v[n]);
298da2e3ebdSchin 	}
299da2e3ebdSchin 	if(!quietflag&&!(setflag&(SET_SET|SET_UNSET)))
300da2e3ebdSchin 		sh_printopts(newflags,verbose,&opt);
301da2e3ebdSchin 	return(ret);
302da2e3ebdSchin }
303da2e3ebdSchin 
304da2e3ebdSchin /* mode = 0: init, called two times
305da2e3ebdSchin         before parsing shell args with SH_PREINIT state turned on
306da2e3ebdSchin 	second time after sh_init() is through and with SH_PREINIT state turned off
307da2e3ebdSchin    mode > 1: re-init
308da2e3ebdSchin    mode < 0: shutdown
309da2e3ebdSchin */
310da2e3ebdSchin 
bash_init(Shell_t * shp,int mode)311*b30d1939SAndy Fiddaman void bash_init(Shell_t *shp,int mode)
312da2e3ebdSchin {
313da2e3ebdSchin 	Sfio_t		*iop;
314da2e3ebdSchin 	Namval_t	*np;
315da2e3ebdSchin 	int		n=0,xtrace,verbose;
316da2e3ebdSchin 	if(mode>0)
317da2e3ebdSchin 		goto reinit;
318da2e3ebdSchin 	if(mode < 0)
319da2e3ebdSchin 	{
320da2e3ebdSchin 		/* termination code */
321da2e3ebdSchin 		if(sh_isoption(SH_LOGIN_SHELL) && !sh_isoption(SH_POSIX))
3227c2fbfb3SApril Chin 			sh_source(shp, NiL, sh_mactry(shp,(char*)e_bash_logout));
323da2e3ebdSchin 		return;
324da2e3ebdSchin 	}
325da2e3ebdSchin 
326da2e3ebdSchin 	if(sh_isstate(SH_PREINIT))
327da2e3ebdSchin 	{	/* pre-init stage */
328da2e3ebdSchin 		if(sh_isoption(SH_RESTRICTED))
329da2e3ebdSchin 			sh_onoption(SH_RESTRICTED2);
330da2e3ebdSchin 		sh_onoption(SH_HISTORY2);
331da2e3ebdSchin 		sh_onoption(SH_INTERACTIVE_COMM);
332da2e3ebdSchin 		sh_onoption(SH_SOURCEPATH);
333da2e3ebdSchin 		sh_onoption(SH_HISTAPPEND);
334da2e3ebdSchin 		sh_onoption(SH_CMDHIST);
335da2e3ebdSchin 		sh_onoption(SH_LITHIST);
336da2e3ebdSchin 		sh_onoption(SH_NOEMPTYCMDCOMPL);
3377c2fbfb3SApril Chin 		if(shp->login_sh==2)
338da2e3ebdSchin 			sh_onoption(SH_LOGIN_SHELL);
339da2e3ebdSchin 		if(strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
340da2e3ebdSchin 			sh_onoption(SH_POSIX);
341da2e3ebdSchin 		if(strcmp(astconf("UNIVERSE",0,0),"att")==0)
342da2e3ebdSchin 			sh_onoption(SH_XPG_ECHO);
343da2e3ebdSchin 		else
344da2e3ebdSchin 			sh_offoption(SH_XPG_ECHO);
345da2e3ebdSchin 		if(strcmp(astconf("PATH_RESOLVE",0,0),"physical")==0)
346da2e3ebdSchin 			sh_onoption(SH_PHYSICAL);
347da2e3ebdSchin 		else
348da2e3ebdSchin 			sh_offoption(SH_PHYSICAL);
349da2e3ebdSchin 
350da2e3ebdSchin 		/* add builtins */
351da2e3ebdSchin 		sh_addbuiltin("shopt", b_shopt, &sh);
352da2e3ebdSchin 
353da2e3ebdSchin 		/* set up some variables needed for --version
354da2e3ebdSchin 		 * needs to go here because --version option is parsed before the init script.
355da2e3ebdSchin 		 */
3567c2fbfb3SApril Chin 		if(np=nv_open("HOSTTYPE",shp->var_tree,0))
357da2e3ebdSchin 			nv_putval(np, BASH_HOSTTYPE, NV_NOFREE);
3587c2fbfb3SApril Chin 		if(np=nv_open("MACHTYPE",shp->var_tree,0))
359da2e3ebdSchin 			nv_putval(np, BASH_MACHTYPE, NV_NOFREE);
3607c2fbfb3SApril Chin 		if(np=nv_open("BASH_VERSION",shp->var_tree,0))
361da2e3ebdSchin 			nv_putval(np, BASH_VERSION, NV_NOFREE);
3627c2fbfb3SApril Chin 		if(np=nv_open("BASH_VERSINFO",shp->var_tree,0))
363da2e3ebdSchin 		{
364da2e3ebdSchin 			char *argv[7];
365da2e3ebdSchin 			argv[0] = BASH_MAJOR;
366da2e3ebdSchin 			argv[1] = BASH_MINOR;
367da2e3ebdSchin 			argv[2] = BASH_PATCH;
368da2e3ebdSchin 			argv[3] = BASH_BUILD;
369da2e3ebdSchin 			argv[4] = BASH_RELEASE;
370da2e3ebdSchin 			argv[5] = BASH_MACHTYPE;
371da2e3ebdSchin 			argv[6] = 0;
372da2e3ebdSchin 			nv_setvec(np, 0, 6, argv);
373da2e3ebdSchin 			nv_onattr(np,NV_RDONLY);
374da2e3ebdSchin 		}
375da2e3ebdSchin 		return;
376da2e3ebdSchin 	}
377da2e3ebdSchin 
378da2e3ebdSchin 	/* rest of init stage */
379da2e3ebdSchin 
380da2e3ebdSchin 	/* restrict BASH_ENV */
3817c2fbfb3SApril Chin 	if(np=nv_open("BASH_ENV",shp->var_tree,0))
382da2e3ebdSchin 	{
383da2e3ebdSchin 		const Namdisc_t *dp = nv_discfun(NV_DCRESTRICT);
384da2e3ebdSchin 		Namfun_t *fp = calloc(dp->dsize,1);
385da2e3ebdSchin 		fp->disc = dp;
386da2e3ebdSchin 		nv_disc(np, fp, 0);
387da2e3ebdSchin 	}
388da2e3ebdSchin 
389da2e3ebdSchin 	/* open GLOBIGNORE node */
3907c2fbfb3SApril Chin 	if(np=nv_open("GLOBIGNORE",shp->var_tree,0))
391da2e3ebdSchin 	{
392da2e3ebdSchin 		const Namdisc_t *dp = &SH_GLOBIGNORE_disc;
393da2e3ebdSchin 		Namfun_t *fp = calloc(dp->dsize,1);
394da2e3ebdSchin 		fp->disc = dp;
395da2e3ebdSchin 		nv_disc(np, fp, 0);
396da2e3ebdSchin 	}
397da2e3ebdSchin 
398da2e3ebdSchin 	/* set startup files */
399da2e3ebdSchin 	n=0;
4007c2fbfb3SApril Chin 	if(sh_isoption(SH_LOGIN_SHELL))
401da2e3ebdSchin 	{
402da2e3ebdSchin 		if(!sh_isoption(SH_POSIX))
403da2e3ebdSchin 		{
404da2e3ebdSchin 			login_files[n++] = (char*)e_bash_profile;
405da2e3ebdSchin 			login_files[n++] = (char*)e_bash_login;
406da2e3ebdSchin 		}
407da2e3ebdSchin 		login_files[n++] = (char*)e_profile;
408da2e3ebdSchin 	}
4097c2fbfb3SApril Chin 	shp->login_files = login_files;
410da2e3ebdSchin reinit:
411da2e3ebdSchin 	xtrace = sh_isoption(SH_XTRACE);
412da2e3ebdSchin 	sh_offoption(SH_XTRACE);
413da2e3ebdSchin 	verbose = sh_isoption(SH_VERBOSE);
414da2e3ebdSchin 	sh_offoption(SH_VERBOSE);
4157c2fbfb3SApril Chin 	if(np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD))
416da2e3ebdSchin 		nv_offattr(np,NV_RDONLY);
417da2e3ebdSchin 	iop = sfopen(NULL, bash_pre_rc, "s");
418da2e3ebdSchin 	sh_eval(iop,0);
419da2e3ebdSchin 	if(xtrace)
420da2e3ebdSchin 		sh_offoption(SH_XTRACE);
421da2e3ebdSchin 	if(verbose)
422da2e3ebdSchin 		sh_offoption(SH_VERBOSE);
423da2e3ebdSchin }
424