diff options
author | April Chin <April.Chin@Sun.COM> | 2008-12-27 14:59:38 -0800 |
---|---|---|
committer | April Chin <April.Chin@Sun.COM> | 2008-12-27 14:59:38 -0800 |
commit | 7c2fbfb345896881c631598ee3852ce9ce33fb07 (patch) | |
tree | 4b173b5657508562dfc0aa05f7d056d1e9add505 /usr/src/lib/libshell/common/sh/init.c | |
parent | 6071ac1de68fed78e1e10052045bbb5f1732a263 (diff) | |
download | illumos-gate-7c2fbfb345896881c631598ee3852ce9ce33fb07.tar.gz |
PSARC/2008/094 ksh93 Update 1
PSARC/2008/344 ksh93 Integration Update 1 Amendments 1
PSARC/2008/589 Remove /usr/bin/printf from PSARC case 2008 094
6619428 *ksh93* RFE: Update ksh93 in Solaris to ast-ksh.2008-11-04
6788659 RFE: Update libpp in Solaris to ast-open.2008-07-25
6561901 RFE: Add "shcomp" (shell script compiler) + kernel module to exec binary sh code
6599668 RFE: Move consumers of alias.sh over to ksh93
6595183 *ksh93* RFE: Update ksh93-integration demo code
6775901 *ksh93* no C message catalogs are generated for ksh93
6451262 *sleep* RFE: /usr/bin/sleep should support floating-point values
6687139 *ksh93* command substitution, exec, and stdout redirection cause allocation loop
6703761 *ksh93* crashes in script containing uncommon output redirections
6715496 *ksh93* SEGVs on array reinitialization
6713682 *ksh93* Creating a compound variable in a subshell "bleeds through" to the calling subshell
6672350 *ksh93* causes parent shell to die when child shell is suspended
6745015 *ksh93* VARIABLE=`command substitution` assignment is not reliable on OpenSolaris
6710205 *ksh93* problem with command substitution (within back quotes) containing \$'
6737600 *ksh93* exits debugger when user presses ctrl-c
6748645 *ksh93* fc -l -e - is mis-parsed, outputs wrong error message "-e - requires single argument"
6754020 *ksh93* does weird '[' expansion
6753538 *ksh93* umask modification leaks out of a ksh93 subshell
6766246 *ksh93* bug in pattern matching
6763594 *ksh93* executes command after "command" builtin twice on failure
6762665 *ksh93* Difficult-to-reproduce SIGSEGV in ksh93
Diffstat (limited to 'usr/src/lib/libshell/common/sh/init.c')
-rw-r--r-- | usr/src/lib/libshell/common/sh/init.c | 796 |
1 files changed, 533 insertions, 263 deletions
diff --git a/usr/src/lib/libshell/common/sh/init.c b/usr/src/lib/libshell/common/sh/init.c index fbb6e5c6bc..0bd2f92b79 100644 --- a/usr/src/lib/libshell/common/sh/init.c +++ b/usr/src/lib/libshell/common/sh/init.c @@ -1,10 +1,10 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1982-2007 AT&T Knowledge Ventures * +* Copyright (c) 1982-2008 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * -* by AT&T Knowledge Ventures * +* by AT&T Intellectual Property * * * * A copy of the License is available at * * http://www.opensource.org/licenses/cpl1.0.txt * @@ -32,6 +32,7 @@ #include <ctype.h> #include <ccode.h> #include <pwd.h> +#include <tmx.h> #include "variables.h" #include "path.h" #include "fault.h" @@ -46,17 +47,44 @@ #include "lexstates.h" #include "version.h" +char e_version[] = "\n@(#)$Id: Version " +#if SHOPT_AUDIT +#define ATTRS 1 + "A" +#endif +#if SHOPT_BASH +#define ATTRS 1 + "B" +#endif +#if SHOPT_ACCT +#define ATTRS 1 + "L" +#endif #if SHOPT_MULTIBYTE - char e_version[] = "\n@(#)$Id: Version M "SH_RELEASE" $\0\n"; -#else - char e_version[] = "\n@(#)$Id: Version "SH_RELEASE" $\0\n"; -#endif /* SHOPT_MULTIBYTE */ +#define ATTRS 1 + "M" +#endif +#if SHOPT_PFSH && _hdr_exec_attr +#define ATTRS 1 + "P" +#endif +#if ATTRS + " " +#endif + SH_RELEASE " $\0\n"; #if SHOPT_BASH - extern void bash_init(int); + extern void bash_init(Shell_t*,int); #endif #define RANDMASK 0x7fff + +#ifndef ARG_MAX +# define ARG_MAX (1*1024*1024) +#endif +#ifndef CHILD_MAX +# define CHILD_MAX (1*1024) +#endif #ifndef CLK_TCK # define CLK_TCK 60 #endif /* CLK_TCK */ @@ -77,23 +105,15 @@ struct seconds struct rand { Namfun_t hdr; - Shell_t *sh; int32_t rand_last; }; struct ifs { Namfun_t hdr; - Shell_t *sh; Namval_t *ifsnp; }; -struct shell -{ - Namfun_t hdr; - Shell_t *sh; -}; - struct match { Namfun_t hdr; @@ -112,31 +132,33 @@ typedef struct _init_ Namfun_t VPATH_init; #endif /* SHOPT_FS_3D */ struct ifs IFS_init; - struct shell PATH_init; -#ifdef PATH_BFPATH - struct shell FPATH_init; - struct shell CDPATH_init; -#endif - struct shell SHELL_init; - struct shell ENV_init; - struct shell VISUAL_init; - struct shell EDITOR_init; - struct shell OPTINDEX_init; + Namfun_t PATH_init; + Namfun_t FPATH_init; + Namfun_t CDPATH_init; + Namfun_t SHELL_init; + Namfun_t ENV_init; + Namfun_t VISUAL_init; + Namfun_t EDITOR_init; + Namfun_t HISTFILE_init; + Namfun_t HISTSIZE_init; + Namfun_t OPTINDEX_init; struct seconds SECONDS_init; struct rand RAND_init; - struct shell LINENO_init; - struct shell L_ARG_init; + Namfun_t LINENO_init; + Namfun_t L_ARG_init; + Namfun_t SH_VERSION_init; struct match SH_MATCH_init; #ifdef _hdr_locale - struct shell LC_TYPE_init; - struct shell LC_NUM_init; - struct shell LC_COLL_init; - struct shell LC_MSG_init; - struct shell LC_ALL_init; - struct shell LANG_init; + Namfun_t LC_TYPE_init; + Namfun_t LC_NUM_init; + Namfun_t LC_COLL_init; + Namfun_t LC_MSG_init; + Namfun_t LC_ALL_init; + Namfun_t LANG_init; #endif /* _hdr_locale */ } Init_t; +static int nbltins; static void env_init(Shell_t*); static Init_t *nv_init(Shell_t*); static Dt_t *inittree(Shell_t*,const struct shtable2*); @@ -173,12 +195,13 @@ static char *nospace(int unused) static void put_ed(register Namval_t* np,const char *val,int flags,Namfun_t *fp) { register const char *cp, *name=nv_name(np); - if(*name=='E' && nv_getval(nv_scoped(VISINOD))) + Shell_t *shp = nv_shell(np); + if(*name=='E' && nv_getval(sh_scoped(shp,VISINOD))) goto done; sh_offoption(SH_VI); sh_offoption(SH_EMACS); sh_offoption(SH_GMACS); - if(!(cp=val) && (*name=='E' || !(cp=nv_getval(nv_scoped(EDITNOD))))) + if(!(cp=val) && (*name=='E' || !(cp=nv_getval(sh_scoped(shp,EDITNOD))))) goto done; /* turn on vi or emacs option if editor name is either*/ cp = path_basename(cp); @@ -192,12 +215,37 @@ done: nv_putv(np, val, flags, fp); } +/* Trap for HISTFILE and HISTSIZE variables */ +static void put_history(register Namval_t* np,const char *val,int flags,Namfun_t *fp) +{ + Shell_t *shp = nv_shell(np); + void *histopen = shp->hist_ptr; + if(val && histopen) + { + if(np==HISTFILE && strcmp(val,nv_getval(HISTFILE))==0) + return; + if(np==HISTSIZE && sh_arith(val)==nv_getnum(HISTSIZE)) + return; + hist_close(shp->hist_ptr); + } + nv_putv(np, val, flags, fp); + if(histopen) + { + if(val) + sh_histinit(shp); + else + hist_close(histopen); + } +} + /* Trap for OPTINDEX */ static void put_optindex(Namval_t* np,const char *val,int flags,Namfun_t *fp) { - Shell_t *shp = ((struct shell*)fp)->sh; + Shell_t *shp = nv_shell(np); shp->st.opterror = shp->st.optchar = 0; nv_putv(np, val, flags, fp); + if(!val) + nv_disc(np,fp,NV_POP); } static Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp) @@ -205,34 +253,37 @@ static Sfdouble_t nget_optindex(register Namval_t* np, Namfun_t *fp) return((Sfdouble_t)*np->nvalue.lp); } +static Namfun_t *clone_optindex(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp) +{ + Namfun_t *dp = (Namfun_t*)malloc(sizeof(Namfun_t)); + memcpy((void*)dp,(void*)fp,sizeof(Namfun_t)); + mp->nvalue.lp = np->nvalue.lp; + dp->nofree = 0; + return(dp); +} + + /* Trap for restricted variables FPATH, PATH, SHELL, ENV */ static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp) { - Shell_t *shp = ((struct shell*)fp)->sh; - int path_scoped = 0; -#ifdef PATH_BFPATH + Shell_t *shp = nv_shell(np); + int path_scoped = 0; Pathcomp_t *pp; char *name = nv_name(np); -#endif if(!(flags&NV_RDONLY) && sh_isoption(SH_RESTRICTED)) errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np)); if(np==PATHNOD || (path_scoped=(strcmp(name,PATHNOD->nvname)==0))) { -#ifndef PATH_BFPATH - shp->lastpath = 0; -#endif nv_scan(shp->track_tree,rehash,(void*)0,NV_TAGGED,NV_TAGGED); if(path_scoped && !val) val = PATHNOD->nvalue.cp; } if(val && !(flags&NV_RDONLY) && np->nvalue.cp && strcmp(val,np->nvalue.cp)==0) return; -#ifdef PATH_BFPATH - if(shp->pathlist && np==FPATHNOD) + if(np==FPATHNOD) shp->pathlist = (void*)path_unsetfpath((Pathcomp_t*)shp->pathlist); -#endif nv_putv(np, val, flags, fp); -#ifdef PATH_BFPATH + shp->universe = 0; if(shp->pathlist) { val = np->nvalue.cp; @@ -255,14 +306,12 @@ sfprintf(sfstderr,"%d: name=%s val=%s\n",getpid(),name,val); path_dump((Pathcomp_t*)shp->pathlist); #endif } -#endif } -#ifdef PATH_BFPATH static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t *fp) { Pathcomp_t *pp; - Shell_t *shp = ((struct shell*)fp)->sh; + Shell_t *shp = nv_shell(np); nv_putv(np, val, flags, fp); if(!shp->cdpathlist) return; @@ -271,7 +320,6 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t if(shp->cdpathlist = (void*)pp) pp->shp = shp; } -#endif #ifdef _hdr_locale /* @@ -295,6 +343,7 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t /* Trap for LC_ALL, LC_TYPE, LC_MESSAGES, LC_COLLATE and LANG */ static void put_lang(Namval_t* np,const char *val,int flags,Namfun_t *fp) { + Shell_t *shp = nv_shell(np); int type; char *lc_all = nv_getval(LCALLNOD); char *name = nv_name(np); @@ -314,11 +363,11 @@ static void put_cdpath(register Namval_t* np,const char *val,int flags,Namfun_t type= -1; if(sh_isstate(SH_INIT) && type>=0 && type!=LC_ALL && lc_all && *lc_all) type= -1; - if(type>=0) + if(type>=0 || type==LC_ALL) { if(!setlocale(type,val?val:"")) { - if(!sh_isstate(SH_INIT) || sh.login_sh==0) + if(!sh_isstate(SH_INIT) || shp->login_sh==0) errormsg(SH_DICT,0,e_badlocale,val); return; } @@ -397,7 +446,7 @@ static char* get_ifs(register Namval_t* np, Namfun_t *fp) register struct ifs *ip = (struct ifs*)fp; register char *cp, *value; register int c,n; - register Shell_t *shp = ip->sh; + register Shell_t *shp = nv_shell(np); value = nv_getv(np,fp); if(np!=ip->ifsnp) { @@ -463,6 +512,7 @@ static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t if(!np->nvalue.dp) { nv_setsize(np,3); + nv_onattr(np,NV_DOUBLE); np->nvalue.dp = new_of(double,0); } nv_putv(np, val, flags, fp); @@ -473,14 +523,15 @@ static void put_seconds(register Namval_t* np,const char *val,int flags,Namfun_t static char* get_seconds(register Namval_t* np, Namfun_t *fp) { + Shell_t *shp = nv_shell(np); register int places = nv_size(np); struct tms tp; double d, offset = (np->nvalue.dp?*np->nvalue.dp:0); NOT_USED(fp); timeofday(&tp); d = dtime(&tp)- offset; - sfprintf(sh.strbuf,"%.*f",places,d); - return(sfstruse(sh.strbuf)); + sfprintf(shp->strbuf,"%.*f",places,d); + return(sfstruse(shp->strbuf)); } static Sfdouble_t nget_seconds(register Namval_t* np, Namfun_t *fp) @@ -554,7 +605,7 @@ static Sfdouble_t nget_lineno(Namval_t* np, Namfun_t *fp) static void put_lineno(Namval_t* np,const char *val,int flags,Namfun_t *fp) { register long n; - Shell_t *shp = ((struct shell*)fp)->sh; + Shell_t *shp = nv_shell(np); if(!val) { nv_stack(np, NIL(Namfun_t*)); @@ -576,25 +627,27 @@ static char* get_lineno(register Namval_t* np, Namfun_t *fp) static char* get_lastarg(Namval_t* np, Namfun_t *fp) { + Shell_t *shp = nv_shell(np); NOT_USED(np); - return(sh.lastarg); + return(shp->lastarg); } static void put_lastarg(Namval_t* np,const char *val,int flags,Namfun_t *fp) { + Shell_t *shp = nv_shell(np); if(flags&NV_INTEGER) { - sfprintf(sh.strbuf,"%.*g",12,*((double*)val)); - val = sfstruse(sh.strbuf); + sfprintf(shp->strbuf,"%.*g",12,*((double*)val)); + val = sfstruse(shp->strbuf); } - if(sh.lastarg && !nv_isattr(np,NV_NOFREE)) - free((void*)sh.lastarg); + if(shp->lastarg && !nv_isattr(np,NV_NOFREE)) + free((void*)shp->lastarg); else nv_offattr(np,NV_NOFREE); if(val) - sh.lastarg = strdup(val); + shp->lastarg = strdup(val); else - sh.lastarg = 0; + shp->lastarg = 0; } static int hasgetdisc(register Namfun_t *fp) @@ -635,7 +688,7 @@ void sh_setmatch(const char *v, int vsize, int nmatch, int match[]) } memcpy(mp->val,v,vsize); mp->val[vsize] = 0; - nv_putsub(SH_MATCHNOD, NIL(char*), nmatch|ARRAY_FILL); + nv_putsub(SH_MATCHNOD, NIL(char*), (nmatch-1)|ARRAY_FILL); mp->lastsub = -1; } } @@ -670,7 +723,30 @@ static char* get_match(register Namval_t* np, Namfun_t *fp) return(mp->rval); } -static const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match }; +static const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match }; + +static char* get_version(register Namval_t* np, Namfun_t *fp) +{ + return(nv_getv(np,fp)); +} + +static Sfdouble_t nget_version(register Namval_t* np, Namfun_t *fp) +{ + register const char *cp = e_version + strlen(e_version)-10; + register int c; + Sflong_t t = 0; + NOT_USED(fp); + + while (c = *cp++) + if (c >= '0' && c <= '9') + { + t *= 10; + t += c - '0'; + } + return((Sfdouble_t)t); +} + +static const Namdisc_t SH_VERSION_disc = { 0, 0, get_version, nget_version }; #if SHOPT_FS_3D /* @@ -709,16 +785,15 @@ static const Namdisc_t SH_MATCH_disc = { sizeof(struct match), 0, get_match }; static const Namdisc_t IFS_disc = { sizeof(struct ifs), put_ifs, get_ifs }; -const Namdisc_t RESTRICTED_disc = { sizeof(struct shell), put_restricted }; -#ifdef PATH_BFPATH -static const Namdisc_t CDPATH_disc = { sizeof(struct shell), put_cdpath }; -#endif -static const Namdisc_t EDITOR_disc = { sizeof(struct shell), put_ed }; -static const Namdisc_t OPTINDEX_disc = { sizeof(struct shell), put_optindex, 0, nget_optindex }; +const Namdisc_t RESTRICTED_disc = { sizeof(Namfun_t), put_restricted }; +static const Namdisc_t CDPATH_disc = { sizeof(Namfun_t), put_cdpath }; +static const Namdisc_t EDITOR_disc = { sizeof(Namfun_t), put_ed }; +static const Namdisc_t HISTFILE_disc = { sizeof(Namfun_t), put_history }; +static const Namdisc_t OPTINDEX_disc = { sizeof(Namfun_t), put_optindex, 0, nget_optindex, 0, 0, clone_optindex }; static const Namdisc_t SECONDS_disc = { sizeof(struct seconds), put_seconds, get_seconds, nget_seconds }; static const Namdisc_t RAND_disc = { sizeof(struct rand), put_rand, get_rand, nget_rand }; -static const Namdisc_t LINENO_disc = { sizeof(struct shell), put_lineno, get_lineno, nget_lineno }; -static const Namdisc_t L_ARG_disc = { sizeof(struct shell), put_lastarg, get_lastarg }; +static const Namdisc_t LINENO_disc = { sizeof(Namfun_t), put_lineno, get_lineno, nget_lineno }; +static const Namdisc_t L_ARG_disc = { sizeof(Namfun_t), put_lastarg, get_lastarg }; #if SHOPT_NAMESPACE static char* get_nspace(Namval_t* np, Namfun_t *fp) @@ -732,7 +807,7 @@ static const Namdisc_t L_ARG_disc = { sizeof(struct shell), put_lastarg, get_la #endif /* SHOPT_NAMESPACE */ #ifdef _hdr_locale - static const Namdisc_t LC_disc = { sizeof(struct shell), put_lang }; + static const Namdisc_t LC_disc = { sizeof(Namfun_t), put_lang }; #endif /* _hdr_locale */ /* @@ -841,25 +916,66 @@ int sh_type(register const char *path) } break; } - if (*s++ != 's' || *s++ != 'h') - return 0; - t |= SH_TYPE_SH; - if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3') - s += 2; + if (*s++ == 's' && (*s == 'h' || *s == 'u')) + { + s++; + t |= SH_TYPE_SH; + if ((t & SH_TYPE_KSH) && *s == '9' && *(s+1) == '3') + s += 2; #if _WINIX - if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e') - s += 4; + if (*s == '.' && *(s+1) == 'e' && *(s+2) == 'x' && *(s+3) == 'e') + s += 4; #endif - if (*s) - t &= ~(SH_TYPE_PROFILE|SH_TYPE_RESTRICTED); - return t; + if (!isalnum(*s)) + return t; + } + return t & ~(SH_TYPE_BASH|SH_TYPE_KSH|SH_TYPE_PROFILE|SH_TYPE_RESTRICTED); +} + + +static char *get_mode(Namval_t* np, Namfun_t* nfp) +{ + mode_t mode = nv_getn(np,nfp); + return(fmtperm(mode)); +} + +static void put_mode(Namval_t* np, const char* val, int flag, Namfun_t* nfp) +{ + if(val) + { + mode_t mode; + char *last; + if(flag&NV_INTEGER) + { + if(flag&NV_LONG) + mode = *(Sfdouble_t*)val; + else + mode = *(double*)val; + } + else + mode = strperm(val, &last,0); + if(*last) + errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val); + nv_putv(np,(char*)&mode,NV_INTEGER,nfp); + } + else + nv_putv(np,val,flag,nfp); } +static const Namdisc_t modedisc = +{ + 0, + put_mode, + get_mode, +}; + + /* * initialize the shell */ -Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) +Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) { + Shell_t *shp = &sh; register int n; int type; static char *login_files[3]; @@ -871,25 +987,26 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) #else init_ebcdic(); #endif - umask(umask(0)); - sh.mac_context = sh_macopen(&sh); - sh.arg_context = sh_argopen(&sh); - sh.lex_context = (void*)sh_lexopen(0,&sh,1); - sh.ed_context = (void*)ed_open(&sh); - sh.strbuf = sfstropen(); - sfsetbuf(sh.strbuf,(char*)0,64); + umask(shp->mask=umask(0)); + shp->mac_context = sh_macopen(shp); + shp->arg_context = sh_argopen(shp); + shp->lex_context = (void*)sh_lexopen(0,shp,1); + shp->ed_context = (void*)ed_open(shp); + shp->strbuf = sfstropen(); + shp->stk = stkstd; + sfsetbuf(shp->strbuf,(char*)0,64); sh_onstate(SH_INIT); error_info.exit = sh_exit; error_info.id = path_basename(argv[0]); #if ERROR_VERSION >= 20000102L error_info.catalog = e_dict; #endif - sh.cpipe[0] = -1; - sh.coutpipe = -1; - sh.userid=getuid(); - sh.euserid=geteuid(); - sh.groupid=getgid(); - sh.egroupid=getegid(); + shp->cpipe[0] = -1; + shp->coutpipe = -1; + shp->userid=getuid(); + shp->euserid=geteuid(); + shp->groupid=getgid(); + shp->egroupid=getegid(); for(n=0;n < 10; n++) { /* don't use lower bits when rand() generates large numbers */ @@ -899,41 +1016,42 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) break; } } - sh.lim.clk_tck = getconf("CLK_TCK"); - sh.lim.arg_max = getconf("ARG_MAX"); - sh.lim.open_max = getconf("OPEN_MAX"); - sh.lim.child_max = getconf("CHILD_MAX"); - sh.lim.ngroups_max = getconf("NGROUPS_MAX"); - sh.lim.posix_version = getconf("VERSION"); - sh.lim.posix_jobcontrol = getconf("JOB_CONTROL"); - if(sh.lim.arg_max <=0) - sh.lim.arg_max = ARG_MAX; - if(sh.lim.child_max <=0) - sh.lim.child_max = CHILD_MAX; - if(sh.lim.open_max <0) - sh.lim.open_max = OPEN_MAX; - if(sh.lim.open_max > (SHRT_MAX-2)) - sh.lim.open_max = SHRT_MAX-2; - if(sh.lim.clk_tck <=0) - sh.lim.clk_tck = CLK_TCK; + shp->lim.clk_tck = getconf("CLK_TCK"); + shp->lim.arg_max = getconf("ARG_MAX"); + shp->lim.open_max = getconf("OPEN_MAX"); + shp->lim.child_max = getconf("CHILD_MAX"); + shp->lim.ngroups_max = getconf("NGROUPS_MAX"); + shp->lim.posix_version = getconf("VERSION"); + shp->lim.posix_jobcontrol = getconf("JOB_CONTROL"); + if(shp->lim.arg_max <=0) + shp->lim.arg_max = ARG_MAX; + if(shp->lim.child_max <=0) + shp->lim.child_max = CHILD_MAX; + if(shp->lim.open_max <0) + shp->lim.open_max = OPEN_MAX; + if(shp->lim.open_max > (SHRT_MAX-2)) + shp->lim.open_max = SHRT_MAX-2; + if(shp->lim.clk_tck <=0) + shp->lim.clk_tck = CLK_TCK; #if SHOPT_FS_3D if(fs3d(FS3D_TEST)) - sh.lim.fs3d = 1; + shp->lim.fs3d = 1; #endif /* SHOPT_FS_3D */ - sh_ioinit(); + sh_ioinit(shp); /* initialize signal handling */ - sh_siginit(); + sh_siginit(shp); stakinstall(NIL(Stak_t*),nospace); /* set up memory for name-value pairs */ - sh.init_context = nv_init(&sh); + shp->init_context = nv_init(shp); /* read the environment */ if(argc>0) { type = sh_type(*argv); if(type&SH_TYPE_LOGIN) - sh.login_sh = 2; + shp->login_sh = 2; } - env_init(&sh); + env_init(shp); + *SHLVL->nvalue.ip +=1; #if SHOPT_SPAWN { /* @@ -942,17 +1060,17 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) */ char *last, *cp=nv_getval(L_ARGNOD); char buff[PATH_MAX+1]; - sh.shpath = 0; - sfprintf(sh.strbuf,"/proc/%d/exe",getpid()); - if((n=readlink(sfstruse(sh.strbuf),buff,sizeof(buff)-1))>0) + shp->shpath = 0; + sfprintf(shp->strbuf,"/proc/%d/exe",getpid()); + if((n=readlink(sfstruse(shp->strbuf),buff,sizeof(buff)-1))>0) { buff[n] = 0; - sh.shpath = strdup(buff); + shp->shpath = strdup(buff); } else if((cp && (sh_type(cp)&SH_TYPE_SH)) || (argc>0 && strchr(cp= *argv,'/'))) { if(*cp=='/') - sh.shpath = strdup(cp); + shp->shpath = strdup(cp); else if(cp = nv_getval(PWDNOD)) { int offset = staktell(); @@ -960,7 +1078,7 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) stakputc('/'); stakputs(argv[0]); pathcanon(stakptr(offset),PATH_DOTDOT); - sh.shpath = strdup(stakptr(offset)); + shp->shpath = strdup(stakptr(offset)); stakseek(offset); } } @@ -972,7 +1090,7 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) #endif /* SHOPT_FS_3D */ astconfdisc(newconf); #if SHOPT_TIMEOUT - sh.st.tmout = SHOPT_TIMEOUT; + shp->st.tmout = SHOPT_TIMEOUT; #endif /* SHOPT_TIMEOUT */ /* initialize jobs table */ job_clear(); @@ -990,33 +1108,33 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) /* check for invocation as bash */ if(type&SH_TYPE_BASH) { - sh.userinit = userinit = bash_init; + shp->userinit = userinit = bash_init; sh_onoption(SH_BASH); sh_onstate(SH_PREINIT); - (*userinit)(0); + (*userinit)(shp, 0); sh_offstate(SH_PREINIT); } #endif /* look for options */ - /* sh.st.dolc is $# */ - if((sh.st.dolc = sh_argopts(-argc,argv)) < 0) + /* shp->st.dolc is $# */ + if((shp->st.dolc = sh_argopts(-argc,argv,shp)) < 0) { - sh.exitval = 2; - sh_done(0); + shp->exitval = 2; + sh_done(shp,0); } opt_info.disc = 0; - sh.st.dolv=argv+(argc-1)-sh.st.dolc; - sh.st.dolv[0] = argv[0]; - if(sh.st.dolc < 1) + shp->st.dolv=argv+(argc-1)-shp->st.dolc; + shp->st.dolv[0] = argv[0]; + if(shp->st.dolc < 1) sh_onoption(SH_SFLAG); if(!sh_isoption(SH_SFLAG)) { - sh.st.dolc--; - sh.st.dolv++; + shp->st.dolc--; + shp->st.dolv++; #if _WINIX { char* name; - name = sh.st.dolv[0]; + name = shp->st.dolv[0]; if(name[1]==':' && (name[2]=='/' || name[2]=='\\')) { #if _lib_pathposix @@ -1041,21 +1159,21 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) #if SHOPT_PFSH if (sh_isoption(SH_PFSH)) { - struct passwd *pw = getpwuid(sh.userid); + struct passwd *pw = getpwuid(shp->userid); if(pw) - sh.user = strdup(pw->pw_name); + shp->user = strdup(pw->pw_name); } #endif /* set[ug]id scripts require the -p flag */ - if(sh.userid!=sh.euserid || sh.groupid!=sh.egroupid) + if(shp->userid!=shp->euserid || shp->groupid!=shp->egroupid) { #if SHOPT_P_SUID /* require sh -p to run setuid and/or setgid */ - if(!sh_isoption(SH_PRIVILEGED) && sh.euserid < SHOPT_P_SUID) + if(!sh_isoption(SH_PRIVILEGED) && shp->euserid < SHOPT_P_SUID) { - setuid(sh.euserid=sh.userid); - setgid(sh.egroupid=sh.groupid); + setuid(shp->euserid=shp->userid); + setgid(shp->egroupid=shp->groupid); } else #else @@ -1063,7 +1181,7 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) #endif /* SHOPT_P_SUID */ #ifdef SHELLMAGIC /* careful of #! setuid scripts with name beginning with - */ - if(sh.login_sh && argv[1] && strcmp(argv[0],argv[1])==0) + if(shp->login_sh && argv[1] && strcmp(argv[0],argv[1])==0) errormsg(SH_DICT,ERROR_exit(1),e_prohibited); #endif /*SHELLMAGIC*/ } @@ -1071,25 +1189,52 @@ Shell_t *sh_init(register int argc,register char *argv[], void(*userinit)(int)) sh_offoption(SH_PRIVILEGED); /* shname for $0 in profiles and . scripts */ if(strmatch(argv[1],e_devfdNN)) - sh.shname = strdup(argv[0]); + shp->shname = strdup(argv[0]); else - sh.shname = strdup(sh.st.dolv[0]); + shp->shname = strdup(shp->st.dolv[0]); /* * return here for shell script execution * but not for parenthesis subshells */ - error_info.id = strdup(sh.st.dolv[0]); /* error_info.id is $0 */ - sh.jmpbuffer = (void*)&sh.checkbase; - sh_pushcontext(&sh.checkbase,SH_JMPSCRIPT); - sh.st.self = &sh.global; - sh.topscope = (Shscope_t*)sh.st.self; + error_info.id = strdup(shp->st.dolv[0]); /* error_info.id is $0 */ + shp->jmpbuffer = (void*)&shp->checkbase; + sh_pushcontext(&shp->checkbase,SH_JMPSCRIPT); + shp->st.self = &shp->global; + shp->topscope = (Shscope_t*)shp->st.self; sh_offstate(SH_INIT); login_files[0] = (char*)e_profile; login_files[1] = ".profile"; - sh.login_files = login_files; - if(sh.userinit=userinit) - (*userinit)(0); - return(&sh); + shp->login_files = login_files; + shp->bltindata.version = SH_VERSION; + shp->bltindata.shp = shp; + shp->bltindata.shrun = sh_run; + shp->bltindata.shtrap = sh_trap; + shp->bltindata.shexit = sh_exit; + shp->bltindata.shbltin = sh_addbuiltin; +#if _AST_VERSION >= 20080617L + shp->bltindata.shgetenv = getenv; + shp->bltindata.shsetenv = setenviron; + astintercept(&shp->bltindata,1); +#endif +#if 0 +#define NV_MKINTTYPE(x,y,z) nv_mkinttype(#x,sizeof(x),(x)-1<0,(y),(Namdisc_t*)z); + NV_MKINTTYPE(pid_t,"process id",0); + NV_MKINTTYPE(gid_t,"group id",0); + NV_MKINTTYPE(uid_t,"user id",0); + NV_MKINTTYPE(size_t,(const char*)0,0); + NV_MKINTTYPE(ssize_t,(const char*)0,0); + NV_MKINTTYPE(off_t,"offset in bytes",0); + NV_MKINTTYPE(ino_t,"\ai-\anode number",0); + NV_MKINTTYPE(mode_t,(const char*)0,&modedisc); + NV_MKINTTYPE(dev_t,"device id",0); + NV_MKINTTYPE(nlink_t,"hard link count",0); + NV_MKINTTYPE(blkcnt_t,"block count",0); + NV_MKINTTYPE(time_t,"seconds since the epoch",0); + nv_mkstat(); +#endif + if(shp->userinit=userinit) + (*userinit)(shp, 0); + return(shp); } Shell_t *sh_getinterp(void) @@ -1102,25 +1247,41 @@ Shell_t *sh_getinterp(void) */ int sh_reinit(char *argv[]) { + Shell_t *shp = &sh; Shopt_t opt; - dtclear(sh.fun_tree); - dtclose(sh.alias_tree); - sh.alias_tree = inittree(&sh,shtab_aliases); - sh.namespace = 0; - sh.inuse_bits = 0; - if(sh.userinit) - (*sh.userinit)(1); - if(sh.heredocs) + Namval_t *np,*npnext; + Dt_t *dp; + for(np=dtfirst(shp->fun_tree);np;np=npnext) { - sfclose(sh.heredocs); - sh.heredocs = 0; + if((dp=shp->fun_tree)->walk) + dp = dp->walk; + npnext = (Namval_t*)dtnext(shp->fun_tree,np); + if(np>= shp->bltin_cmds && np < &shp->bltin_cmds[nbltins]) + continue; + if(is_abuiltin(np) && nv_isattr(np,NV_EXPORT)) + continue; + if(*np->nvname=='/') + continue; + nv_delete(np,dp,NV_NOFREE); + } + dtclose(shp->alias_tree); + shp->alias_tree = inittree(shp,shtab_aliases); + shp->last_root = shp->var_tree; + shp->namespace = 0; + shp->inuse_bits = 0; + if(shp->userinit) + (*shp->userinit)(shp, 1); + if(shp->heredocs) + { + sfclose(shp->heredocs); + shp->heredocs = 0; } /* remove locals */ sh_onstate(SH_INIT); - nv_scan(sh.var_tree,sh_envnolocal,(void*)0,NV_EXPORT,0); - nv_scan(sh.var_tree,sh_envnolocal,(void*)0,NV_ARRAY,NV_ARRAY); + nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_EXPORT,0); + nv_scan(shp->var_tree,sh_envnolocal,(void*)0,NV_ARRAY,NV_ARRAY); sh_offstate(SH_INIT); - memset(sh.st.trapcom,0,(sh.st.trapmax+1)*sizeof(char*)); + memset(shp->st.trapcom,0,(shp->st.trapmax+1)*sizeof(char*)); memset((void*)&opt,0,sizeof(opt)); if(sh_isoption(SH_TRACKALL)) on_option(&opt,SH_TRACKALL); @@ -1132,18 +1293,19 @@ int sh_reinit(char *argv[]) on_option(&opt,SH_VI); if(sh_isoption(SH_VIRAW)) on_option(&opt,SH_VIRAW); - sh.options = opt; + shp->options = opt; /* set up new args */ if(argv) - sh.arglist = sh_argcreate(argv); - if(sh.arglist) - sh_argreset(sh.arglist,NIL(struct dolnod*)); - sh.envlist=0; - sh.curenv = 0; - sh.shname = error_info.id = strdup(sh.st.dolv[0]); + shp->arglist = sh_argcreate(argv); + if(shp->arglist) + sh_argreset(shp,shp->arglist,NIL(struct dolnod*)); + shp->envlist=0; + shp->curenv = 0; + shp->shname = error_info.id = strdup(shp->st.dolv[0]); sh_offstate(SH_FORKED); - sh.fn_depth = sh.dot_depth = 0; + shp->fn_depth = shp->dot_depth = 0; sh_sigreset(0); + *SHLVL->nvalue.ip +=1; return(1); } @@ -1152,11 +1314,7 @@ int sh_reinit(char *argv[]) */ Namfun_t *nv_cover(register Namval_t *np) { -#ifdef PATH_BFPATH if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==FPATHNOD || np==CDPNOD || np==SECONDS) -#else - if(np==IFSNOD || np==PATHNOD || np==SHELLNOD || np==SECONDS) -#endif return(np->nvfun); #ifdef _hdr_locale if(np==LCALLNOD || np==LCTYPENOD || np==LCMSGNOD || np==LCCOLLNOD || np==LCNUMNOD || np==LANGNOD) @@ -1165,110 +1323,205 @@ Namfun_t *nv_cover(register Namval_t *np) return(0); } -static Namtype_t typeset; static const char *shdiscnames[] = { "tilde", 0}; +#ifdef SHOPT_STATS +struct Stats +{ + Namfun_t hdr; + Shell_t *sh; + char *nodes; + int numnodes; + int current; +}; + +static Namval_t *next_stat(register Namval_t* np, Dt_t *root,Namfun_t *fp) +{ + struct Stats *sp = (struct Stats*)fp; + if(!root) + sp->current = 0; + else if(++sp->current>=sp->numnodes) + return(0); + return(nv_namptr(sp->nodes,sp->current)); +} + +static Namval_t *create_stat(Namval_t *np,const char *name,int flag,Namfun_t *fp) +{ + struct Stats *sp = (struct Stats*)fp; + register const char *cp=name; + register int i=0,n; + Namval_t *nq=0; + Shell_t *shp = sp->sh; + if(!name) + return(SH_STATS); + while((i=*cp++) && i != '=' && i != '+' && i!='['); + n = (cp-1) -name; + for(i=0; i < sp->numnodes; i++) + { + nq = nv_namptr(sp->nodes,i); + if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0) + goto found; + } + nq = 0; +found: + if(nq) + { + fp->last = (char*)&name[n]; + shp->last_table = SH_STATS; + } + else + errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np)); + return(nq); +} + +static const Namdisc_t stat_disc = +{ + 0, 0, 0, 0, 0, + create_stat, + 0, 0, + next_stat +}; + +static char *name_stat(Namval_t *np, Namfun_t *fp) +{ + Shell_t *shp = sh_getinterp(); + sfprintf(shp->strbuf,".sh.stats.%s",np->nvname); + return(sfstruse(shp->strbuf)); +} + +static const Namdisc_t stat_child_disc = +{ + 0,0,0,0,0,0,0, + name_stat +}; + +static Namfun_t stat_child_fun = +{ + &stat_child_disc, 1, 0, sizeof(Namfun_t) +}; + +static void stat_init(Shell_t *shp) +{ + int i,nstat = STAT_SUBSHELL+1; + struct Stats *sp = newof(0,struct Stats,1,nstat*NV_MINSZ); + Namval_t *np; + sp->numnodes = nstat; + sp->nodes = (char*)(sp+1); + shp->stats = (int*)calloc(sizeof(int*),nstat); + sp->sh = shp; + for(i=0; i < nstat; i++) + { + np = nv_namptr(sp->nodes,i); + np->nvfun = &stat_child_fun; + np->nvname = (char*)shtab_stats[i].sh_name; + nv_onattr(np,NV_RDONLY|NV_MINIMAL|NV_NOFREE|NV_INTEGER); + nv_setsize(np,10); + np->nvalue.ip = &shp->stats[i]; + } + sp->hdr.dsize = sizeof(struct Stats) + nstat*(sizeof(int)+NV_MINSZ); + sp->hdr.disc = &stat_disc; + nv_stack(SH_STATS,&sp->hdr); + sp->hdr.nofree = 1; + nv_setvtree(SH_STATS); +} +#else +# define stat_init(x) +#endif /* SHOPT_STATS */ + /* * Initialize the shell name and alias table */ static Init_t *nv_init(Shell_t *shp) { + static int shlvl=0; Namval_t *np; register Init_t *ip; double d=0; ip = newof(0,Init_t,1,0); if(!ip) return(0); + shp->nvfun.last = (char*)shp; + shp->nvfun.nofree = 1; ip->sh = shp; shp->var_base = shp->var_tree = inittree(shp,shtab_variables); + SHLVL->nvalue.ip = &shlvl; ip->IFS_init.hdr.disc = &IFS_disc; ip->IFS_init.hdr.nofree = 1; - ip->IFS_init.sh = shp; - ip->PATH_init.hdr.disc = &RESTRICTED_disc; - ip->PATH_init.hdr.nofree = 1; - ip->PATH_init.sh = shp; -#ifdef PATH_BFPATH - ip->FPATH_init.hdr.disc = &RESTRICTED_disc; - ip->FPATH_init.hdr.nofree = 1; - ip->FPATH_init.sh = shp; - ip->CDPATH_init.hdr.disc = &CDPATH_disc; - ip->CDPATH_init.hdr.nofree = 1; - ip->CDPATH_init.sh = shp; -#endif - ip->SHELL_init.hdr.disc = &RESTRICTED_disc; - ip->SHELL_init.sh = shp; - ip->SHELL_init.hdr.nofree = 1; - ip->ENV_init.hdr.disc = &RESTRICTED_disc; - ip->ENV_init.hdr.nofree = 1; - ip->ENV_init.sh = shp; - ip->VISUAL_init.hdr.disc = &EDITOR_disc; - ip->VISUAL_init.hdr.nofree = 1; - ip->VISUAL_init.sh = shp; - ip->EDITOR_init.hdr.disc = &EDITOR_disc; - ip->EDITOR_init.hdr.nofree = 1; - ip->EDITOR_init.sh = shp; - ip->OPTINDEX_init.hdr.disc = &OPTINDEX_disc; - ip->OPTINDEX_init.hdr.nofree = 1; - ip->OPTINDEX_init.sh = shp; + ip->PATH_init.disc = &RESTRICTED_disc; + ip->PATH_init.nofree = 1; + ip->FPATH_init.disc = &RESTRICTED_disc; + ip->FPATH_init.nofree = 1; + ip->CDPATH_init.disc = &CDPATH_disc; + ip->CDPATH_init.nofree = 1; + ip->SHELL_init.disc = &RESTRICTED_disc; + ip->SHELL_init.nofree = 1; + ip->ENV_init.disc = &RESTRICTED_disc; + ip->ENV_init.nofree = 1; + ip->VISUAL_init.disc = &EDITOR_disc; + ip->VISUAL_init.nofree = 1; + ip->EDITOR_init.disc = &EDITOR_disc; + ip->EDITOR_init.nofree = 1; + ip->HISTFILE_init.disc = &HISTFILE_disc; + ip->HISTFILE_init.nofree = 1; + ip->HISTSIZE_init.disc = &HISTFILE_disc; + ip->HISTSIZE_init.nofree = 1; + ip->OPTINDEX_init.disc = &OPTINDEX_disc; + ip->OPTINDEX_init.nofree = 1; ip->SECONDS_init.hdr.disc = &SECONDS_disc; ip->SECONDS_init.hdr.nofree = 1; - ip->SECONDS_init.sh = shp; ip->RAND_init.hdr.disc = &RAND_disc; ip->RAND_init.hdr.nofree = 1; ip->SH_MATCH_init.hdr.disc = &SH_MATCH_disc; ip->SH_MATCH_init.hdr.nofree = 1; - ip->LINENO_init.hdr.disc = &LINENO_disc; - ip->LINENO_init.hdr.nofree = 1; - ip->LINENO_init.sh = shp; - ip->L_ARG_init.hdr.disc = &L_ARG_disc; - ip->L_ARG_init.hdr.nofree = 1; + ip->SH_VERSION_init.disc = &SH_VERSION_disc; + ip->SH_VERSION_init.nofree = 1; + ip->LINENO_init.disc = &LINENO_disc; + ip->LINENO_init.nofree = 1; + ip->L_ARG_init.disc = &L_ARG_disc; + ip->L_ARG_init.nofree = 1; #ifdef _hdr_locale - ip->LC_TYPE_init.hdr.disc = &LC_disc; - ip->LC_TYPE_init.hdr.nofree = 1; - ip->LC_NUM_init.hdr.disc = &LC_disc; - ip->LC_NUM_init.hdr.nofree = 1; - ip->LC_COLL_init.hdr.disc = &LC_disc; - ip->LC_COLL_init.hdr.nofree = 1; - ip->LC_MSG_init.hdr.disc = &LC_disc; - ip->LC_MSG_init.hdr.nofree = 1; - ip->LC_ALL_init.hdr.disc = &LC_disc; - ip->LC_ALL_init.hdr.nofree = 1; - ip->LANG_init.hdr.disc = &LC_disc; - ip->LANG_init.hdr.nofree = 1; - ip->LC_TYPE_init.sh = shp; - ip->LC_NUM_init.sh = shp; - ip->LC_COLL_init.sh = shp; - ip->LC_MSG_init.sh = shp; - ip->LANG_init.sh = shp; + ip->LC_TYPE_init.disc = &LC_disc; + ip->LC_TYPE_init.nofree = 1; + ip->LC_NUM_init.disc = &LC_disc; + ip->LC_NUM_init.nofree = 1; + ip->LC_COLL_init.disc = &LC_disc; + ip->LC_COLL_init.nofree = 1; + ip->LC_MSG_init.disc = &LC_disc; + ip->LC_MSG_init.nofree = 1; + ip->LC_ALL_init.disc = &LC_disc; + ip->LC_ALL_init.nofree = 1; + ip->LANG_init.disc = &LC_disc; + ip->LANG_init.nofree = 1; #endif /* _hdr_locale */ nv_stack(IFSNOD, &ip->IFS_init.hdr); - nv_stack(PATHNOD, &ip->PATH_init.hdr); -#ifdef PATH_BFPATH - nv_stack(FPATHNOD, &ip->FPATH_init.hdr); - nv_stack(CDPNOD, &ip->CDPATH_init.hdr); -#endif - nv_stack(SHELLNOD, &ip->SHELL_init.hdr); - nv_stack(ENVNOD, &ip->ENV_init.hdr); - nv_stack(VISINOD, &ip->VISUAL_init.hdr); - nv_stack(EDITNOD, &ip->EDITOR_init.hdr); - nv_stack(OPTINDNOD, &ip->OPTINDEX_init.hdr); + nv_stack(PATHNOD, &ip->PATH_init); + nv_stack(FPATHNOD, &ip->FPATH_init); + nv_stack(CDPNOD, &ip->CDPATH_init); + nv_stack(SHELLNOD, &ip->SHELL_init); + nv_stack(ENVNOD, &ip->ENV_init); + nv_stack(VISINOD, &ip->VISUAL_init); + nv_stack(EDITNOD, &ip->EDITOR_init); + nv_stack(HISTFILE, &ip->HISTFILE_init); + nv_stack(HISTSIZE, &ip->HISTSIZE_init); + nv_stack(OPTINDNOD, &ip->OPTINDEX_init); nv_stack(SECONDS, &ip->SECONDS_init.hdr); - nv_stack(L_ARGNOD, &ip->L_ARG_init.hdr); - nv_putval(SECONDS, (char*)&d, NV_INTEGER|NV_DOUBLE); + nv_stack(L_ARGNOD, &ip->L_ARG_init); + nv_putval(SECONDS, (char*)&d, NV_DOUBLE); nv_stack(RANDNOD, &ip->RAND_init.hdr); d = (shp->pid&RANDMASK); - nv_putval(RANDNOD, (char*)&d, NV_INTEGER|NV_DOUBLE); - nv_stack(LINENO, &ip->LINENO_init.hdr); + nv_putval(RANDNOD, (char*)&d, NV_DOUBLE); + nv_stack(LINENO, &ip->LINENO_init); nv_putsub(SH_MATCHNOD,(char*)0,10); nv_onattr(SH_MATCHNOD,NV_RDONLY); nv_stack(SH_MATCHNOD, &ip->SH_MATCH_init.hdr); + nv_stack(SH_VERSIONNOD, &ip->SH_VERSION_init); #ifdef _hdr_locale - nv_stack(LCTYPENOD, &ip->LC_TYPE_init.hdr); - nv_stack(LCALLNOD, &ip->LC_ALL_init.hdr); - nv_stack(LCMSGNOD, &ip->LC_MSG_init.hdr); - nv_stack(LCCOLLNOD, &ip->LC_COLL_init.hdr); - nv_stack(LCNUMNOD, &ip->LC_NUM_init.hdr); - nv_stack(LANGNOD, &ip->LANG_init.hdr); + nv_stack(LCTYPENOD, &ip->LC_TYPE_init); + nv_stack(LCALLNOD, &ip->LC_ALL_init); + nv_stack(LCMSGNOD, &ip->LC_MSG_init); + nv_stack(LCCOLLNOD, &ip->LC_COLL_init); + nv_stack(LCNUMNOD, &ip->LC_NUM_init); + nv_stack(LANGNOD, &ip->LANG_init); #endif /* _hdr_locale */ (PPIDNOD)->nvalue.lp = (&shp->ppid); (TMOUTNOD)->nvalue.lp = (&shp->st.tmout); @@ -1278,12 +1531,6 @@ static Init_t *nv_init(Shell_t *shp) shp->alias_tree = inittree(shp,shtab_aliases); shp->track_tree = dtopen(&_Nvdisc,Dtset); shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); - typeset.shp = shp; - typeset.optstring = sh_opttypeset; - nv_search("typeset",shp->bltin_tree,0)->nvfun = (void*)&typeset; -#if SHOPT_BASH - nv_search("local",shp->bltin_tree,0)->nvfun = (void*)&typeset; -#endif shp->fun_tree = dtopen(&_Nvdisc,Dtoset); dtview(shp->fun_tree,shp->bltin_tree); #if SHOPT_NAMESPACE @@ -1293,8 +1540,15 @@ static Init_t *nv_init(Shell_t *shp) nv_putval(np,".sh.global",NV_RDONLY|NV_NOFREE); nv_stack(np, &NSPACE_init); #endif /* SHOPT_NAMESPACE */ - np = nv_mount(DOTSHNOD, "type", dtopen(&_Nvdisc,Dtoset)); + np = nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0); + SH_LINENO->nvalue.ip = &shp->st.lineno; + VERSIONNOD->nvalue.nrp = newof(0,struct Namref,1,0); + VERSIONNOD->nvalue.nrp->np = SH_VERSIONNOD; + VERSIONNOD->nvalue.nrp->root = nv_dict(DOTSHNOD); + VERSIONNOD->nvalue.nrp->table = DOTSHNOD; + nv_onattr(VERSIONNOD,NV_RDONLY|NV_REF); + stat_init(shp); return(ip); } @@ -1313,10 +1567,17 @@ static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals) n++; np = (Namval_t*)calloc(n,sizeof(Namval_t)); if(!shp->bltin_nodes) + { shp->bltin_nodes = np; + shp->bltin_nnodes = n; + } else if(name_vals==(const struct shtable2*)shtab_builtins) + { shp->bltin_cmds = np; + nbltins = n; + } base_treep = treep = dtopen(&_Nvdisc,Dtoset); + treep->user = (void*)shp; for(tp=name_vals;*tp->sh_name;tp++,np++) { if((np->nvname = strrchr(tp->sh_name,'.')) && np->nvname!=((char*)tp->sh_name)) @@ -1330,7 +1591,11 @@ static Dt_t *inittree(Shell_t *shp,const struct shtable2 *name_vals) if(name_vals==(const struct shtable2*)shtab_builtins) np->nvalue.bfp = ((struct shtable3*)tp)->sh_value; else + { + if(name_vals == shtab_variables) + np->nvfun = &sh.nvfun; np->nvalue.cp = (char*)tp->sh_value; + } nv_setattr(np,tp->sh_number); if(nv_istable(np)) nv_mount(np,(const char*)0,dict=dtopen(&_Nvdisc,Dtoset)); @@ -1372,6 +1637,11 @@ static void env_init(Shell_t *shp) np->nvenv = cp; nv_close(np); } + else /* swap with fron */ + { + ep[-1] = environ[shp->nenv]; + environ[shp->nenv++] = cp; + } } while(cp=next) { @@ -1412,7 +1682,7 @@ static void env_init(Shell_t *shp) } } #ifdef _ENV_H - env_delete(sh.env,e_envmarker); + env_delete(shp->env,e_envmarker); #endif if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED)) { |