summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/sh/init.c
diff options
context:
space:
mode:
authorApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
committerApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
commit7c2fbfb345896881c631598ee3852ce9ce33fb07 (patch)
tree4b173b5657508562dfc0aa05f7d056d1e9add505 /usr/src/lib/libshell/common/sh/init.c
parent6071ac1de68fed78e1e10052045bbb5f1732a263 (diff)
downloadillumos-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.c796
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))
{