1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

[shp cleanup 01..20] all the rest (re: 2d3ec8b6)

This combines 20 cleanup commits from the dev branch.

All changed files:
- Clean up pointer defererences to sh.
- Remove shp arguments from functions.

Other notable changes:

src/cmd/ksh93/include/shell.h,
src/cmd/ksh93/sh/init.c:
- On second thought, get rid of the function version of
  sh_getinterp() as libshell ABI compatibility is moot. We've
  already been breaking that by reordering the sh struct, so there
  is no way it's going to work without recompiling.

src/cmd/ksh93/sh/name.c:
- De-obfuscate the relationship between nv_scan() and scanfilter().
  The former just calls the latter as a static function, there's no
  need to do that via a function pointer and void* type conversions.

src/cmd/ksh93/bltins/typeset.c,
src/cmd/ksh93/sh/name.c,
src/cmd/ksh93/sh/nvdisc.c:
- 'struct adata' and 'struct tdata', defined as local struct types
  in these files, need to have their first three fields in common,
  the first being a pointer to sh. This is because scanfilter() in
  name.c accesses these fields via a type conversion. So the sh
  field needed to be removed in all three at the same time.
  TODO: de-obfuscate: good practice definition via a header file.

src/cmd/ksh93/sh/path.c:
- Naming consistency: reserve the path_ function name prefix for
  externs and rename statics with that prefix.
- The default path was sometimes referred to as the standard path.
  To use one term, rename std_path to defpath and onstdpath() to
  ondefpath().
- De-obfuscate SHOPT_PFSH conditional code by only calling
  pf_execve() (was path_pfexecve()) if that is compiled in.

src/cmd/ksh93/include/streval.h,
src/cmd/ksh93/sh/streval.c:
- Rename extern strval() to arith_strval() for consistency.

src/cmd/ksh93/sh/string.c:
- Remove outdated/incorrect isxdigit() fallback; '#ifnded isxdigit'
  is not a correct test as isxdigit() is specified as a function.
  Plus, it's part of C89/C90 which we now require. (re: ac8991e5)

src/cmd/ksh93/sh/suid_exec.c:
- Replace an incorrect reference to shgd->current_pid with
  getpid(); it cannot work as (contrary to its misleading directory
  placement) suid_exec is an independent libast program with no
  link to ksh or libshell at all. However, no one noticed because
  this was in fallback code for ancient systems without
  setreuid(2). Since that standard function was specified in POSIX
  Issue 4 Version 2 from 1994, we should remove that fallback code
  sometime as part of another obsolete code cleanup operation to
  avoid further bit rot. (re: 843b546c)

src/cmd/ksh93/bltins/print.c: genformat():
- Remove preformat[] which was always empty and had no effect.

src/cmd/ksh93/shell.3:
- Minor copy-edit.
- Remove documentation for nonexistent sh.infile_name. A search
  through ast-open-archive[*] reveals this never existed at all.
- Document sh.savexit (== $?).

src/cmd/ksh93/shell.3,
src/cmd/ksh93/include/shell.h,
src/cmd/ksh93/sh/init.c:
- Remove sh.gd/shgd; this is now unused and was never documented
  or exposed in the shell.h public interface.
- sh_sigcheck() was documented in shell.3 as taking no arguments
  whereas in the actual code it took a shp argument. I decided to
  go with the documentation.
- That leaves sh_parse() as the only documented function that still
  takes an shp argument. I'm just going to go ahead and remove it
  for consistency, reverting sh_parse() to its pre-2003 spec.
- Remove undocumented/unused sh_bltin_tree() function which simply
  returned sh.bltin_tree.
- Bump SH_VERSION to 20220106.
This commit is contained in:
Martijn Dekker 2022-01-07 16:16:31 +00:00
parent 01da863154
commit b590a9f155
68 changed files with 3674 additions and 3935 deletions

View file

@ -31,7 +31,7 @@
* *
* > I never documented the alarm builtin because it is problematic. The * > I never documented the alarm builtin because it is problematic. The
* > problem is that traps can't safely be handled asynchronously. What should * > problem is that traps can't safely be handled asynchronously. What should
* > happen is that the trap is marked for execution (sh_trapnote) and run after * > happen is that the trap is marked for execution (sh.trapnote) and run after
* > the current command completes. The time trap should wake up the shell if * > the current command completes. The time trap should wake up the shell if
* > it is blocked and it should return and then handle the trap. * > it is blocked and it should return and then handle the trap.
*/ */
@ -54,7 +54,6 @@ struct tevent
long milli; long milli;
int flags; int flags;
void *timeout; void *timeout;
Shell_t *sh;
}; };
static const char ALARM[] = "alarm"; static const char ALARM[] = "alarm";
@ -127,23 +126,23 @@ static void print_alarms(void *list)
static void trap_timeout(void* handle) static void trap_timeout(void* handle)
{ {
register struct tevent *tp = (struct tevent*)handle; register struct tevent *tp = (struct tevent*)handle;
tp->sh->trapnote |= SH_SIGALRM; sh.trapnote |= SH_SIGALRM;
if(!(tp->flags&R_FLAG)) if(!(tp->flags&R_FLAG))
tp->timeout = 0; tp->timeout = 0;
tp->flags |= L_FLAG; tp->flags |= L_FLAG;
tp->sh->sigflag[SIGALRM] |= SH_SIGALRM; sh.sigflag[SIGALRM] |= SH_SIGALRM;
if(sh_isstate(SH_TTYWAIT)) if(sh_isstate(SH_TTYWAIT))
sh_timetraps(tp->sh); sh_timetraps();
} }
void sh_timetraps(Shell_t *shp) void sh_timetraps(void)
{ {
register struct tevent *tp, *tpnext; register struct tevent *tp, *tpnext;
register struct tevent *tptop; register struct tevent *tptop;
while(1) while(1)
{ {
shp->sigflag[SIGALRM] &= ~SH_SIGALRM; sh.sigflag[SIGALRM] &= ~SH_SIGALRM;
tptop= (struct tevent*)shp->st.timetrap; tptop= (struct tevent*)sh.st.timetrap;
for(tp=tptop;tp;tp=tpnext) for(tp=tptop;tp;tp=tpnext)
{ {
tpnext = tp->next; tpnext = tp->next;
@ -160,7 +159,7 @@ void sh_timetraps(Shell_t *shp)
} }
} }
} }
if(!(shp->sigflag[SIGALRM]&SH_SIGALRM)) if(!(sh.sigflag[SIGALRM]&SH_SIGALRM))
break; break;
} }
} }
@ -169,12 +168,11 @@ void sh_timetraps(Shell_t *shp)
/* /*
* This trap function catches "alarm" actions only * This trap function catches "alarm" actions only
*/ */
static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t *fp)
*fp)
{ {
register struct tevent *tp = (struct tevent*)fp; register struct tevent *tp = (struct tevent*)fp;
if(!event) if(!event)
return(action?"":(char*)ALARM); return(action ? Empty : (char*)ALARM);
if(strcmp(event,ALARM)!=0) if(strcmp(event,ALARM)!=0)
{ {
/* try the next level */ /* try the next level */
@ -184,7 +182,7 @@ static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t
action = tp->action; action = tp->action;
else else
tp->action = action; tp->action = action;
return(action?(char*)action:""); return(action ? (char*)action : Empty);
} }
/* /*
@ -194,7 +192,6 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
{ {
register struct tevent *tp = (struct tevent*)fp; register struct tevent *tp = (struct tevent*)fp;
register double d; register double d;
Shell_t *shp = tp->sh;
if(val) if(val)
{ {
double now; double now;
@ -216,14 +213,14 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
d -= now; d -= now;
tp->milli = 1000*(d+.0005); tp->milli = 1000*(d+.0005);
if(tp->timeout) if(tp->timeout)
shp->st.timetrap = time_delete(tp,shp->st.timetrap); sh.st.timetrap = time_delete(tp,sh.st.timetrap);
if(tp->milli > 0) if(tp->milli > 0)
shp->st.timetrap = time_add(tp,shp->st.timetrap); sh.st.timetrap = time_add(tp,sh.st.timetrap);
} }
else else
{ {
tp = (struct tevent*)nv_stack(np, (Namfun_t*)0); tp = (struct tevent*)nv_stack(np, (Namfun_t*)0);
shp->st.timetrap = time_delete(tp,shp->st.timetrap); sh.st.timetrap = time_delete(tp,sh.st.timetrap);
if(tp->action) if(tp->action)
nv_close(tp->action); nv_close(tp->action);
nv_unset(np); nv_unset(np);
@ -245,7 +242,6 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
register int n,rflag=0; register int n,rflag=0;
register Namval_t *np; register Namval_t *np;
register struct tevent *tp; register struct tevent *tp;
register Shell_t *shp = context->shp;
while (n = optget(argv, sh_optalarm)) switch (n) while (n = optget(argv, sh_optalarm)) switch (n)
{ {
case 'r': case 'r':
@ -267,7 +263,7 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
} }
if(argc==0) if(argc==0)
{ {
print_alarms(shp->st.timetrap); print_alarms(sh.st.timetrap);
return(0); return(0);
} }
if(argc!=2) if(argc!=2)
@ -275,7 +271,7 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
np = nv_open(argv[0],shp->var_tree,NV_NOARRAY|NV_VARNAME|NV_NOASSIGN); np = nv_open(argv[0],sh.var_tree,NV_NOARRAY|NV_VARNAME|NV_NOASSIGN);
if(!nv_isnull(np)) if(!nv_isnull(np))
nv_unset(np); nv_unset(np);
nv_setattr(np, NV_DOUBLE); nv_setattr(np, NV_DOUBLE);
@ -283,7 +279,6 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
tp->fun.disc = &alarmdisc; tp->fun.disc = &alarmdisc;
tp->flags = rflag; tp->flags = rflag;
tp->node = np; tp->node = np;
tp->sh = shp;
nv_stack(np,(Namfun_t*)tp); nv_stack(np,(Namfun_t*)tp);
nv_putval(np, argv[1], 0); nv_putval(np, argv[1], 0);
return(0); return(0);

View file

@ -54,11 +54,11 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
register char *dir; register char *dir;
Pathcomp_t *cdpath = 0; Pathcomp_t *cdpath = 0;
register const char *dp; register const char *dp;
register Shell_t *shp = context->shp;
int saverrno=0; int saverrno=0;
int rval,pflag=0,eflag=0,ret=1; int rval,pflag=0,eflag=0,ret=1;
char *oldpwd; char *oldpwd;
Namval_t *opwdnod, *pwdnod; Namval_t *opwdnod, *pwdnod;
NOT_USED(context);
while((rval = optget(argv,sh_optcd))) switch(rval) while((rval = optget(argv,sh_optcd))) switch(rval)
{ {
case 'e': case 'e':
@ -97,12 +97,12 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
oldpwd = path_pwd(shp,0); oldpwd = path_pwd();
opwdnod = sh_scoped(shp,OLDPWDNOD); opwdnod = sh_scoped(OLDPWDNOD);
pwdnod = sh_scoped(shp,PWDNOD); pwdnod = sh_scoped(PWDNOD);
if(oldpwd == e_dot && pwdnod->nvalue.cp) if(oldpwd == e_dot && pwdnod->nvalue.cp)
oldpwd = (char*)pwdnod->nvalue.cp; /* if path_pwd() failed to get the pwd, use $PWD */ oldpwd = (char*)pwdnod->nvalue.cp; /* if path_pwd() failed to get the pwd, use $PWD */
if(shp->subshell) if(sh.subshell)
{ {
/* clone $OLDPWD and $PWD into the subshell's scope */ /* clone $OLDPWD and $PWD into the subshell's scope */
opwdnod = sh_assignok(opwdnod,1); opwdnod = sh_assignok(opwdnod,1);
@ -123,7 +123,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
* If sh_subshell() in subshell.c cannot use fchdir(2) to restore the PWD using a saved file descriptor, * If sh_subshell() in subshell.c cannot use fchdir(2) to restore the PWD using a saved file descriptor,
* we must fork any virtual subshell now to avoid the possibility of ending up in the wrong PWD on exit. * we must fork any virtual subshell now to avoid the possibility of ending up in the wrong PWD on exit.
*/ */
if(shp->subshell && !shp->subshare) if(sh.subshell && !sh.subshare)
{ {
#if _lib_fchdir #if _lib_fchdir
if(!test_inode(nv_getval(pwdnod),e_dot)) if(!test_inode(nv_getval(pwdnod),e_dot))
@ -140,28 +140,25 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
&& !(dir[0]=='.' && (dir[1]=='/' || dir[1]==0)) && !(dir[0]=='.' && (dir[1]=='/' || dir[1]==0))
&& !(dir[0]=='.' && dir[1]=='.' && (dir[2]=='/' || dir[2]==0))) && !(dir[0]=='.' && dir[1]=='.' && (dir[2]=='/' || dir[2]==0)))
{ {
if((dp=sh_scoped(&sh,CDPNOD)->nvalue.cp) && !(cdpath = (Pathcomp_t*)shp->cdpathlist)) if((dp=sh_scoped(CDPNOD)->nvalue.cp) && !(cdpath = (Pathcomp_t*)sh.cdpathlist))
{ {
if(cdpath=path_addpath(shp,(Pathcomp_t*)0,dp,PATH_CDPATH)) if(cdpath=path_addpath((Pathcomp_t*)0,dp,PATH_CDPATH))
{ sh.cdpathlist = (void*)cdpath;
shp->cdpathlist = (void*)cdpath;
cdpath->shp = shp;
}
} }
} }
if(*dir!='/') if(*dir!='/')
{ {
/* check for leading .. */ /* check for leading .. */
char *cp; char *cp;
sfprintf(shp->strbuf,"%s",dir); sfprintf(sh.strbuf,"%s",dir);
cp = sfstruse(shp->strbuf); cp = sfstruse(sh.strbuf);
pathcanon(cp, 0); pathcanon(cp, 0);
if(cp[0]=='.' && cp[1]=='.' && (cp[2]=='/' || cp[2]==0)) if(cp[0]=='.' && cp[1]=='.' && (cp[2]=='/' || cp[2]==0))
{ {
if(!shp->strbuf2) if(!sh.strbuf2)
shp->strbuf2 = sfstropen(); sh.strbuf2 = sfstropen();
sfprintf(shp->strbuf2,"%s/%s",oldpwd,cp); sfprintf(sh.strbuf2,"%s/%s",oldpwd,cp);
dir = sfstruse(shp->strbuf2); dir = sfstruse(sh.strbuf2);
pathcanon(dir, 0); pathcanon(dir, 0);
} }
} }
@ -169,7 +166,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
do do
{ {
dp = cdpath?cdpath->name:""; dp = cdpath?cdpath->name:"";
cdpath = path_nextcomp(shp,cdpath,dir,0); cdpath = path_nextcomp(cdpath,dir,0);
#if _WINIX #if _WINIX
if(*stakptr(PATH_OFFSET+1)==':' && isalpha(*stakptr(PATH_OFFSET))) if(*stakptr(PATH_OFFSET+1)==':' && isalpha(*stakptr(PATH_OFFSET)))
{ {
@ -197,13 +194,13 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
if(!pathcanon(cp,PATH_DOTDOT)) if(!pathcanon(cp,PATH_DOTDOT))
continue; continue;
} }
if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0) if((rval=chdir(path_relative(stakptr(PATH_OFFSET)))) >= 0)
goto success; goto success;
if(errno!=ENOENT && saverrno==0) if(errno!=ENOENT && saverrno==0)
saverrno=errno; saverrno=errno;
} }
while(cdpath); while(cdpath);
if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/') if(rval<0 && *dir=='/' && *(path_relative(stakptr(PATH_OFFSET)))!='/')
rval = chdir(dir); rval = chdir(dir);
/* use absolute chdir() if relative chdir() fails */ /* use absolute chdir() if relative chdir() fails */
if(rval<0) if(rval<0)
@ -239,27 +236,27 @@ success:
dir[len] = 0; dir[len] = 0;
nv_putval(pwdnod,dir,NV_RDONLY); nv_putval(pwdnod,dir,NV_RDONLY);
nv_onattr(pwdnod,NV_EXPORT); nv_onattr(pwdnod,NV_EXPORT);
if(shp->pwd) if(sh.pwd)
free((void*)shp->pwd); free((void*)sh.pwd);
shp->pwd = sh_strdup(pwdnod->nvalue.cp); sh.pwd = sh_strdup(pwdnod->nvalue.cp);
} }
else else
{ {
/* pathcanon() failed to canonicalize the directory, which happens when 'cd' is invoked from a /* pathcanon() failed to canonicalize the directory, which happens when 'cd' is invoked from a
nonexistent PWD with a relative path as the argument. Reinitialize $PWD as it will be wrong. */ nonexistent PWD with a relative path as the argument. Reinitialize $PWD as it will be wrong. */
if(shp->pwd) if(sh.pwd)
free((void*)shp->pwd); free((void*)sh.pwd);
shp->pwd = NIL(const char*); sh.pwd = NIL(const char*);
path_pwd(shp,0); path_pwd();
if(*shp->pwd != '/') if(*sh.pwd != '/')
{ {
errormsg(SH_DICT,ERROR_system(ret),e_direct); errormsg(SH_DICT,ERROR_system(ret),e_direct);
UNREACHABLE(); UNREACHABLE();
} }
} }
nv_scan(sh_subtracktree(1),rehash,(void*)0,NV_TAGGED,NV_TAGGED); nv_scan(sh_subtracktree(1),rehash,(void*)0,NV_TAGGED,NV_TAGGED);
path_newdir(shp,shp->pathlist); path_newdir(sh.pathlist);
path_newdir(shp,shp->cdpathlist); path_newdir(sh.cdpathlist);
if(pflag && eflag) if(pflag && eflag)
{ {
/* Verify the current working directory matches $PWD */ /* Verify the current working directory matches $PWD */
@ -272,8 +269,8 @@ int b_pwd(int argc, char *argv[],Shbltin_t *context)
{ {
register int n, flag = 0; register int n, flag = 0;
register char *cp; register char *cp;
register Shell_t *shp = context->shp;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
while((n = optget(argv,sh_optpwd))) switch(n) while((n = optget(argv,sh_optpwd))) switch(n)
{ {
case 'L': case 'L':
@ -294,7 +291,7 @@ int b_pwd(int argc, char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
if(*(cp = path_pwd(shp,0)) != '/') if(*(cp = path_pwd()) != '/')
{ {
errormsg(SH_DICT,ERROR_system(1), e_pwd); errormsg(SH_DICT,ERROR_system(1), e_pwd);
UNREACHABLE(); UNREACHABLE();

View file

@ -99,7 +99,7 @@ int b_break(register int n, register char *argv[],Shbltin_t *context)
{ {
char *arg; char *arg;
register int cont= **argv=='c'; register int cont= **argv=='c';
register Shell_t *shp = context->shp; NOT_USED(context);
while((n = optget(argv,cont?sh_optcont:sh_optbreak))) switch(n) while((n = optget(argv,cont?sh_optcont:sh_optbreak))) switch(n)
{ {
case ':': case ':':
@ -125,13 +125,13 @@ int b_break(register int n, register char *argv[],Shbltin_t *context)
UNREACHABLE(); UNREACHABLE();
} }
} }
if(shp->st.loopcnt) if(sh.st.loopcnt)
{ {
shp->st.execbrk = shp->st.breakcnt = n; sh.st.execbrk = sh.st.breakcnt = n;
if(shp->st.breakcnt > shp->st.loopcnt) if(sh.st.breakcnt > sh.st.loopcnt)
shp->st.breakcnt = shp->st.loopcnt; sh.st.breakcnt = sh.st.loopcnt;
if(cont) if(cont)
shp->st.breakcnt = -shp->st.breakcnt; sh.st.breakcnt = -sh.st.breakcnt;
} }
return(0); return(0);
} }

View file

@ -209,7 +209,6 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
Namarr_t *ap; Namarr_t *ap;
char *cp,*sp; char *cp,*sp;
struct Enum *ep; struct Enum *ep;
Shell_t *shp = context->shp;
struct { struct {
Optdisc_t opt; Optdisc_t opt;
Namval_t *np; Namval_t *np;
@ -251,7 +250,7 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
} }
n = staktell(); n = staktell();
sfprintf(stkstd,"%s.%s%c",NV_CLASS,np->nvname,0); sfprintf(stkstd,"%s.%s%c",NV_CLASS,np->nvname,0);
tp = nv_open(stakptr(n), shp->var_tree, NV_VARNAME); tp = nv_open(stakptr(n), sh.var_tree, NV_VARNAME);
stakseek(n); stakseek(n);
n = sz; n = sz;
i = 0; i = 0;
@ -296,12 +295,12 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
#ifdef STANDALONE #ifdef STANDALONE
void lib_init(int flag, void* context) void lib_init(int flag, void* context)
{ {
Shell_t *shp = ((Shbltin_t*)context)->shp;
Namval_t *mp,*bp; Namval_t *mp,*bp;
NOT_USED(context);
if(flag) if(flag)
return; return;
bp = sh_addbuiltin("Enum", enum_create, (void*)0); bp = sh_addbuiltin("Enum", enum_create, (void*)0);
mp = nv_search("typeset",shp->bltin_tree,0); mp = nv_search("typeset",sh.bltin_tree,0);
nv_onattr(bp,nv_isattr(mp,NV_PUBLIC)); nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
} }
#endif #endif

View file

@ -35,12 +35,11 @@
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp) static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
{ {
Shell_t *shp = *(Shell_t**)(dp+1); Stk_t *stkp = sh.stk;
Stk_t *stkp = shp->stk;
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if((shp->namespace && sh_fsearch(shp,s,0)) || nv_search(s,shp->fun_tree,0)) if((sh.namespace && sh_fsearch(s,0)) || nv_search(s,sh.fun_tree,0))
#else #else
if(nv_search(s,shp->fun_tree,0)) if(nv_search(s,sh.fun_tree,0))
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
{ {
int savtop = stktell(stkp); int savtop = stktell(stkp);
@ -48,7 +47,7 @@ static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
sfputc(stkp,'$'); sfputc(stkp,'$');
sfputc(stkp,'('); sfputc(stkp,'(');
sfputr(stkp,s,')'); sfputr(stkp,s,')');
sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1); sfputr(sp,sh_mactry(stkfreeze(stkp,1)),-1);
stkset(stkp,savptr,savtop); stkset(stkp,savptr,savtop);
} }
return(1); return(1);
@ -59,19 +58,14 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
register char *options=error_info.context->id; register char *options=error_info.context->id;
register Namval_t *np; register Namval_t *np;
register int flag, mode; register int flag, mode;
register Shell_t *shp = context->shp;
char value[2], key[2]; char value[2], key[2];
int jmpval; int jmpval;
volatile int extended, r= -1; volatile int extended, r= -1;
struct checkpt buff, *pp; struct checkpt buff, *pp;
struct { Optdisc_t disc;
Optdisc_t hdr;
Shell_t *sh;
} disc;
memset(&disc, 0, sizeof(disc)); memset(&disc, 0, sizeof(disc));
disc.hdr.version = OPT_VERSION; disc.version = OPT_VERSION;
disc.hdr.infof = infof; disc.infof = infof;
disc.sh = shp;
value[1] = 0; value[1] = 0;
key[1] = 0; key[1] = 0;
while((flag = optget(argv,sh_optgetopts))) switch(flag) while((flag = optget(argv,sh_optgetopts))) switch(flag)
@ -96,7 +90,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
error_info.context->flags |= ERROR_SILENT; error_info.context->flags |= ERROR_SILENT;
error_info.id = options; error_info.id = options;
options = argv[0]; options = argv[0];
np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME); np = nv_open(argv[1],sh.var_tree,NV_NOASSIGN|NV_VARNAME);
if(argc>2) if(argc>2)
{ {
argv +=1; argv +=1;
@ -104,27 +98,27 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
} }
else else
{ {
argv = shp->st.dolv; argv = sh.st.dolv;
argc = shp->st.dolc; argc = sh.st.dolc;
} }
opt_info.index = shp->st.optindex; opt_info.index = sh.st.optindex;
opt_info.offset = shp->st.optchar; opt_info.offset = sh.st.optchar;
if(mode= (*options==':')) if(mode= (*options==':'))
options++; options++;
extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-'; extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
sh_pushcontext(shp,&buff,1); sh_pushcontext(&sh,&buff,1);
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
if(jmpval) if(jmpval)
{ {
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
shp->st.opterror = 1; sh.st.opterror = 1;
if(r==0) if(r==0)
return(2); return(2);
pp = (struct checkpt*)shp->jmplist; pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPERREXIT; pp->mode = SH_JMPERREXIT;
sh_exit(2); sh_exit(2);
} }
opt_info.disc = &disc.hdr; opt_info.disc = &disc;
switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0) switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
{ {
case '?': case '?':
@ -148,7 +142,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
flag = '?'; flag = '?';
} }
*(options = value) = flag; *(options = value) = flag;
shp->st.opterror = 1; sh.st.opterror = 1;
if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset]) if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
{ {
opt_info.offset = 0; opt_info.offset = 0;
@ -156,7 +150,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
} }
break; break;
case 0: case 0:
if(shp->st.opterror) if(sh.st.opterror)
{ {
char *com[2]; char *com[2];
com[0] = "-?"; com[0] = "-?";
@ -183,11 +177,11 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
if(r<0) if(r<0)
r = 0; r = 0;
error_info.context->flags &= ~ERROR_SILENT; error_info.context->flags &= ~ERROR_SILENT;
shp->st.optindex = opt_info.index; sh.st.optindex = opt_info.index;
shp->st.optchar = opt_info.offset; sh.st.optchar = opt_info.offset;
nv_putval(np, options, 0); nv_putval(np, options, 0);
nv_close(np); nv_close(np);
np = nv_open(nv_name(OPTARGNOD),shp->var_tree,0); np = nv_open(nv_name(OPTARGNOD),sh.var_tree,0);
if(opt_info.num == LONG_MIN) if(opt_info.num == LONG_MIN)
nv_putval(np, opt_info.arg, NV_RDONLY); nv_putval(np, opt_info.arg, NV_RDONLY);
else if (opt_info.arg && opt_info.num > 0 && isalpha((char)opt_info.num) && !isdigit(opt_info.arg[0]) && opt_info.arg[0] != '-' && opt_info.arg[0] != '+') else if (opt_info.arg && opt_info.num > 0 && isalpha((char)opt_info.num) && !isdigit(opt_info.arg[0]) && opt_info.arg[0] != '-' && opt_info.arg[0] != '+')
@ -205,7 +199,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
else else
nv_putval(np, opt_info.arg, NV_RDONLY); nv_putval(np, opt_info.arg, NV_RDONLY);
nv_close(np); nv_close(np);
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
opt_info.disc = 0; opt_info.disc = 0;
return(r); return(r);
} }

View file

@ -44,7 +44,6 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
register History_t *hp; register History_t *hp;
register char *arg; register char *arg;
register int flag,fdo; register int flag,fdo;
register Shell_t *shp = context->shp;
Sfio_t *outfile; Sfio_t *outfile;
char *fname; char *fname;
int range[2], incr, index2, indx= -1; int range[2], incr, index2, indx= -1;
@ -56,12 +55,13 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
#endif #endif
Histloc_t location; Histloc_t location;
NOT_USED(argc); NOT_USED(argc);
if(!sh_histinit((void*)shp)) NOT_USED(context);
if(!sh_histinit())
{ {
errormsg(SH_DICT,ERROR_system(1),e_histopen); errormsg(SH_DICT,ERROR_system(1),e_histopen);
UNREACHABLE(); UNREACHABLE();
} }
hp = shp->gd->hist_ptr; hp = sh.hist_ptr;
while((flag = optget(argv,sh_opthist))) switch(flag) while((flag = optget(argv,sh_opthist))) switch(flag)
{ {
case 'e': case 'e':
@ -214,7 +214,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
errormsg(SH_DICT,ERROR_system(1),e_create,fname); errormsg(SH_DICT,ERROR_system(1),e_create,fname);
UNREACHABLE(); UNREACHABLE();
} }
outfile= sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fdo,SF_WRITE); outfile= sfnew(NIL(Sfio_t*),sh.outbuff,IOBSIZE,fdo,SF_WRITE);
arg = "\n"; arg = "\n";
nflag++; nflag++;
} }
@ -224,9 +224,9 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
sfprintf(outfile,"%d\t",range[flag]); sfprintf(outfile,"%d\t",range[flag]);
else if(lflag) else if(lflag)
sfputc(outfile,'\t'); sfputc(outfile,'\t');
hist_list(shp->gd->hist_ptr,outfile,hist_tell(shp->gd->hist_ptr,range[flag]),0,arg); hist_list(sh.hist_ptr,outfile,hist_tell(sh.hist_ptr,range[flag]),0,arg);
if(lflag) if(lflag)
sh_sigcheck(shp); sh_sigcheck();
if(range[flag] == range[1-flag]) if(range[flag] == range[1-flag])
break; break;
range[flag] += incr; range[flag] += incr;
@ -236,7 +236,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
sfclose(outfile); sfclose(outfile);
hist_eof(hp); hist_eof(hp);
arg = edit; arg = edit;
if(!arg && !(arg=nv_getval(sh_scoped(shp,HISTEDIT))) && !(arg=nv_getval(sh_scoped(shp,FCEDNOD)))) if(!arg && !(arg=nv_getval(sh_scoped(HISTEDIT))) && !(arg=nv_getval(sh_scoped(FCEDNOD))))
{ {
arg = (char*)e_defedit; arg = (char*)e_defedit;
if(*arg!='/') if(*arg!='/')
@ -272,7 +272,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
char buff[IOBSIZE+1]; char buff[IOBSIZE+1];
Sfio_t *iop; Sfio_t *iop;
/* read in and run the command */ /* read in and run the command */
if(shp->hist_depth++ > HIST_RECURSE) if(sh.hist_depth++ > HIST_RECURSE)
{ {
sh_close(fdo); sh_close(fdo);
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,"history"); errormsg(SH_DICT,ERROR_exit(1),e_toodeep,"history");
@ -280,7 +280,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
} }
iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fdo,SF_READ); iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fdo,SF_READ);
sh_eval(iop,1); /* this will close fdo */ sh_eval(iop,1); /* this will close fdo */
shp->hist_depth--; sh.hist_depth--;
} }
else else
{ {
@ -289,7 +289,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
sh_offstate(SH_VERBOSE); sh_offstate(SH_VERBOSE);
sh_offstate(SH_HISTORY); sh_offstate(SH_HISTORY);
} }
return(shp->exitval); return(sh.exitval);
} }

View file

@ -84,6 +84,7 @@ int b_exec(int argc,char *argv[], Shbltin_t *context)
int clear = 0; int clear = 0;
char *arg0 = 0; char *arg0 = 0;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
sh.st.ioset = 0; sh.st.ioset = 0;
while (n = optget(argv, *argv[0]=='r' ? sh_optredirect : sh_optexec)) switch (n) while (n = optget(argv, *argv[0]=='r' ? sh_optredirect : sh_optexec)) switch (n)
{ {
@ -145,18 +146,18 @@ int b_exec(int argc,char *argv[], Shbltin_t *context)
if(arg0) if(arg0)
argv[0] = arg0; argv[0] = arg0;
#ifdef JOBS #ifdef JOBS
if(job_close(&sh) < 0) if(job_close() < 0)
return(1); return(1);
#endif /* JOBS */ #endif /* JOBS */
/* if the main shell is about to be replaced, decrease SHLVL to cancel out a subsequent increase */ /* if the main shell is about to be replaced, decrease SHLVL to cancel out a subsequent increase */
if(!shgd->realsubshell) if(!sh.realsubshell)
(*SHLVL->nvalue.ip)--; (*SHLVL->nvalue.ip)--;
/* force bad exec to terminate shell */ /* force bad exec to terminate shell */
pp = (struct checkpt*)sh.jmplist; pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPEXIT; pp->mode = SH_JMPEXIT;
sh_sigreset(2); sh_sigreset(2);
sh_freeup(&sh); sh_freeup();
path_exec(&sh,pname,argv,NIL(struct argnod*)); path_exec(pname,argv,NIL(struct argnod*));
} }
return(1); return(1);
} }
@ -165,8 +166,8 @@ int b_let(int argc,char *argv[],Shbltin_t *context)
{ {
register int r; register int r;
register char *arg; register char *arg;
Shell_t *shp = context->shp;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
while (r = optget(argv,sh_optlet)) switch (r) while (r = optget(argv,sh_optlet)) switch (r)
{ {
case ':': case ':':
@ -183,15 +184,15 @@ int b_let(int argc,char *argv[],Shbltin_t *context)
UNREACHABLE(); UNREACHABLE();
} }
while(arg= *argv++) while(arg= *argv++)
r = !sh_arith(shp,arg); r = !sh_arith(arg);
return(r); return(r);
} }
int b_eval(int argc,char *argv[], Shbltin_t *context) int b_eval(int argc,char *argv[], Shbltin_t *context)
{ {
register int r; register int r;
register Shell_t *shp = context->shp;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
while (r = optget(argv,sh_opteval)) switch (r) while (r = optget(argv,sh_opteval)) switch (r)
{ {
case ':': case ':':
@ -212,7 +213,7 @@ int b_eval(int argc,char *argv[], Shbltin_t *context)
sh_offstate(SH_MONITOR); sh_offstate(SH_MONITOR);
sh_eval(sh_sfeval(argv),0); sh_eval(sh_sfeval(argv),0);
} }
return(shp->exitval); return(sh.exitval);
} }
#if 0 #if 0
@ -224,8 +225,7 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
register char *script; register char *script;
register Namval_t *np; register Namval_t *np;
register int jmpval; register int jmpval;
register Shell_t *shp = context->shp; struct sh_scoped savst, *prevscope = sh.st.self;
struct sh_scoped savst, *prevscope = shp->st.self;
char *filename=0, *buffer=0, *tofree; char *filename=0, *buffer=0, *tofree;
int fd; int fd;
struct dolnod *saveargfor; struct dolnod *saveargfor;
@ -233,6 +233,7 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
struct checkpt buff; struct checkpt buff;
Sfio_t *iop=0; Sfio_t *iop=0;
short level; short level;
NOT_USED(context);
while (n = optget(argv,sh_optdot)) switch (n) while (n = optget(argv,sh_optdot)) switch (n)
{ {
case ':': case ':':
@ -249,20 +250,20 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
if(shp->dot_depth+1 > DOTMAX) if(sh.dot_depth+1 > DOTMAX)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script); errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
UNREACHABLE(); UNREACHABLE();
} }
if(!(np=shp->posix_fun)) if(!(np=sh.posix_fun))
{ {
/* check for KornShell style function first */ /* check for KornShell style function first */
np = nv_search(script,shp->fun_tree,0); np = nv_search(script,sh.fun_tree,0);
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && shp->bltindata.bnode==SYSDOT)) if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && sh.bltindata.bnode==SYSDOT))
{ {
if(!np->nvalue.ip) if(!np->nvalue.ip)
{ {
path_search(shp,script,NIL(Pathcomp_t**),0); path_search(script,NIL(Pathcomp_t**),0);
if(np->nvalue.ip) if(np->nvalue.ip)
{ {
if(nv_isattr(np,NV_FPOSIX)) if(nv_isattr(np,NV_FPOSIX))
@ -279,40 +280,40 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
np = 0; np = 0;
if(!np) if(!np)
{ {
if((fd=path_open(shp,script,path_get(shp,script))) < 0) if((fd=path_open(script,path_get(script))) < 0)
{ {
errormsg(SH_DICT,ERROR_system(1),e_open,script); errormsg(SH_DICT,ERROR_system(1),e_open,script);
UNREACHABLE(); UNREACHABLE();
} }
filename = path_fullname(shp,stkptr(shp->stk,PATH_OFFSET)); filename = path_fullname(stkptr(sh.stk,PATH_OFFSET));
} }
} }
*prevscope = shp->st; *prevscope = sh.st;
shp->st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1; sh.st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
shp->st.var_local = shp->st.save_tree = shp->var_tree; sh.st.var_local = sh.st.save_tree = sh.var_tree;
if(filename) if(filename)
{ {
shp->st.filename = filename; sh.st.filename = filename;
shp->st.lineno = 1; sh.st.lineno = 1;
} }
level = shp->fn_depth+shp->dot_depth+1; level = sh.fn_depth+sh.dot_depth+1;
nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16); nv_putval(SH_LEVELNOD,(char*)&level,NV_INT16);
shp->st.prevst = prevscope; sh.st.prevst = prevscope;
shp->st.self = &savst; sh.st.self = &savst;
shp->topscope = (Shscope_t*)shp->st.self; sh.topscope = (Shscope_t*)sh.st.self;
prevscope->save_tree = shp->var_tree; prevscope->save_tree = sh.var_tree;
tofree = shp->st.filename; tofree = sh.st.filename;
if(np) if(np)
shp->st.filename = np->nvalue.rp->fname; sh.st.filename = np->nvalue.rp->fname;
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE); nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
shp->posix_fun = 0; sh.posix_fun = 0;
if(np || argv[1]) if(np || argv[1])
argsave = sh_argnew(shp,argv,&saveargfor); argsave = sh_argnew(argv,&saveargfor);
sh_pushcontext(shp,&buff,SH_JMPDOT); sh_pushcontext(&sh,&buff,SH_JMPDOT);
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
if(jmpval == 0) if(jmpval == 0)
{ {
shp->dot_depth++; sh.dot_depth++;
if(np) if(np)
sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT)); sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
else else
@ -323,28 +324,28 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
sh_eval(iop,sh_isstate(SH_PROFILE)?SH_FUNEVAL:0); sh_eval(iop,sh_isstate(SH_PROFILE)?SH_FUNEVAL:0);
} }
} }
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
if(buffer) if(buffer)
free(buffer); free(buffer);
if(!np) if(!np)
free(tofree); free(tofree);
shp->dot_depth--; sh.dot_depth--;
if((np || argv[1]) && jmpval!=SH_JMPSCRIPT) if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
sh_argreset(shp,(struct dolnod*)argsave,saveargfor); sh_argreset((struct dolnod*)argsave,saveargfor);
else else
{ {
prevscope->dolc = shp->st.dolc; prevscope->dolc = sh.st.dolc;
prevscope->dolv = shp->st.dolv; prevscope->dolv = sh.st.dolv;
} }
if (shp->st.self != &savst) if (sh.st.self != &savst)
*shp->st.self = shp->st; *sh.st.self = sh.st;
/* only restore the top Shscope_t portion for POSIX functions */ /* only restore the top Shscope_t portion for POSIX functions */
memcpy((void*)&shp->st, (void*)prevscope, sizeof(Shscope_t)); memcpy((void*)&sh.st, (void*)prevscope, sizeof(Shscope_t));
shp->topscope = (Shscope_t*)prevscope; sh.topscope = (Shscope_t*)prevscope;
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE); nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
if(jmpval && jmpval!=SH_JMPFUN) if(jmpval && jmpval!=SH_JMPFUN)
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
return(shp->exitval); return(sh.exitval);
} }
/* /*
@ -372,7 +373,7 @@ int b_false(int argc,register char *argv[], Shbltin_t *context)
int b_shift(register int n, register char *argv[], Shbltin_t *context) int b_shift(register int n, register char *argv[], Shbltin_t *context)
{ {
register char *arg; register char *arg;
register Shell_t *shp = context->shp; NOT_USED(context);
while((n = optget(argv,sh_optshift))) switch(n) while((n = optget(argv,sh_optshift))) switch(n)
{ {
case ':': case ':':
@ -388,23 +389,23 @@ int b_shift(register int n, register char *argv[], Shbltin_t *context)
UNREACHABLE(); UNREACHABLE();
} }
argv += opt_info.index; argv += opt_info.index;
n = ((arg= *argv)?(int)sh_arith(shp,arg):1); n = ((arg= *argv)?(int)sh_arith(arg):1);
if(n<0 || shp->st.dolc<n) if(n < 0 || sh.st.dolc < n)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_number,arg); errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
UNREACHABLE(); UNREACHABLE();
} }
else else
{ {
shp->st.dolv += n; sh.st.dolv += n;
shp->st.dolc -= n; sh.st.dolc -= n;
} }
return(0); return(0);
} }
int b_wait(int n,register char *argv[],Shbltin_t *context) int b_wait(int n,register char *argv[],Shbltin_t *context)
{ {
register Shell_t *shp = context->shp; NOT_USED(context);
while((n = optget(argv,sh_optwait))) switch(n) while((n = optget(argv,sh_optwait))) switch(n)
{ {
case ':': case ':':
@ -421,7 +422,7 @@ int b_wait(int n,register char *argv[],Shbltin_t *context)
} }
argv += opt_info.index; argv += opt_info.index;
job_bwait(argv); job_bwait(argv);
return(shp->exitval); return(sh.exitval);
} }
#ifdef JOBS #ifdef JOBS
@ -433,8 +434,8 @@ int b_wait(int n,register char *argv[],Shbltin_t *context)
int b_bg(register int n,register char *argv[],Shbltin_t *context) int b_bg(register int n,register char *argv[],Shbltin_t *context)
{ {
register int flag = **argv; register int flag = **argv;
register Shell_t *shp = context->shp;
register const char *optstr = sh_optbg; register const char *optstr = sh_optbg;
NOT_USED(context);
if(*argv[0]=='f') if(*argv[0]=='f')
optstr = sh_optfg; optstr = sh_optfg;
else if(*argv[0]=='d') else if(*argv[0]=='d')
@ -466,13 +467,13 @@ int b_bg(register int n,register char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_exit(1),e_no_job); errormsg(SH_DICT,ERROR_exit(1),e_no_job);
UNREACHABLE(); UNREACHABLE();
} }
return(shp->exitval); return(sh.exitval);
} }
int b_jobs(register int n,char *argv[],Shbltin_t *context) int b_jobs(register int n,char *argv[],Shbltin_t *context)
{ {
register int flag = 0; register int flag = 0;
register Shell_t *shp = context->shp; NOT_USED(context);
while((n = optget(argv,sh_optjobs))) switch(n) while((n = optget(argv,sh_optjobs))) switch(n)
{ {
case 'l': case 'l':
@ -505,7 +506,7 @@ int b_jobs(register int n,char *argv[],Shbltin_t *context)
UNREACHABLE(); UNREACHABLE();
} }
job_wait((pid_t)0); job_wait((pid_t)0);
return(shp->exitval); return(sh.exitval);
} }
#endif #endif
@ -540,7 +541,7 @@ static void print_cpu_times(void)
{ {
struct timeval utime, stime; struct timeval utime, stime;
double dtime; double dtime;
int clk_tck = shgd->lim.clk_tck; int clk_tck = sh.lim.clk_tck;
struct tms cpu_times; struct tms cpu_times;
times(&cpu_times); times(&cpu_times);
/* Print the time (user & system) consumed by the shell. */ /* Print the time (user & system) consumed by the shell. */

View file

@ -380,7 +380,7 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
if (!val) if (!val)
{ {
register int i; register int i;
for(i=0; i< sh.gd->lim.open_max; i++) for(i=0; i< sh.lim.open_max; i++)
{ {
if(service_list[i]==sp) if(service_list[i]==sp)
{ {

View file

@ -62,7 +62,6 @@ struct printf
char *lastarg; char *lastarg;
char cescape; char cescape;
char err; char err;
Shell_t *sh;
}; };
struct printmap struct printmap
@ -84,15 +83,13 @@ static const struct printmap Pmap[] =
}; };
static int echolist(Sfio_t*, int, char**);
static int extend(Sfio_t*,void*, Sffmt_t*); static int extend(Sfio_t*,void*, Sffmt_t*);
static const char preformat[] = "";
static char *genformat(char*); static char *genformat(char*);
static int fmtvecho(const char*, struct printf*); static int fmtvecho(const char*, struct printf*);
static ssize_t fmtbase64(Sfio_t*, char*, int); static ssize_t fmtbase64(Sfio_t*, char*, int);
struct print struct print
{ {
Shell_t *sh;
const char *options; const char *options;
char raw; char raw;
char echon; char echon;
@ -108,15 +105,15 @@ static int exitval;
struct print prdata; struct print prdata;
prdata.options = sh_optecho+5; prdata.options = sh_optecho+5;
prdata.raw = prdata.echon = 0; prdata.raw = prdata.echon = 0;
prdata.sh = context->shp;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
/* This mess is because /bin/echo on BSD is different */ /* This mess is because /bin/echo on BSD is different */
if(!prdata.sh->universe) if(!sh.universe)
{ {
register char *universe; register char *universe;
if(universe=astconf("UNIVERSE",0,0)) if(universe=astconf("UNIVERSE",0,0))
bsd_univ = (strcmp(universe,"ucb")==0); bsd_univ = (strcmp(universe,"ucb")==0);
prdata.sh->universe = 1; sh.universe = 1;
} }
if(!bsd_univ) if(!bsd_univ)
return(b_print(0,argv,(Shbltin_t*)&prdata)); return(b_print(0,argv,(Shbltin_t*)&prdata));
@ -147,8 +144,8 @@ int b_printf(int argc, char *argv[],Shbltin_t *context)
{ {
struct print prdata; struct print prdata;
NOT_USED(argc); NOT_USED(argc);
NOT_USED(context);
memset(&prdata,0,sizeof(prdata)); memset(&prdata,0,sizeof(prdata));
prdata.sh = context->shp;
prdata.options = sh_optprintf; prdata.options = sh_optprintf;
return(b_print(-1,argv,(Shbltin_t*)&prdata)); return(b_print(-1,argv,(Shbltin_t*)&prdata));
} }
@ -171,7 +168,6 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
{ {
register Sfio_t *outfile; register Sfio_t *outfile;
register int n, fd = 1; register int n, fd = 1;
register Shell_t *shp = context->shp;
const char *options, *msg = e_file+4; const char *options, *msg = e_file+4;
char *format = 0; char *format = 0;
int sflag = 0, nflag=0, rflag=0, vflag=0; int sflag = 0, nflag=0, rflag=0, vflag=0;
@ -190,7 +186,6 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
else else
{ {
struct print *pp = (struct print*)context; struct print *pp = (struct print*)context;
shp = pp->sh;
options = pp->options; options = pp->options;
if(argc==0) if(argc==0)
{ {
@ -206,7 +201,7 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
nflag++; nflag++;
break; break;
case 'p': case 'p':
fd = shp->coutpipe; fd = sh.coutpipe;
msg = e_query; msg = e_query;
break; break;
case 'f': case 'f':
@ -214,12 +209,12 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
break; break;
case 's': case 's':
/* print to history file */ /* print to history file */
if(!sh_histinit((void*)shp)) if(!sh_histinit())
{ {
errormsg(SH_DICT,ERROR_system(1),e_history); errormsg(SH_DICT,ERROR_system(1),e_history);
UNREACHABLE(); UNREACHABLE();
} }
fd = sffileno(shp->gd->hist_ptr->histfp); fd = sffileno(sh.hist_ptr->histfp);
sh_onstate(SH_HISTORY); sh_onstate(SH_HISTORY);
sflag++; sflag++;
break; break;
@ -233,16 +228,16 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
fd = (int)strtol(opt_info.arg,&opt_info.arg,10); fd = (int)strtol(opt_info.arg,&opt_info.arg,10);
if(*opt_info.arg) if(*opt_info.arg)
fd = -1; fd = -1;
else if(!sh_iovalidfd(shp,fd)) else if(!sh_iovalidfd(fd))
fd = -1; fd = -1;
else if(!(shp->inuse_bits&(1<<fd)) && (sh_inuse(shp,fd) || (shp->gd->hist_ptr && fd==sffileno(shp->gd->hist_ptr->histfp)))) else if(!(sh.inuse_bits&(1<<fd)) && (sh_inuse(fd) || (sh.hist_ptr && fd==sffileno(sh.hist_ptr->histfp))))
fd = -1; fd = -1;
break; break;
case 'v': case 'v':
if(argc < 0) if(argc < 0)
{ {
/* prepare variable for printf -v varname */ /* prepare variable for printf -v varname */
vname = nv_open(opt_info.arg, shp->var_tree, NV_VARNAME); vname = nv_open(opt_info.arg, sh.var_tree, NV_VARNAME);
if(!vname) if(!vname)
{ {
errormsg(SH_DICT, ERROR_exit(2), e_create, opt_info.arg); errormsg(SH_DICT, ERROR_exit(2), e_create, opt_info.arg);
@ -300,9 +295,9 @@ skip:
argv++; argv++;
if(vname) if(vname)
{ {
if(!shp->strbuf2) if(!sh.strbuf2)
shp->strbuf2 = sfstropen(); sh.strbuf2 = sfstropen();
outfile = shp->strbuf2; outfile = sh.strbuf2;
goto printf_v; goto printf_v;
} }
skip2: skip2:
@ -311,8 +306,8 @@ skip2:
errno = EBADF; errno = EBADF;
n = 0; n = 0;
} }
else if(!(n=shp->fdstatus[fd])) else if(!(n=sh.fdstatus[fd]))
n = sh_iocheckfd(shp,fd); n = sh_iocheckfd(fd);
if(!(n&IOWRITE)) if(!(n&IOWRITE))
{ {
/* don't print error message for stdout for compatibility */ /* don't print error message for stdout for compatibility */
@ -321,13 +316,13 @@ skip2:
errormsg(SH_DICT,ERROR_system(1),msg); errormsg(SH_DICT,ERROR_system(1),msg);
UNREACHABLE(); UNREACHABLE();
} }
if(!(outfile=shp->sftable[fd])) if(!(outfile=sh.sftable[fd]))
{ {
sh_onstate(SH_NOTRACK); sh_onstate(SH_NOTRACK);
n = SF_WRITE|((n&IOREAD)?SF_READ:0); n = SF_WRITE|((n&IOREAD)?SF_READ:0);
shp->sftable[fd] = outfile = sfnew(NIL(Sfio_t*),shp->outbuff,IOBSIZE,fd,n); sh.sftable[fd] = outfile = sfnew(NIL(Sfio_t*),sh.outbuff,IOBSIZE,fd,n);
sh_offstate(SH_NOTRACK); sh_offstate(SH_NOTRACK);
sfpool(outfile,shp->outpool,SF_WRITE); sfpool(outfile,sh.outpool,SF_WRITE);
} }
/* turn off share to guarantee atomic writes for printf */ /* turn off share to guarantee atomic writes for printf */
n = sfset(outfile,SF_SHARE|SF_PUBLIC,0); n = sfset(outfile,SF_SHARE|SF_PUBLIC,0);
@ -338,7 +333,6 @@ printf_v:
Sfio_t *pool; Sfio_t *pool;
struct printf pdata; struct printf pdata;
memset(&pdata, 0, sizeof(pdata)); memset(&pdata, 0, sizeof(pdata));
pdata.sh = shp;
pdata.hdr.version = SFIO_VERSION; pdata.hdr.version = SFIO_VERSION;
pdata.hdr.extf = extend; pdata.hdr.extf = extend;
pdata.nextarg = argv; pdata.nextarg = argv;
@ -346,7 +340,7 @@ printf_v:
pool=sfpool(sfstderr,NIL(Sfio_t*),SF_WRITE); pool=sfpool(sfstderr,NIL(Sfio_t*),SF_WRITE);
do do
{ {
if(shp->trapnote&SH_SIGSET) if(sh.trapnote&SH_SIGSET)
break; break;
pdata.hdr.form = format; pdata.hdr.form = format;
sfprintf(outfile,"%!",&pdata); sfprintf(outfile,"%!",&pdata);
@ -377,7 +371,7 @@ printf_v:
if (sfsync((Sfio_t*)0) < 0) if (sfsync((Sfio_t*)0) < 0)
exitval = 1; exitval = 1;
} }
else if(sh_echolist(shp,outfile,rflag,argv) && !nflag) else if(echolist(outfile,rflag,argv) && !nflag)
if(sfputc(outfile,'\n') < 0) if(sfputc(outfile,'\n') < 0)
exitval = 1; exitval = 1;
} }
@ -385,7 +379,7 @@ printf_v:
nv_putval(vname, sfstruse(outfile), 0); nv_putval(vname, sfstruse(outfile), 0);
else if(sflag) else if(sflag)
{ {
hist_flush(shp->gd->hist_ptr); hist_flush(sh.hist_ptr);
sh_offstate(SH_HISTORY); sh_offstate(SH_HISTORY);
} }
else else
@ -404,7 +398,7 @@ printf_v:
* returns 0 for \c otherwise 1. * returns 0 for \c otherwise 1.
*/ */
int sh_echolist(Shell_t *shp,Sfio_t *outfile, int raw, char *argv[]) static int echolist(Sfio_t *outfile, int raw, char *argv[])
{ {
register char *cp; register char *cp;
register int n; register int n;
@ -425,7 +419,7 @@ int sh_echolist(Shell_t *shp,Sfio_t *outfile, int raw, char *argv[])
if(*argv) if(*argv)
if(sfputc(outfile,' ') < 0) if(sfputc(outfile,' ') < 0)
exitval = 1; exitval = 1;
sh_sigcheck(shp); sh_sigcheck();
} }
return(!pdata.cescape); return(!pdata.cescape);
} }
@ -491,10 +485,9 @@ static char *genformat(char *format)
{ {
register char *fp; register char *fp;
stakseek(0); stakseek(0);
stakputs(preformat);
stakputs(format); stakputs(format);
fp = (char*)stakfreeze(1); fp = (char*)stakfreeze(1);
strformat(fp+sizeof(preformat)-1); strformat(fp);
return(fp); return(fp);
} }
@ -718,7 +711,6 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
int fold = fe->base; int fold = fe->base;
union types_t* value = (union types_t*)v; union types_t* value = (union types_t*)v;
struct printf* pp = (struct printf*)fe; struct printf* pp = (struct printf*)fe;
Shell_t *shp = pp->sh;
register char* argp = *pp->nextarg; register char* argp = *pp->nextarg;
char *w,*s; char *w,*s;
if(fe->n_str>0 && (format=='T'||format=='Q') && varname(fe->t_str,fe->n_str) && (!argp || varname(argp,-1))) if(fe->n_str>0 && (format=='T'||format=='Q') && varname(fe->t_str,fe->n_str) && (!argp || varname(argp,-1)))
@ -729,8 +721,8 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
argp = pp->lastarg; argp = pp->lastarg;
if(argp) if(argp)
{ {
sfprintf(pp->sh->strbuf,"%s.%.*s%c",argp,fe->n_str,fe->t_str,0); sfprintf(sh.strbuf,"%s.%.*s%c",argp,fe->n_str,fe->t_str,0);
argp = sfstruse(pp->sh->strbuf); argp = sfstruse(sh.strbuf);
} }
} }
else else
@ -804,7 +796,7 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
case 'n': case 'n':
{ {
Namval_t *np; Namval_t *np;
np = nv_open(argp,shp->var_tree,NV_VARNAME|NV_NOASSIGN|NV_NOARRAY); np = nv_open(argp,sh.var_tree,NV_VARNAME|NV_NOASSIGN|NV_NOARRAY);
_nv_unset(np,0); _nv_unset(np,0);
nv_onattr(np,NV_INTEGER); nv_onattr(np,NV_INTEGER);
if (np->nvalue.lp = new_of(int32_t,0)) if (np->nvalue.lp = new_of(int32_t,0))
@ -998,10 +990,10 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
} }
break; break;
case 'B': case 'B':
if(!shp->strbuf2) if(!sh.strbuf2)
shp->strbuf2 = sfstropen(); sh.strbuf2 = sfstropen();
fe->size = fmtbase64(shp->strbuf2,value->s, fe->flags&SFFMT_ALTER); fe->size = fmtbase64(sh.strbuf2,value->s, fe->flags&SFFMT_ALTER);
value->s = sfstruse(shp->strbuf2); value->s = sfstruse(sh.strbuf2);
fe->flags |= SFFMT_SHORT; fe->flags |= SFFMT_SHORT;
break; break;
case 'H': case 'H':

View file

@ -64,9 +64,8 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
Sfdouble_t sec; Sfdouble_t sec;
register char *name; register char *name;
register int r, flags=0, fd=0; register int r, flags=0, fd=0;
register Shell_t *shp = context->shp;
ssize_t len=0; ssize_t len=0;
long timeout = 1000*shp->st.tmout; long timeout = 1000*sh.st.tmout;
int save_prompt, fixargs=context->invariant; int save_prompt, fixargs=context->invariant;
struct read_save *rp; struct read_save *rp;
static char default_prompt[3] = {ESC,ESC}; static char default_prompt[3] = {ESC,ESC};
@ -108,7 +107,7 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
} }
break; break;
case 'p': case 'p':
if((fd = shp->cpipe[0])<=0) if((fd = sh.cpipe[0])<=0)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_query); errormsg(SH_DICT,ERROR_exit(1),e_query);
UNREACHABLE(); UNREACHABLE();
@ -131,12 +130,12 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
break; break;
case 'u': case 'u':
fd = (int)opt_info.num; fd = (int)opt_info.num;
if(opt_info.num<0 || opt_info.num>INT_MAX || (fd>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fd))) if(opt_info.num<0 || opt_info.num>INT_MAX || (fd>=sh.lim.open_max && !sh_iovalidfd(fd)))
{ {
errormsg(SH_DICT,ERROR_exit(1),e_file,opt_info.arg); /* reject invalid file descriptors */ errormsg(SH_DICT,ERROR_exit(1),e_file,opt_info.arg); /* reject invalid file descriptors */
UNREACHABLE(); UNREACHABLE();
} }
if(sh_inuse(shp,fd)) if(sh_inuse(fd))
fd = -1; fd = -1;
break; break;
case 'v': case 'v':
@ -155,8 +154,8 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
if(!((r=shp->fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK))) if(!((r=sh.fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
r = sh_iocheckfd(shp,fd); r = sh_iocheckfd(fd);
if(fd<0 || !(r&IOREAD)) if(fd<0 || !(r&IOREAD))
{ {
errormsg(SH_DICT,ERROR_system(1),e_file+4); errormsg(SH_DICT,ERROR_system(1),e_file+4);
@ -180,21 +179,21 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
rp->len = len; rp->len = len;
} }
bypass: bypass:
shp->prompt = default_prompt; sh.prompt = default_prompt;
if(r && (shp->prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR))) if(r && (sh.prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR)))
{ {
memcpy(shp->prompt,name,r); memcpy(sh.prompt,name,r);
sfwrite(sfstderr,shp->prompt,r-1); sfwrite(sfstderr,sh.prompt,r-1);
} }
shp->timeout = 0; sh.timeout = 0;
save_prompt = shp->nextprompt; save_prompt = sh.nextprompt;
shp->nextprompt = 0; sh.nextprompt = 0;
r=sh_readline(shp,argv,fd,flags,len,timeout); r=sh_readline(argv,fd,flags,len,timeout);
shp->nextprompt = save_prompt; sh.nextprompt = save_prompt;
if(r==0 && (r=(sfeof(shp->sftable[fd])||sferror(shp->sftable[fd])))) if(r==0 && (r=(sfeof(sh.sftable[fd])||sferror(sh.sftable[fd]))))
{ {
if(fd == shp->cpipe[0] && errno!=EINTR) if(fd == sh.cpipe[0] && errno!=EINTR)
sh_pclose(shp->cpipe); sh_pclose(sh.cpipe);
} }
return(r); return(r);
} }
@ -216,7 +215,7 @@ static void timedout(void *handle)
* <timeout> is the number of milliseconds until timeout * <timeout> is the number of milliseconds until timeout
*/ */
int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,ssize_t size,long timeout) int sh_readline(char **names, volatile int fd, int flags, ssize_t size, long timeout)
{ {
register ssize_t c; register ssize_t c;
register unsigned char *cp; register unsigned char *cp;
@ -241,8 +240,8 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
int oflags=NV_ASSIGN|NV_VARNAME; int oflags=NV_ASSIGN|NV_VARNAME;
char inquote = 0; char inquote = 0;
struct checkpt buff; struct checkpt buff;
Edit_t *ep = (struct edit*)shp->gd->ed_context; Edit_t *ep = (struct edit*)sh.ed_context;
if(!(iop=shp->sftable[fd]) && !(iop=sh_iostream(shp,fd))) if(!(iop=sh.sftable[fd]) && !(iop=sh_iostream(fd)))
return(1); return(1);
sh_stats(STAT_READS); sh_stats(STAT_READS);
if(names && (name = *names)) if(names && (name = *names))
@ -252,11 +251,11 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
*val = 0; *val = 0;
if(flags&C_FLAG) if(flags&C_FLAG)
oflags |= NV_ARRAY; oflags |= NV_ARRAY;
np = nv_open(name,shp->var_tree,oflags); np = nv_open(name,sh.var_tree,oflags);
if(np && nv_isarray(np) && (mp=nv_opensub(np))) if(np && nv_isarray(np) && (mp=nv_opensub(np)))
np = mp; np = mp;
if((flags&V_FLAG) && shp->gd->ed_context) if((flags&V_FLAG) && sh.ed_context)
((struct edit*)shp->gd->ed_context)->e_default = np; ((struct edit*)sh.ed_context)->e_default = np;
if(flags&A_FLAG) if(flags&A_FLAG)
{ {
Namarr_t *ap; Namarr_t *ap;
@ -286,15 +285,15 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
else else
{ {
name = 0; name = 0;
if(dtvnext(shp->var_tree) || shp->namespace) if(dtvnext(sh.var_tree) || sh.namespace)
np = nv_open(nv_name(REPLYNOD),shp->var_tree,0); np = nv_open(nv_name(REPLYNOD),sh.var_tree,0);
else else
np = REPLYNOD; np = REPLYNOD;
} }
keytrap = ep?ep->e_keytrap:0; keytrap = ep?ep->e_keytrap:0;
if(size || (flags>>D_FLAG)) /* delimiter not new-line or fixed size read */ if(size || (flags>>D_FLAG)) /* delimiter not new-line or fixed size read */
{ {
if((shp->fdstatus[fd]&IOTTY) && !keytrap) if((sh.fdstatus[fd]&IOTTY) && !keytrap)
tty_raw(fd,1); tty_raw(fd,1);
if(!(flags&(N_FLAG|NN_FLAG))) if(!(flags&(N_FLAG|NN_FLAG)))
{ {
@ -309,23 +308,23 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
{ {
Namval_t *mp; Namval_t *mp;
/* set up state table based on IFS */ /* set up state table based on IFS */
ifs = nv_getval(mp=sh_scoped(shp,IFSNOD)); ifs = nv_getval(mp=sh_scoped(IFSNOD));
if((flags&R_FLAG) && shp->ifstable['\\']==S_ESC) if((flags&R_FLAG) && sh.ifstable['\\']==S_ESC)
shp->ifstable['\\'] = 0; sh.ifstable['\\'] = 0;
else if(!(flags&R_FLAG) && shp->ifstable['\\']==0) else if(!(flags&R_FLAG) && sh.ifstable['\\']==0)
shp->ifstable['\\'] = S_ESC; sh.ifstable['\\'] = S_ESC;
if(delim>0) if(delim>0)
shp->ifstable[delim] = S_NL; sh.ifstable[delim] = S_NL;
if(delim!='\n') if(delim!='\n')
{ {
shp->ifstable['\n'] = 0; sh.ifstable['\n'] = 0;
nv_putval(mp, ifs, NV_RDONLY); nv_putval(mp, ifs, NV_RDONLY);
} }
shp->ifstable[0] = S_EOF; sh.ifstable[0] = S_EOF;
if((flags&SS_FLAG)) if((flags&SS_FLAG))
{ {
shp->ifstable['"'] = S_QUOTE; sh.ifstable['"'] = S_QUOTE;
shp->ifstable['\r'] = S_ERR; sh.ifstable['\r'] = S_ERR;
} }
} }
sfclrerr(iop); sfclrerr(iop);
@ -333,7 +332,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
{ {
if(nfp->disc && nfp->disc->readf) if(nfp->disc && nfp->disc->readf)
{ {
Namval_t *mp = nv_open(name,shp->var_tree,oflags|NV_NOREF); Namval_t *mp = nv_open(name,sh.var_tree,oflags|NV_NOREF);
if((c=(*nfp->disc->readf)(mp,iop,delim,nfp))>=0) if((c=(*nfp->disc->readf)(mp,iop,delim,nfp))>=0)
return(c); return(c);
} }
@ -345,10 +344,10 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
} }
was_write = (sfset(iop,SF_WRITE,0)&SF_WRITE)!=0; was_write = (sfset(iop,SF_WRITE,0)&SF_WRITE)!=0;
if(fd==0) if(fd==0)
was_share = (sfset(iop,SF_SHARE,shp->redir0!=2)&SF_SHARE)!=0; was_share = (sfset(iop,SF_SHARE,sh.redir0!=2)&SF_SHARE)!=0;
if(timeout || (shp->fdstatus[fd]&(IOTTY|IONOSEEK))) if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
{ {
sh_pushcontext(shp,&buff,1); sh_pushcontext(&sh,&buff,1);
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
if(jmpval) if(jmpval)
goto done; goto done;
@ -504,10 +503,10 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
} }
if(timeslot) if(timeslot)
timerdel(timeslot); timerdel(timeslot);
if((flags&S_FLAG) && !shp->gd->hist_ptr) if((flags&S_FLAG) && !sh.hist_ptr)
{ {
sh_histinit((void*)shp); sh_histinit();
if(!shp->gd->hist_ptr) if(!sh.hist_ptr)
flags &= ~S_FLAG; flags &= ~S_FLAG;
} }
if(cp) if(cp)
@ -520,20 +519,20 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
if(*(cpmax-1) != delim) if(*(cpmax-1) != delim)
*(cpmax-1) = delim; *(cpmax-1) = delim;
if(flags&S_FLAG) if(flags&S_FLAG)
sfwrite(shp->gd->hist_ptr->histfp,(char*)cp,c); sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
#if !SHOPT_MULTIBYTE #if !SHOPT_MULTIBYTE
if(!name && (flags&R_FLAG)) /* special case single argument */ if(!name && (flags&R_FLAG)) /* special case single argument */
{ {
/* skip over leading blanks */ /* skip over leading blanks */
while(c==S_SPACE) while(c==S_SPACE)
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
/* strip trailing delimiters */ /* strip trailing delimiters */
if(cpmax[-1] == '\n') if(cpmax[-1] == '\n')
cpmax--; cpmax--;
if(cpmax>cp) if(cpmax>cp)
{ {
while((c=shp->ifstable[*--cpmax])==S_DELIM || c==S_SPACE); while((c=sh.ifstable[*--cpmax])==S_DELIM || c==S_SPACE);
cpmax[1] = 0; cpmax[1] = 0;
} }
else else
@ -551,7 +550,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
} }
else else
c = S_NL; c = S_NL;
shp->nextprompt = 2; sh.nextprompt = 2;
rel= staktell(); rel= staktell();
mbinit(); mbinit();
/* val==0 at the start of a field */ /* val==0 at the start of a field */
@ -580,7 +579,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
continue; continue;
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
case S_QUOTE: case S_QUOTE:
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
if(inquote && c==S_QUOTE) if(inquote && c==S_QUOTE)
c = -1; c = -1;
else else
@ -594,12 +593,12 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
if(c==-1) if(c==-1)
{ {
stakputc('"'); stakputc('"');
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
} }
continue; continue;
case S_ESC: case S_ESC:
/* process escape character */ /* process escape character */
if((c = shp->ifstable[*cp++]) == S_NL) if((c = sh.ifstable[*cp++]) == S_NL)
was_escape = 1; was_escape = 1;
else else
c = 0; c = 0;
@ -629,7 +628,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
break; break;
} }
/* eliminate null bytes */ /* eliminate null bytes */
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE)) if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE))
c = 0; c = 0;
continue; continue;
@ -644,9 +643,9 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
if(cp) if(cp)
{ {
if(flags&S_FLAG) if(flags&S_FLAG)
sfwrite(shp->gd->hist_ptr->histfp,(char*)cp,c); sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
cpmax = cp + c; cpmax = cp + c;
c = shp->ifstable[*cp++]; c = sh.ifstable[*cp++];
val=0; val=0;
if(!name && (c==S_SPACE || c==S_DELIM || c==S_MBYTE)) if(!name && (c==S_SPACE || c==S_DELIM || c==S_MBYTE))
c = 0; c = 0;
@ -658,7 +657,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
case S_SPACE: case S_SPACE:
/* skip over blanks */ /* skip over blanks */
while((c=shp->ifstable[*cp++])==S_SPACE); while((c=sh.ifstable[*cp++])==S_SPACE);
if(!val) if(!val)
continue; continue;
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
@ -684,7 +683,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
if(name) if(name)
{ {
/* skip over trailing blanks */ /* skip over trailing blanks */
while((c=shp->ifstable[*cp++])==S_SPACE); while((c=sh.ifstable[*cp++])==S_SPACE);
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
@ -702,7 +701,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
cp += mbsz - 1; cp += mbsz - 1;
while(1) while(1)
{ {
while((c = shp->ifstable[*cp]) == 0) while((c = sh.ifstable[*cp]) == 0)
{ {
cp += (mbsz = mbsize(cp)) > 1 ? mbsz : 1; /* treat invalid char as 1 byte */ cp += (mbsz = mbsize(cp)) > 1 ? mbsz : 1; /* treat invalid char as 1 byte */
if(!wrd) if(!wrd)
@ -713,7 +712,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
{ {
if(c==S_QUOTE) if(c==S_QUOTE)
{ {
if(shp->ifstable[*cp]==S_QUOTE) if(sh.ifstable[*cp]==S_QUOTE)
{ {
if(val) if(val)
{ {
@ -769,13 +768,13 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
{ {
/* strip off trailing space delimiters */ /* strip off trailing space delimiters */
register unsigned char *vp = (unsigned char*)val + strlen(val); register unsigned char *vp = (unsigned char*)val + strlen(val);
while(shp->ifstable[*--vp]==S_SPACE); while(sh.ifstable[*--vp]==S_SPACE);
if(vp==del) if(vp==del)
{ {
if(vp==(unsigned char*)val) if(vp==(unsigned char*)val)
vp--; vp--;
else else
while(shp->ifstable[*--vp]==S_SPACE); while(sh.ifstable[*--vp]==S_SPACE);
} }
vp[1] = 0; vp[1] = 0;
} }
@ -805,12 +804,12 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
if(sh_isoption(SH_ALLEXPORT)&&!strchr(nv_name(np),'.') && !nv_isattr(np,NV_EXPORT)) if(sh_isoption(SH_ALLEXPORT)&&!strchr(nv_name(np),'.') && !nv_isattr(np,NV_EXPORT))
{ {
nv_onattr(np,NV_EXPORT); nv_onattr(np,NV_EXPORT);
sh_envput(shp->env,np); sh_envput(sh.env,np);
} }
if(name) if(name)
{ {
nv_close(np); nv_close(np);
np = nv_open(name,shp->var_tree,NV_NOASSIGN|NV_VARNAME); np = nv_open(name,sh.var_tree,NV_NOASSIGN|NV_VARNAME);
name = *++names; name = *++names;
} }
else else
@ -829,18 +828,18 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
} }
} }
done: done:
if(timeout || (shp->fdstatus[fd]&(IOTTY|IONOSEEK))) if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
if(was_write) if(was_write)
sfset(iop,SF_WRITE,1); sfset(iop,SF_WRITE,1);
if(!was_share) if(!was_share)
sfset(iop,SF_SHARE,0); sfset(iop,SF_SHARE,0);
nv_close(np); nv_close(np);
if((shp->fdstatus[fd]&IOTTY) && !keytrap) if((sh.fdstatus[fd]&IOTTY) && !keytrap)
tty_cooked(fd); tty_cooked(fd);
if(flags&S_FLAG) if(flags&S_FLAG)
hist_flush(shp->gd->hist_ptr); hist_flush(sh.hist_ptr);
if(jmpval > 1) if(jmpval > 1)
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
return(jmpval); return(jmpval);
} }

View file

@ -122,11 +122,11 @@ static const char* regress_options[] =
"etc", "etc",
}; };
void sh_regress_init(Shell_t* shp) void sh_regress_init(void)
{ {
static Regress_t state; static Regress_t state;
shp->regress = &state; sh.regress = &state;
} }
/* /*
@ -261,7 +261,6 @@ char* sh_regress_etc(const char* path, unsigned int line, const char* file)
int b___regress__(int argc, char** argv, Shbltin_t *context) int b___regress__(int argc, char** argv, Shbltin_t *context)
{ {
register Shell_t* shp = context->shp;
int n; int n;
for (;;) for (;;)

View file

@ -38,11 +38,11 @@ int b_sleep(register int argc,char *argv[],Shbltin_t *context)
{ {
register char *cp; register char *cp;
register double d=0; register double d=0;
register Shell_t *shp = context->shp;
int sflag=0; int sflag=0;
time_t tloc = 0; time_t tloc = 0;
char *last; char *last;
if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF))) NOT_USED(context);
if(!(sh.sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
sh_sigtrap(SIGALRM); sh_sigtrap(SIGALRM);
while((argc = optget(argv,sh_optsleep))) switch(argc) while((argc = optget(argv,sh_optsleep))) switch(argc)
{ {
@ -73,7 +73,7 @@ int b_sleep(register int argc,char *argv[],Shbltin_t *context)
ns = 0; ns = 0;
if(*cp == 'P' || *cp == 'p') if(*cp == 'P' || *cp == 'p')
ns = tmxdate(cp, &last, now); ns = tmxdate(cp, &last, now);
else if(*last=='.' && shp->decomma && d==(unsigned long)d) else if(*last=='.' && sh.decomma && d==(unsigned long)d)
{ {
*(pp=last) = ','; *(pp=last) = ',';
if(!strchr(cp,'.')) if(!strchr(cp,'.'))
@ -120,16 +120,16 @@ skip:
{ {
time_t now; time_t now;
errno = 0; errno = 0;
shp->lastsig=0; sh.lastsig=0;
sh_delay(d,sflag); sh_delay(d,sflag);
if(sflag || tloc==0 || errno!=EINTR || shp->lastsig) if(sflag || tloc==0 || errno!=EINTR || sh.lastsig)
break; break;
sh_sigcheck(shp); sh_sigcheck();
if(tloc < (now=time(NIL(time_t*)))) if(tloc < (now=time(NIL(time_t*))))
break; break;
d = (double)(tloc-now); d = (double)(tloc-now);
if(shp->sigflag[SIGALRM]&SH_SIGTRAP) if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps(shp); sh_timetraps();
} }
return(0); return(0);
} }
@ -141,7 +141,6 @@ skip:
*/ */
void sh_delay(double t, int sflag) void sh_delay(double t, int sflag)
{ {
Shell_t *shp = sh_getinterp();
int n = (int)t; int n = (int)t;
Tv_t ts, tx; Tv_t ts, tx;
@ -149,7 +148,7 @@ void sh_delay(double t, int sflag)
ts.tv_nsec = 1000000000 * (t - (double)n); ts.tv_nsec = 1000000000 * (t - (double)n);
while(tvsleep(&ts, &tx) < 0) while(tvsleep(&ts, &tx) < 0)
{ {
if ((shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) || sflag) if ((sh.trapnote & (SH_SIGSET | SH_SIGTRAP)) || sflag)
return; return;
ts = tx; ts = tx;
} }

View file

@ -72,7 +72,6 @@ static int test_mode(const char*);
struct test struct test
{ {
Shell_t *sh;
int ap; int ap;
int ac; int ac;
char **av; char **av;
@ -82,7 +81,7 @@ static char *nxtarg(struct test*,int);
static int expr(struct test*,int); static int expr(struct test*,int);
static int e3(struct test*); static int e3(struct test*);
static int test_strmatch(Shell_t *shp,const char *str, const char *pat) static int test_strmatch(const char *str, const char *pat)
{ {
regoff_t match[2*(MATCH_MAX+1)],n; regoff_t match[2*(MATCH_MAX+1)],n;
register int c, m=0; register int c, m=0;
@ -104,7 +103,7 @@ static int test_strmatch(Shell_t *shp,const char *str, const char *pat)
if(m==0 && n==1) if(m==0 && n==1)
match[1] = strlen(str); match[1] = strlen(str);
if(n) if(n)
sh_setmatch(shp, str, -1, n, match, 0); sh_setmatch(str, -1, n, match, 0);
return(n); return(n);
} }
@ -115,7 +114,6 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
register int not; register int not;
int exitval; int exitval;
tdata.sh = context->shp;
tdata.av = argv; tdata.av = argv;
tdata.ap = 1; tdata.ap = 1;
if(c_eq(cp,'[')) if(c_eq(cp,'['))
@ -164,12 +162,12 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
break; break;
if(not && cp[0]=='-' && cp[2]==0) if(not && cp[0]=='-' && cp[2]==0)
{ {
exitval = (test_unop(tdata.sh,cp[1],argv[3])!=0); exitval = (test_unop(cp[1],argv[3])!=0);
goto done; goto done;
} }
else if(argv[1][0]=='-' && argv[1][2]==0) else if(argv[1][0]=='-' && argv[1][2]==0)
{ {
exitval = (!test_unop(tdata.sh,argv[1][1],cp)); exitval = (!test_unop(argv[1][1],cp));
goto done; goto done;
} }
else if(not && c_eq(argv[2],'!')) else if(not && c_eq(argv[2],'!'))
@ -180,7 +178,7 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_exit(2),e_badop,cp); errormsg(SH_DICT,ERROR_exit(2),e_badop,cp);
UNREACHABLE(); UNREACHABLE();
} }
exitval = (test_binop(tdata.sh,op,argv[1],argv[3])^(argc!=5)); exitval = (test_binop(op,argv[1],argv[3])^(argc!=5));
goto done; goto done;
} }
case 3: case 3:
@ -209,7 +207,7 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
} }
break; break;
} }
exitval = (!test_unop(tdata.sh,cp[1],argv[2])); exitval = (!test_unop(cp[1],argv[2]));
goto done; goto done;
case 2: case 2:
exitval = (*cp==0); exitval = (*cp==0);
@ -346,7 +344,7 @@ static int e3(struct test *tp)
UNREACHABLE(); UNREACHABLE();
} }
if(strchr(test_opchars,op)) if(strchr(test_opchars,op))
return(test_unop(tp->sh,op,cp)); return(test_unop(op,cp));
} }
if(!cp) if(!cp)
{ {
@ -364,10 +362,10 @@ skip:
} }
if(op==TEST_AND || op==TEST_OR) if(op==TEST_AND || op==TEST_OR)
tp->ap--; tp->ap--;
return(test_binop(tp->sh,op,arg,cp)); return(test_binop(op,arg,cp));
} }
int test_unop(Shell_t *shp,register int op,register const char *arg) int test_unop(register int op,register const char *arg)
{ {
struct stat statb; struct stat statb;
int f; int f;
@ -449,8 +447,8 @@ int test_unop(Shell_t *shp,register int op,register const char *arg)
if(op=='s') if(op=='s')
return(statb.st_size>0); return(statb.st_size>0);
else if(op=='O') else if(op=='O')
return(statb.st_uid==shp->gd->userid); return(statb.st_uid==sh.userid);
return(statb.st_gid==shp->gd->groupid); return(statb.st_gid==sh.groupid);
case 'a': case 'a':
case 'e': case 'e':
if(memcmp(arg,"/dev/",5)==0 && sh_open(arg,O_NONBLOCK)) if(memcmp(arg,"/dev/",5)==0 && sh_open(arg,O_NONBLOCK))
@ -474,7 +472,7 @@ int test_unop(Shell_t *shp,register int op,register const char *arg)
Namval_t *np; Namval_t *np;
Namarr_t *ap; Namarr_t *ap;
int isref; int isref;
if(!(np = nv_open(arg,shp->var_tree,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOREF))) if(!(np = nv_open(arg,sh.var_tree,NV_VARNAME|NV_NOFAIL|NV_NOADD|NV_NOREF)))
return(0); return(0);
isref = nv_isref(np); isref = nv_isref(np);
if(op=='R') if(op=='R')
@ -505,7 +503,7 @@ int test_unop(Shell_t *shp,register int op,register const char *arg)
* This function handles binary operators for both the * This function handles binary operators for both the
* test/[ built-in and the [[ ... ]] compound command * test/[ built-in and the [[ ... ]] compound command
*/ */
int test_binop(Shell_t *shp,register int op,const char *left,const char *right) int test_binop(register int op,const char *left,const char *right)
{ {
register double lnum = 0, rnum = 0; register double lnum = 0, rnum = 0;
if(op&TEST_ARITH) if(op&TEST_ARITH)
@ -514,8 +512,8 @@ int test_binop(Shell_t *shp,register int op,const char *left,const char *right)
left++; left++;
while(*right=='0') while(*right=='0')
right++; right++;
lnum = sh_arith(shp,left); lnum = sh_arith(left);
rnum = sh_arith(shp,right); rnum = sh_arith(right);
} }
switch(op) switch(op)
{ {
@ -523,9 +521,9 @@ int test_binop(Shell_t *shp,register int op,const char *left,const char *right)
case TEST_OR: case TEST_OR:
return(*left!=0); return(*left!=0);
case TEST_PEQ: case TEST_PEQ:
return(test_strmatch(shp, left, right)); return(test_strmatch(left, right));
case TEST_PNE: case TEST_PNE:
return(!test_strmatch(shp, left, right)); return(!test_strmatch(left, right));
case TEST_SGT: case TEST_SGT:
return(strcoll(left, right)>0); return(strcoll(left, right)>0);
case TEST_SLT: case TEST_SLT:
@ -535,8 +533,8 @@ int test_binop(Shell_t *shp,register int op,const char *left,const char *right)
case TEST_SNE: case TEST_SNE:
return(strcmp(left, right)!=0); return(strcmp(left, right)!=0);
case TEST_REP: case TEST_REP:
sfprintf(stkstd, "~(E)%s", right); sfprintf(sh.strbuf, "~(E)%s", right);
return(test_strmatch(shp, left, stkfreeze(stkstd, 1))>0); return(test_strmatch(left, sfstruse(sh.strbuf))>0);
case TEST_EF: case TEST_EF:
return(test_inode(left,right)); return(test_inode(left,right));
case TEST_NT: case TEST_NT:
@ -603,35 +601,34 @@ int test_inode(const char *file1,const char *file2)
int sh_access(register const char *name, register int mode) int sh_access(register const char *name, register int mode)
{ {
Shell_t *shp = sh_getinterp();
struct stat statb; struct stat statb;
if(*name==0) if(*name==0)
return(-1); return(-1);
if(sh_isdevfd(name)) if(sh_isdevfd(name))
return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode)); return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode));
/* can't use access function for execute permission with root */ /* can't use access function for execute permission with root */
if(mode==X_OK && shp->gd->euserid==0) if(mode==X_OK && sh.euserid==0)
goto skip; goto skip;
if(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid) if(sh.userid==sh.euserid && sh.groupid==sh.egroupid)
return(access(name,mode)); return(access(name,mode));
#ifdef _lib_setreuid #ifdef _lib_setreuid
/* swap the real uid to effective, check access then restore */ /* swap the real uid to effective, check access then restore */
/* first swap real and effective gid, if different */ /* first swap real and effective gid, if different */
if(shp->gd->groupid==shp->gd->euserid || setregid(shp->gd->egroupid,shp->gd->groupid)==0) if(sh.groupid==sh.euserid || setregid(sh.egroupid,sh.groupid)==0)
{ {
/* next swap real and effective uid, if needed */ /* next swap real and effective uid, if needed */
if(shp->gd->userid==shp->gd->euserid || setreuid(shp->gd->euserid,shp->gd->userid)==0) if(sh.userid==sh.euserid || setreuid(sh.euserid,sh.userid)==0)
{ {
mode = access(name,mode); mode = access(name,mode);
/* restore ids */ /* restore ids */
if(shp->gd->userid!=shp->gd->euserid) if(sh.userid!=sh.euserid)
setreuid(shp->gd->userid,shp->gd->euserid); setreuid(sh.userid,sh.euserid);
if(shp->gd->groupid!=shp->gd->egroupid) if(sh.groupid!=sh.egroupid)
setregid(shp->gd->groupid,shp->gd->egroupid); setregid(sh.groupid,sh.egroupid);
return(mode); return(mode);
} }
else if(shp->gd->groupid!=shp->gd->egroupid) else if(sh.groupid!=sh.egroupid)
setregid(shp->gd->groupid,shp->gd->egroupid); setregid(sh.groupid,sh.egroupid);
} }
#endif /* _lib_setreuid */ #endif /* _lib_setreuid */
skip: skip:
@ -639,16 +636,16 @@ skip:
{ {
if(mode == F_OK) if(mode == F_OK)
return(mode); return(mode);
else if(shp->gd->euserid == 0) else if(sh.euserid == 0)
{ {
if(!S_ISREG(statb.st_mode) || mode!=X_OK) if(!S_ISREG(statb.st_mode) || mode!=X_OK)
return(0); return(0);
/* root needs execute permission for someone */ /* root needs execute permission for someone */
mode = (S_IXUSR|S_IXGRP|S_IXOTH); mode = (S_IXUSR|S_IXGRP|S_IXOTH);
} }
else if(shp->gd->euserid == statb.st_uid) else if(sh.euserid == statb.st_uid)
mode <<= 6; mode <<= 6;
else if(shp->gd->egroupid == statb.st_gid) else if(sh.egroupid == statb.st_gid)
mode <<= 3; mode <<= 3;
#ifdef _lib_getgroups #ifdef _lib_getgroups
/* on some systems you can be in several groups */ /* on some systems you can be in several groups */

View file

@ -40,14 +40,13 @@
static const char trapfmt[] = "trap -- %s %s\n"; static const char trapfmt[] = "trap -- %s %s\n";
static int sig_number(Shell_t*,const char*); static int sig_number(const char*);
static void sig_list(Shell_t*,int); static void sig_list(int);
int b_trap(int argc,char *argv[],Shbltin_t *context) int b_trap(int argc,char *argv[],Shbltin_t *context)
{ {
register char *arg = argv[1]; register char *arg = argv[1];
register int sig, clear = 0, dflag = 0, pflag = 0; register int sig, clear = 0, dflag = 0, pflag = 0;
register Shell_t *shp = context->shp;
NOT_USED(argc); NOT_USED(argc);
while (sig = optget(argv, sh_opttrap)) switch (sig) while (sig = optget(argv, sh_opttrap)) switch (sig)
{ {
@ -86,7 +85,7 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
* if function semantics can be worked out then it * if function semantics can be worked out then it
* may merit a -d/--default option * may merit a -d/--default option
*/ */
else if(*action=='+' && action[1]==0 && shp->st.self == &shp->global) else if(*action=='+' && action[1]==0 && sh.st.self == &sh.global)
{ {
clear++; clear++;
dflag++; dflag++;
@ -100,7 +99,7 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
} }
while(arg = *argv++) while(arg = *argv++)
{ {
sig = sig_number(shp,arg); sig = sig_number(arg);
if(sig<0) if(sig<0)
{ {
errormsg(SH_DICT,2,e_trap,arg); errormsg(SH_DICT,2,e_trap,arg);
@ -109,7 +108,7 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
/* internal traps */ /* internal traps */
if(sig&SH_TRAP) if(sig&SH_TRAP)
{ {
char **trap = (shp->st.otrap?shp->st.otrap:shp->st.trap); char **trap = (sh.st.otrap ? sh.st.otrap : sh.st.trap);
sig &= ~SH_TRAP; sig &= ~SH_TRAP;
if(sig>SH_DEBUGTRAP) if(sig>SH_DEBUGTRAP)
{ {
@ -122,37 +121,37 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
sfputr(sfstdout,sh_fmtq(arg),'\n'); sfputr(sfstdout,sh_fmtq(arg),'\n');
continue; continue;
} }
shp->st.otrap = 0; sh.st.otrap = 0;
if(shp->st.trap[sig]) if(sh.st.trap[sig])
free(shp->st.trap[sig]); free(sh.st.trap[sig]);
shp->st.trap[sig] = 0; sh.st.trap[sig] = 0;
if(!clear && *action) if(!clear && *action)
shp->st.trap[sig] = sh_strdup(action); sh.st.trap[sig] = sh_strdup(action);
if(sig == SH_DEBUGTRAP) if(sig == SH_DEBUGTRAP)
{ {
if(shp->st.trap[sig]) if(sh.st.trap[sig])
shp->trapnote |= SH_SIGTRAP; sh.trapnote |= SH_SIGTRAP;
else else
shp->trapnote = 0; sh.trapnote = 0;
} }
if(sig == SH_ERRTRAP) if(sig == SH_ERRTRAP)
{ {
if(clear) if(clear)
shp->errtrap = 0; sh.errtrap = 0;
else if(!shp->fn_depth || shp->end_fn) else if(!sh.fn_depth || sh.end_fn)
shp->errtrap = 1; sh.errtrap = 1;
} }
continue; continue;
} }
if(sig>shp->gd->sigmax) if(sig > sh.sigmax)
{ {
errormsg(SH_DICT,2,e_trap,arg); errormsg(SH_DICT,2,e_trap,arg);
return(1); return(1);
} }
else if(pflag) else if(pflag)
{ {
char **trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom); char **trapcom = (sh.st.otrapcom ? sh.st.otrapcom : sh.st.trapcom);
if(arg=trapcom[sig]) if(arg=trapcom[sig])
sfputr(sfstdout,arg,'\n'); sfputr(sfstdout,arg,'\n');
} }
@ -160,26 +159,26 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
{ {
sh_sigclear(sig); sh_sigclear(sig);
if(sig == 0) if(sig == 0)
shp->exittrap = 0; sh.exittrap = 0;
if(dflag) if(dflag)
signal(sig,SIG_DFL); signal(sig,SIG_DFL);
} }
else else
{ {
if(sig >= shp->st.trapmax) if(sig >= sh.st.trapmax)
shp->st.trapmax = sig+1; sh.st.trapmax = sig+1;
arg = shp->st.trapcom[sig]; arg = sh.st.trapcom[sig];
sh_sigtrap(sig); sh_sigtrap(sig);
shp->st.trapcom[sig] = (shp->sigflag[sig]&SH_SIGOFF) ? Empty : sh_strdup(action); sh.st.trapcom[sig] = (sh.sigflag[sig]&SH_SIGOFF) ? Empty : sh_strdup(action);
if(arg && arg != Empty) if(arg && arg != Empty)
free(arg); free(arg);
if(sig == 0 && (!shp->fn_depth || shp->end_fn)) if(sig == 0 && (!sh.fn_depth || sh.end_fn))
shp->exittrap = 1; sh.exittrap = 1;
} }
} }
} }
else /* print out current traps */ else /* print out current traps */
sig_list(shp,-2); sig_list(-2);
return(0); return(0);
} }
@ -191,7 +190,6 @@ int b_kill(int argc,char *argv[],Shbltin_t *context)
{ {
register char *signame; register char *signame;
register int sig=SIGTERM, flag=0, n; register int sig=SIGTERM, flag=0, n;
register Shell_t *shp = context->shp;
int usemenu = 0; int usemenu = 0;
NOT_USED(argc); NOT_USED(argc);
#if defined(JOBS) && defined(SIGSTOP) #if defined(JOBS) && defined(SIGSTOP)
@ -206,7 +204,7 @@ int b_kill(int argc,char *argv[],Shbltin_t *context)
#endif /* defined(JOBS) && defined(SIGSTOP) */ #endif /* defined(JOBS) && defined(SIGSTOP) */
{ {
case ':': case ':':
if((signame=argv[opt_info.index++]) && (sig=sig_number(shp,signame+1))>=0) if((signame=argv[opt_info.index++]) && (sig=sig_number(signame+1))>=0)
goto endopts; goto endopts;
opt_info.index--; opt_info.index--;
errormsg(SH_DICT,2, "%s", opt_info.arg); errormsg(SH_DICT,2, "%s", opt_info.arg);
@ -242,35 +240,35 @@ endopts:
if(flag&L_FLAG) if(flag&L_FLAG)
{ {
if(!(*argv)) if(!(*argv))
sig_list(shp,usemenu); sig_list(usemenu);
else while(signame = *argv++) else while(signame = *argv++)
{ {
if(isdigit(*signame)) if(isdigit(*signame))
sig_list(shp,((int)strtol(signame, (char**)0, 10)&0177)+1); sig_list(((int)strtol(signame, (char**)0, 10)&0177)+1);
else else
{ {
if((sig=sig_number(shp,signame))<0) if((sig=sig_number(signame))<0)
{ {
shp->exitval = 2; sh.exitval = 2;
errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame); errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
UNREACHABLE(); UNREACHABLE();
} }
sfprintf(sfstdout,"%d\n",sig); sfprintf(sfstdout,"%d\n",sig);
} }
} }
return(shp->exitval); return(sh.exitval);
} }
if(flag&S_FLAG) if(flag&S_FLAG)
{ {
if((sig=sig_number(shp,signame)) < 0 || sig > shp->gd->sigmax) if((sig=sig_number(signame)) < 0 || sig > sh.sigmax)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame); errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
UNREACHABLE(); UNREACHABLE();
} }
} }
if(job_walk(sfstdout,job_kill,sig,argv)) if(job_walk(sfstdout,job_kill,sig,argv))
shp->exitval = 1; sh.exitval = 1;
return(shp->exitval); return(sh.exitval);
} }
#if defined(JOBS) && defined(SIGSTOP) #if defined(JOBS) && defined(SIGSTOP)
@ -306,9 +304,9 @@ int b_suspend(int argc,char *argv[],Shbltin_t *context)
errormsg(SH_DICT, ERROR_exit(1), "cannot suspend a login shell"); errormsg(SH_DICT, ERROR_exit(1), "cannot suspend a login shell");
UNREACHABLE(); UNREACHABLE();
} }
if(kill(context->shp->gd->pid, SIGSTOP) != 0) if(kill(sh.pid, SIGSTOP) != 0)
{ {
errormsg(SH_DICT, ERROR_exit(1), "could not signal main shell at PID %d", context->shp->gd->pid); errormsg(SH_DICT, ERROR_exit(1), "could not signal main shell at PID %d", sh.pid);
UNREACHABLE(); UNREACHABLE();
} }
return(0); return(0);
@ -319,7 +317,7 @@ int b_suspend(int argc,char *argv[],Shbltin_t *context)
* Given the name or number of a signal return the signal number * Given the name or number of a signal return the signal number
*/ */
static int sig_number(Shell_t *shp,const char *string) static int sig_number(const char *string)
{ {
const Shtable_t *tp; const Shtable_t *tp;
register int n,o,sig=0; register int n,o,sig=0;
@ -365,29 +363,29 @@ static int sig_number(Shell_t *shp,const char *string)
n = tp->sh_number; n = tp->sh_number;
} }
if((n>>SH_SIGBITS)&SH_SIGRUNTIME) if((n>>SH_SIGBITS)&SH_SIGRUNTIME)
n = shp->gd->sigruntime[(n&((1<<SH_SIGBITS)-1))-1]; n = sh.sigruntime[(n&((1<<SH_SIGBITS)-1))-1];
else else
{ {
n &= (1<<SH_SIGBITS)-1; n &= (1<<SH_SIGBITS)-1;
if(n < SH_TRAP) if(n < SH_TRAP)
n--; n--;
} }
if(n<0 && shp->gd->sigruntime[1] && (name=stakptr(o)) && *name++=='R' && *name++=='T') if(n<0 && sh.sigruntime[1] && (name=stakptr(o)) && *name++=='R' && *name++=='T')
{ {
/* Real-time signals */ /* Real-time signals */
if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+') /* MIN+ */ if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+') /* MIN+ */
{ {
if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name) if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
n = shp->gd->sigruntime[SH_SIGRTMIN] + sig; n = sh.sigruntime[SH_SIGRTMIN] + sig;
} }
else if(name[0]=='M' && name[1]=='A' && name[2]=='X' && name[3]=='-') /* MAX- */ else if(name[0]=='M' && name[1]=='A' && name[2]=='X' && name[3]=='-') /* MAX- */
{ {
if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name) if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
n = shp->gd->sigruntime[SH_SIGRTMAX] - sig; n = sh.sigruntime[SH_SIGRTMAX] - sig;
} }
else if((sig=(int)strtol(name,&name,10)) > 0 && !*name) else if((sig=(int)strtol(name,&name,10)) > 0 && !*name)
n = shp->gd->sigruntime[SH_SIGRTMIN] + sig - 1; n = sh.sigruntime[SH_SIGRTMIN] + sig - 1;
if(n<shp->gd->sigruntime[SH_SIGRTMIN] || n>shp->gd->sigruntime[SH_SIGRTMAX]) if(n < sh.sigruntime[SH_SIGRTMIN] || n > sh.sigruntime[SH_SIGRTMAX])
n = -1; n = -1;
} }
} }
@ -398,29 +396,29 @@ static int sig_number(Shell_t *shp,const char *string)
* synthesize signal name for sig in buf * synthesize signal name for sig in buf
* pfx!=0 prepends SIG to default signal number * pfx!=0 prepends SIG to default signal number
*/ */
static char* sig_name(Shell_t *shp,int sig, char* buf, int pfx) static char* sig_name(int sig, char* buf, int pfx)
{ {
register int i; register int i;
i = 0; i = 0;
if(sig>shp->gd->sigruntime[SH_SIGRTMIN] && sig<shp->gd->sigruntime[SH_SIGRTMAX]) if(sig > sh.sigruntime[SH_SIGRTMIN] && sig < sh.sigruntime[SH_SIGRTMAX])
{ {
buf[i++] = 'R'; buf[i++] = 'R';
buf[i++] = 'T'; buf[i++] = 'T';
buf[i++] = 'M'; buf[i++] = 'M';
if(sig>shp->gd->sigruntime[SH_SIGRTMIN]+(shp->gd->sigruntime[SH_SIGRTMAX]-shp->gd->sigruntime[SH_SIGRTMIN])/2) if(sig > sh.sigruntime[SH_SIGRTMIN] + (sh.sigruntime[SH_SIGRTMAX] - sh.sigruntime[SH_SIGRTMIN]) / 2)
{ {
buf[i++] = 'A'; buf[i++] = 'A';
buf[i++] = 'X'; buf[i++] = 'X';
buf[i++] = '-'; buf[i++] = '-';
sig = shp->gd->sigruntime[SH_SIGRTMAX]-sig; sig = sh.sigruntime[SH_SIGRTMAX] - sig;
} }
else else
{ {
buf[i++] = 'I'; buf[i++] = 'I';
buf[i++] = 'N'; buf[i++] = 'N';
buf[i++] = '+'; buf[i++] = '+';
sig = sig-shp->gd->sigruntime[SH_SIGRTMIN]; sig = sig - sh.sigruntime[SH_SIGRTMIN];
} }
} }
else if(pfx) else if(pfx)
@ -440,7 +438,7 @@ static char* sig_name(Shell_t *shp,int sig, char* buf, int pfx)
* if <flag> is -1, then print all signal names in menu format * if <flag> is -1, then print all signal names in menu format
* if <flag> is <-1, then print all traps * if <flag> is <-1, then print all traps
*/ */
static void sig_list(register Shell_t *shp,register int flag) static void sig_list(register int flag)
{ {
register const struct shtable2 *tp; register const struct shtable2 *tp;
register int sig; register int sig;
@ -452,7 +450,7 @@ static void sig_list(register Shell_t *shp,register int flag)
if(flag<=0) if(flag<=0)
{ {
/* not all signals may be defined, so initialize */ /* not all signals may be defined, so initialize */
for(sig=shp->gd->sigmax; sig>=0; sig--) for(sig=sh.sigmax; sig>=0; sig--)
names[sig] = 0; names[sig] = 0;
for(sig=SH_DEBUGTRAP; sig>=0; sig--) for(sig=SH_DEBUGTRAP; sig>=0; sig--)
traps[sig] = 0; traps[sig] = 0;
@ -460,7 +458,7 @@ static void sig_list(register Shell_t *shp,register int flag)
for(; *tp->sh_name; tp++) for(; *tp->sh_name; tp++)
{ {
sig = tp->sh_number&((1<<SH_SIGBITS)-1); sig = tp->sh_number&((1<<SH_SIGBITS)-1);
if (((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) && (sig = shp->gd->sigruntime[sig-1]+1) == 1) if (((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) && (sig = sh.sigruntime[sig-1]+1) == 1)
continue; continue;
if(sig==flag) if(sig==flag)
{ {
@ -473,25 +471,25 @@ static void sig_list(register Shell_t *shp,register int flag)
names[sig] = (char*)tp->sh_name; names[sig] = (char*)tp->sh_name;
} }
if(flag > 0) if(flag > 0)
sfputr(sfstdout, sig_name(shp,flag-1,name,0), '\n'); sfputr(sfstdout, sig_name(flag-1,name,0), '\n');
else if(flag<-1) else if(flag<-1)
{ {
/* print the traps */ /* print the traps */
register char *trap,**trapcom; register char *trap,**trapcom;
sig = shp->st.trapmax; sig = sh.st.trapmax;
/* use parent traps if otrapcom is set (for $(trap) */ /* use parent traps if otrapcom is set (for $(trap) */
trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom); trapcom = (sh.st.otrapcom ? sh.st.otrapcom : sh.st.trapcom);
while(--sig >= 0) while(--sig >= 0)
{ {
if(!(trap=trapcom[sig])) if(!(trap=trapcom[sig]))
continue; continue;
if(sig > shp->gd->sigmax || !(sname=(char*)names[sig])) if(sig > sh.sigmax || !(sname=(char*)names[sig]))
sname = sig_name(shp,sig,name,1); sname = sig_name(sig,name,1);
sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname); sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
} }
for(sig=SH_DEBUGTRAP; sig>=0; sig--) for(sig=SH_DEBUGTRAP; sig>=0; sig--)
{ {
if(!(trap=shp->st.otrap?shp->st.otrap[sig]:shp->st.trap[sig])) if(!(trap=sh.st.otrap ? sh.st.otrap[sig] : sh.st.trap[sig]))
continue; continue;
sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]); sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
} }
@ -499,11 +497,11 @@ static void sig_list(register Shell_t *shp,register int flag)
else else
{ {
/* print all the signal names */ /* print all the signal names */
for(sig=1; sig <= shp->gd->sigmax; sig++) for(sig=1; sig <= sh.sigmax; sig++)
{ {
if(!(sname=(char*)names[sig])) if(!(sname=(char*)names[sig]))
{ {
sname = sig_name(shp,sig,name,1); sname = sig_name(sig,name,1);
if(flag) if(flag)
sname = stakcopy(sname); sname = stakcopy(sname);
} }
@ -515,7 +513,7 @@ static void sig_list(register Shell_t *shp,register int flag)
if(flag) if(flag)
{ {
names[sig] = 0; names[sig] = 0;
sh_menu(sfstdout,shp->gd->sigmax,(char**)names+1); sh_menu(sfstdout,sh.sigmax,(char**)names+1);
} }
} }
} }

View file

@ -49,9 +49,12 @@
#include "variables.h" #include "variables.h"
#include "FEATURE/dynamic" #include "FEATURE/dynamic"
/*
* The first two fields must correspond with those in 'struct adata' in name.c and nvdisc.c
* (those fields are used via a type conversion in scanfilter() in name.c)
*/
struct tdata struct tdata
{ {
Shell_t *sh;
Namval_t *tp; Namval_t *tp;
const char *wctname; const char *wctname;
Sfio_t *outfile; Sfio_t *outfile;
@ -73,7 +76,7 @@ static int print_namval(Sfio_t*, Namval_t*, int, struct tdata*);
static void print_attribute(Namval_t*,void*); static void print_attribute(Namval_t*,void*);
static void print_all(Sfio_t*, Dt_t*, struct tdata*); static void print_all(Sfio_t*, Dt_t*, struct tdata*);
static void print_scan(Sfio_t*, int, Dt_t*, int, struct tdata*); static void print_scan(Sfio_t*, int, Dt_t*, int, struct tdata*);
static int unall(int, char**, Dt_t*, Shell_t*); static int unall(int, char**, Dt_t*);
static int setall(char**, int, Dt_t*, struct tdata*); static int setall(char**, int, Dt_t*, struct tdata*);
static void pushname(Namval_t*,void*); static void pushname(Namval_t*,void*);
static void(*nullscan)(Namval_t*,void*); static void(*nullscan)(Namval_t*,void*);
@ -92,7 +95,6 @@ int b_readonly(int argc,char *argv[],Shbltin_t *context)
struct tdata tdata; struct tdata tdata;
NOT_USED(argc); NOT_USED(argc);
memset((void*)&tdata,0,sizeof(tdata)); memset((void*)&tdata,0,sizeof(tdata));
tdata.sh = context->shp;
tdata.aflag = '-'; tdata.aflag = '-';
while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag) while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag)
{ {
@ -116,9 +118,9 @@ int b_readonly(int argc,char *argv[],Shbltin_t *context)
flag = (NV_ASSIGN|NV_RDONLY|NV_VARNAME); flag = (NV_ASSIGN|NV_RDONLY|NV_VARNAME);
else else
flag = (NV_ASSIGN|NV_EXPORT|NV_IDENT); flag = (NV_ASSIGN|NV_EXPORT|NV_IDENT);
if(!tdata.sh->prefix) if(!sh.prefix)
tdata.sh->prefix = ""; sh.prefix = Empty;
return(setall(argv,flag,tdata.sh->var_tree, &tdata)); return(setall(argv,flag,sh.var_tree, &tdata));
} }
/* /*
@ -136,8 +138,7 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context)
struct tdata tdata; struct tdata tdata;
NOT_USED(argc); NOT_USED(argc);
memset((void*)&tdata,0,sizeof(tdata)); memset((void*)&tdata,0,sizeof(tdata));
tdata.sh = context->shp; troot = sh.alias_tree;
troot = tdata.sh->alias_tree;
if(*argv[0]=='h') if(*argv[0]=='h')
flag |= NV_TAGGED; flag |= NV_TAGGED;
if(argv[1]) if(argv[1])
@ -192,7 +193,7 @@ int b_alias(int argc,register char *argv[],Shbltin_t *context)
if(rflag) /* hash -r: clear hash table */ if(rflag) /* hash -r: clear hash table */
nv_scan(troot,nv_rehash,(void*)0,NV_TAGGED,NV_TAGGED); nv_scan(troot,nv_rehash,(void*)0,NV_TAGGED,NV_TAGGED);
} }
else if(argv[1] && tdata.sh->subshell && !tdata.sh->subshare) else if(argv[1] && sh.subshell && !sh.subshare)
sh_subfork(); /* avoid affecting the parent shell's alias table */ sh_subfork(); /* avoid affecting the parent shell's alias table */
if(xflag && (flag&NV_TAGGED)) if(xflag && (flag&NV_TAGGED))
return(0); /* do nothing for 'alias -tx' */ return(0); /* do nothing for 'alias -tx' */
@ -220,8 +221,7 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
int isfloat=0, isadjust=0, shortint=0, sflag=0; int isfloat=0, isadjust=0, shortint=0, sflag=0;
memset((void*)&tdata,0,sizeof(tdata)); memset((void*)&tdata,0,sizeof(tdata));
tdata.sh = context->shp; troot = sh.var_tree;
troot = tdata.sh->var_tree;
if(ntp) /* custom declaration command added using enum */ if(ntp) /* custom declaration command added using enum */
{ {
tdata.tp = ntp->tp; tdata.tp = ntp->tp;
@ -359,7 +359,7 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
break; break;
case 'f': case 'f':
flag &= ~(NV_VARNAME|NV_ASSIGN); flag &= ~(NV_VARNAME|NV_ASSIGN);
troot = tdata.sh->fun_tree; troot = sh.fun_tree;
break; break;
case 'i': case 'i':
if(!opt_info.arg || (tdata.argnum = opt_info.num) <2 || tdata.argnum >64) if(!opt_info.arg || (tdata.argnum = opt_info.num) <2 || tdata.argnum >64)
@ -472,12 +472,12 @@ endargs:
errormsg(SH_DICT,2,e_optincompat1,"-T"); errormsg(SH_DICT,2,e_optincompat1,"-T");
error_info.errors++; error_info.errors++;
} }
if(troot==tdata.sh->fun_tree && ((isfloat || flag&~(NV_FUNCT|NV_TAGGED|NV_EXPORT|NV_LTOU)))) if(troot==sh.fun_tree && ((isfloat || flag&~(NV_FUNCT|NV_TAGGED|NV_EXPORT|NV_LTOU))))
{ {
errormsg(SH_DICT,2,e_optincompat1,"-f"); errormsg(SH_DICT,2,e_optincompat1,"-f");
error_info.errors++; error_info.errors++;
} }
if(sflag && troot==tdata.sh->fun_tree) if(sflag && troot==sh.fun_tree)
{ {
/* static function */ /* static function */
sflag = 0; sflag = 0;
@ -497,39 +497,39 @@ endargs:
flag |= NV_DOUBLE; flag |= NV_DOUBLE;
if(sflag) if(sflag)
{ {
if(tdata.sh->mktype) if(sh.mktype)
flag |= NV_REF|NV_TAGGED; flag |= NV_REF|NV_TAGGED;
else if(!tdata.sh->typeinit) else if(!sh.typeinit)
flag |= NV_STATIC|NV_IDENT; flag |= NV_STATIC|NV_IDENT;
} }
if(tdata.sh->fn_depth && !tdata.pflag) if(sh.fn_depth && !tdata.pflag)
flag |= NV_NOSCOPE; flag |= NV_NOSCOPE;
if(tdata.help) if(tdata.help)
tdata.help = sh_strdup(tdata.help); tdata.help = sh_strdup(tdata.help);
if(flag&NV_TYPE) if(flag&NV_TYPE)
{ {
Stk_t *stkp = tdata.sh->stk; Stk_t *stkp = sh.stk;
int off=0,offset = stktell(stkp); int off=0,offset = stktell(stkp);
if(!tdata.prefix) if(!tdata.prefix)
return(sh_outtype(tdata.sh,sfstdout)); return(sh_outtype(sfstdout));
sfputr(stkp,NV_CLASS,-1); sfputr(stkp,NV_CLASS,-1);
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(tdata.sh->namespace) if(sh.namespace)
{ {
off = stktell(stkp)+1; off = stktell(stkp)+1;
sfputr(stkp,nv_name(tdata.sh->namespace),'.'); sfputr(stkp,nv_name(sh.namespace),'.');
} }
else else
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
if(NV_CLASS[sizeof(NV_CLASS)-2]!='.') if(NV_CLASS[sizeof(NV_CLASS)-2]!='.')
sfputc(stkp,'.'); sfputc(stkp,'.');
sfputr(stkp,tdata.prefix,0); sfputr(stkp,tdata.prefix,0);
tdata.tp = nv_open(stkptr(stkp,offset),tdata.sh->var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN); tdata.tp = nv_open(stkptr(stkp,offset),sh.var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN);
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(!tdata.tp && off) if(!tdata.tp && off)
{ {
*stkptr(stkp,off)=0; *stkptr(stkp,off)=0;
tdata.tp = nv_open(stkptr(stkp,offset),tdata.sh->var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN); tdata.tp = nv_open(stkptr(stkp,offset),sh.var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN);
} }
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
stkseek(stkp,offset); stkseek(stkp,offset);
@ -550,7 +550,7 @@ endargs:
} }
else if(tdata.aflag==0 && ntp && ntp->tp) else if(tdata.aflag==0 && ntp && ntp->tp)
tdata.aflag = '-'; tdata.aflag = '-';
if(!tdata.sh->mktype) if(!sh.mktype)
tdata.help = 0; tdata.help = 0;
if(tdata.aflag=='+' && (flag&(NV_ARRAY|NV_IARRAY|NV_COMVAR)) && argv[1]) if(tdata.aflag=='+' && (flag&(NV_ARRAY|NV_IARRAY|NV_COMVAR)) && argv[1])
{ {
@ -573,8 +573,8 @@ static void print_value(Sfio_t *iop, Namval_t *np, struct tdata *tp)
} }
else if(nv_istable(np)) else if(nv_istable(np))
{ {
Dt_t *root = tp->sh->last_root; Dt_t *root = sh.last_root;
Namval_t *nsp = tp->sh->namespace; Namval_t *nsp = sh.namespace;
char *cp; char *cp;
if(!tp->pflag) if(!tp->pflag)
return; return;
@ -589,20 +589,20 @@ static void print_value(Sfio_t *iop, Namval_t *np, struct tdata *tp)
sfprintf(iop,"{\n", name); sfprintf(iop,"{\n", name);
tp->indent++; tp->indent++;
/* output types from namespace */ /* output types from namespace */
tp->sh->namespace = 0; sh.namespace = 0;
tp->sh->prefix = nv_name(np)+1; sh.prefix = nv_name(np)+1;
sh_outtype(tp->sh,iop); sh_outtype(iop);
tp->sh->prefix = 0; sh.prefix = 0;
tp->sh->namespace = np; sh.namespace = np;
tp->sh->last_root = root; sh.last_root = root;
/* output variables from namespace */ /* output variables from namespace */
print_scan(iop,NV_NOSCOPE,nv_dict(np),aflag=='+',tp); print_scan(iop,NV_NOSCOPE,nv_dict(np),aflag=='+',tp);
tp->wctname = cp; tp->wctname = cp;
tp->sh->namespace = 0; sh.namespace = 0;
/* output functions from namespace */ /* output functions from namespace */
print_scan(iop,NV_FUNCTION|NV_NOSCOPE,tp->sh->fun_tree,aflag=='+',tp); print_scan(iop,NV_FUNCTION|NV_NOSCOPE,sh.fun_tree,aflag=='+',tp);
tp->wctname = 0; tp->wctname = 0;
tp->sh->namespace = nsp; sh.namespace = nsp;
if(--tp->indent) if(--tp->indent)
sfnputc(iop,'\t',tp->indent); sfnputc(iop,'\t',tp->indent);
sfwrite(iop,"}\n",2); sfwrite(iop,"}\n",2);
@ -610,9 +610,9 @@ static void print_value(Sfio_t *iop, Namval_t *np, struct tdata *tp)
} }
if(tp->prefix && *tp->prefix=='a' && !nv_isattr(np,NV_TAGGED)) if(tp->prefix && *tp->prefix=='a' && !nv_isattr(np,NV_TAGGED))
sfprintf(iop,"%s ", tp->prefix); sfprintf(iop,"%s ", tp->prefix);
table = tp->sh->last_table; table = sh.last_table;
sfputr(iop,nv_name(np),aflag=='+'?'\n':'='); sfputr(iop,nv_name(np),aflag=='+'?'\n':'=');
tp->sh->last_table = table; sh.last_table = table;
if(aflag=='+') if(aflag=='+')
return; return;
if(nv_isarray(np) && nv_arrayptr(np)) if(nv_isarray(np) && nv_arrayptr(np))
@ -638,14 +638,13 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
char *last = 0; char *last = 0;
int nvflags=(flag&(NV_ARRAY|NV_NOARRAY|NV_VARNAME|NV_IDENT|NV_ASSIGN|NV_STATIC|NV_MOVE)); int nvflags=(flag&(NV_ARRAY|NV_NOARRAY|NV_VARNAME|NV_IDENT|NV_ASSIGN|NV_STATIC|NV_MOVE));
int r=0, ref=0, comvar=(flag&NV_COMVAR),iarray=(flag&NV_IARRAY); int r=0, ref=0, comvar=(flag&NV_COMVAR),iarray=(flag&NV_IARRAY);
Shell_t *shp =tp->sh; if(!sh.prefix)
if(!shp->prefix)
{ {
if(!tp->pflag) if(!tp->pflag)
nvflags |= NV_NOSCOPE; nvflags |= NV_NOSCOPE;
} }
else if(*shp->prefix==0) else if(*sh.prefix==0)
shp->prefix = 0; sh.prefix = 0;
if(*argv[0]=='+') if(*argv[0]=='+')
nvflags |= NV_NOADD; nvflags |= NV_NOADD;
flag &= ~(NV_NOARRAY|NV_NOSCOPE|NV_VARNAME|NV_IDENT|NV_STATIC|NV_COMVAR|NV_IARRAY); flag &= ~(NV_NOARRAY|NV_NOSCOPE|NV_VARNAME|NV_IDENT|NV_STATIC|NV_COMVAR|NV_IARRAY);
@ -667,7 +666,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
Namarr_t *ap=0; Namarr_t *ap=0;
Namval_t *mp; Namval_t *mp;
unsigned curflag; unsigned curflag;
if(troot == shp->fun_tree) if(troot == sh.fun_tree)
{ {
/* /*
* functions can be exported or * functions can be exported or
@ -677,29 +676,29 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
if(flag&NV_LTOU) if(flag&NV_LTOU)
{ {
/* Function names cannot be special builtin */ /* Function names cannot be special builtin */
if((np=nv_search(name,shp->bltin_tree,0)) && nv_isattr(np,BLT_SPC)) if((np=nv_search(name,sh.bltin_tree,0)) && nv_isattr(np,BLT_SPC))
{ {
errormsg(SH_DICT,ERROR_exit(1),e_badfun,name); errormsg(SH_DICT,ERROR_exit(1),e_badfun,name);
UNREACHABLE(); UNREACHABLE();
} }
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(shp->namespace) if(sh.namespace)
np = sh_fsearch(shp,name,NV_ADD|HASH_NOSCOPE); np = sh_fsearch(name,NV_ADD|HASH_NOSCOPE);
else else
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE); np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE);
} }
else else
{ {
if(shp->prefix) if(sh.prefix)
{ {
sfprintf(shp->strbuf,"%s.%s%c",shp->prefix,name,0); sfprintf(sh.strbuf,"%s.%s%c",sh.prefix,name,0);
name = sfstruse(shp->strbuf); name = sfstruse(sh.strbuf);
} }
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
np = 0; np = 0;
if(shp->namespace) if(sh.namespace)
np = sh_fsearch(shp,name,HASH_NOSCOPE); np = sh_fsearch(name,HASH_NOSCOPE);
if(!np) if(!np)
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
if(np=nv_search(name,troot,0)) if(np=nv_search(name,troot,0))
@ -717,7 +716,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
print_namval(sfstdout,np,tp->aflag=='+',tp); print_namval(sfstdout,np,tp->aflag=='+',tp);
continue; continue;
} }
if(shp->subshell && !shp->subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
if(tp->aflag=='-') if(tp->aflag=='-')
nv_onattr(np,flag|NV_FUNCTION); nv_onattr(np,flag|NV_FUNCTION);
@ -728,13 +727,13 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
r++; r++;
if(tp->help) if(tp->help)
{ {
int offset = stktell(shp->stk); int offset = stktell(sh.stk);
if(!np) if(!np)
{ {
sfputr(shp->stk,shp->prefix,'.'); sfputr(sh.stk,sh.prefix,'.');
sfputr(shp->stk,name,0); sfputr(sh.stk,name,0);
np = nv_search(stkptr(shp->stk,offset),troot,0); np = nv_search(stkptr(sh.stk,offset),troot,0);
stkseek(shp->stk,offset); stkseek(sh.stk,offset);
} }
if(np && np->nvalue.cp) if(np && np->nvalue.cp)
np->nvalue.rp->help = tp->help; np->nvalue.rp->help = tp->help;
@ -742,10 +741,10 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
continue; continue;
} }
/* tracked alias */ /* tracked alias */
if(troot==shp->track_tree && tp->aflag=='-') if(troot==sh.track_tree && tp->aflag=='-')
{ {
np = nv_search(name,troot,NV_ADD|HASH_NOSCOPE); np = nv_search(name,troot,NV_ADD|HASH_NOSCOPE);
path_alias(np,path_absolute(shp,nv_name(np),NIL(Pathcomp_t*),0)); path_alias(np,path_absolute(nv_name(np),NIL(Pathcomp_t*),0));
continue; continue;
} }
np = nv_open(name,troot,nvflags|((nvflags&NV_ASSIGN)?0:NV_ARRAY)|((iarray|(nvflags&(NV_REF|NV_NOADD)==NV_REF))?NV_FARRAY:0)); np = nv_open(name,troot,nvflags|((nvflags&NV_ASSIGN)?0:NV_ARRAY)|((iarray|(nvflags&(NV_REF|NV_NOADD)==NV_REF))?NV_FARRAY:0));
@ -794,7 +793,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
} }
if(flag==NV_ASSIGN && !ref && tp->aflag!='-' && !strchr(name,'=')) if(flag==NV_ASSIGN && !ref && tp->aflag!='-' && !strchr(name,'='))
{ {
if(troot!=shp->var_tree && (nv_isnull(np) || !print_namval(sfstdout,np,0,tp))) if(troot!=sh.var_tree && (nv_isnull(np) || !print_namval(sfstdout,np,0,tp)))
{ {
if(!sh.shcomp) if(!sh.shcomp)
sfprintf(sfstderr,sh_translate(e_noalias),name); sfprintf(sfstderr,sh_translate(e_noalias),name);
@ -803,9 +802,9 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
if(!comvar && !iarray) if(!comvar && !iarray)
continue; continue;
} }
if(troot==shp->var_tree) if(troot==sh.var_tree)
{ {
if(shp->subshell) if(sh.subshell)
{ {
/* /*
* Create local scope for virtual subshell. Variables with discipline functions * Create local scope for virtual subshell. Variables with discipline functions
@ -861,7 +860,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
flag &= ~NV_ASSIGN; flag &= ~NV_ASSIGN;
if(last=strchr(name,'=')) if(last=strchr(name,'='))
*last = 0; *last = 0;
if (shp->typeinit) if (sh.typeinit)
continue; continue;
curflag = np->nvflag; curflag = np->nvflag;
if(!(flag&NV_INTEGER) && (flag&(NV_LTOU|NV_UTOL))) if(!(flag&NV_INTEGER) && (flag&(NV_LTOU|NV_UTOL)))
@ -917,9 +916,9 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
newflag = curflag & ~flag; newflag = curflag & ~flag;
if (tp->aflag && (tp->argnum || (curflag!=newflag))) if (tp->aflag && (tp->argnum || (curflag!=newflag)))
{ {
if(shp->subshell) if(sh.subshell)
sh_assignok(np,2); sh_assignok(np,2);
if(troot!=shp->var_tree) if(troot!=sh.var_tree)
nv_setattr(np,newflag&~NV_ASSIGN); nv_setattr(np,newflag&~NV_ASSIGN);
else else
{ {
@ -946,12 +945,12 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
if(tp->aflag=='-') if(tp->aflag=='-')
{ {
Dt_t *hp=0; Dt_t *hp=0;
if(nv_isattr(np,NV_PARAM) && shp->st.prevst) if(nv_isattr(np,NV_PARAM) && sh.st.prevst)
{ {
if(!(hp=(Dt_t*)shp->st.prevst->save_tree)) if(!(hp=(Dt_t*)sh.st.prevst->save_tree))
hp = dtvnext(shp->var_tree); hp = dtvnext(sh.var_tree);
} }
if(tp->sh->mktype) if(sh.mktype)
nv_onattr(np,NV_REF|NV_FUNCT); nv_onattr(np,NV_REF|NV_FUNCT);
else else
nv_setref(np,hp,NV_VARNAME); nv_setref(np,hp,NV_VARNAME);
@ -964,16 +963,16 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
} }
else else
{ {
if(shp->prefix) if(sh.prefix)
errormsg(SH_DICT,2, e_subcomvar,shp->prefix); errormsg(SH_DICT,2, e_subcomvar,sh.prefix);
if(tp->aflag) if(tp->aflag)
{ {
if(troot==shp->fun_tree) if(troot==sh.fun_tree)
{ {
flag |= NV_FUNCTION; flag |= NV_FUNCTION;
tp->prefix = 0; tp->prefix = 0;
} }
else if(troot==shp->var_tree) else if(troot==sh.var_tree)
{ {
flag |= (nvflags&NV_ARRAY); flag |= (nvflags&NV_ARRAY);
if(iarray) if(iarray)
@ -995,7 +994,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
print_scan(sfstdout,flag|NV_REF,troot,tp->aflag=='+',tp); print_scan(sfstdout,flag|NV_REF,troot,tp->aflag=='+',tp);
} }
} }
else if(troot==shp->alias_tree) else if(troot==sh.alias_tree)
print_scan(sfstdout,0,troot,0,tp); print_scan(sfstdout,0,troot,0,tp);
else else
print_all(sfstdout,troot,tp); print_all(sfstdout,troot,tp);
@ -1029,12 +1028,12 @@ static int maxlib;
* return: 0: already loaded 1: first load * return: 0: already loaded 1: first load
*/ */
int sh_addlib(Shell_t* shp, void* dll, char* name, Pathcomp_t* pp) int sh_addlib(void* dll, char* name, Pathcomp_t* pp)
{ {
register int n; register int n;
register int r; register int r;
Libinit_f initfn; Libinit_f initfn;
Shbltin_t *sp = &shp->bltindata; Shbltin_t *sp = &sh.bltindata;
sp->nosfio = 0; sp->nosfio = 0;
for (n = r = 0; n < nlib; n++) for (n = r = 0; n < nlib; n++)
@ -1066,7 +1065,7 @@ int sh_addlib(Shell_t* shp, void* dll, char* name, Pathcomp_t* pp)
return !r; return !r;
} }
Shbltin_f sh_getlib(Shell_t* shp, char* sym, Pathcomp_t* pp) Shbltin_f sh_getlib(char* sym, Pathcomp_t* pp)
{ {
register int n; register int n;
@ -1076,18 +1075,6 @@ Shbltin_f sh_getlib(Shell_t* shp, char* sym, Pathcomp_t* pp)
return 0; return 0;
} }
#else
int sh_addlib(Shell_t* shp, void* library, char* name, Pathcomp_t* pp)
{
return 0;
}
Shbltin_f sh_getlib(Shell_t* shp, char* name, Pathcomp_t* pp)
{
return 0;
}
#endif /* SHOPT_DYNAMIC */ #endif /* SHOPT_DYNAMIC */
/* /*
@ -1112,10 +1099,9 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
#endif #endif
NOT_USED(argc); NOT_USED(argc);
memset(&tdata,0,sizeof(tdata)); memset(&tdata,0,sizeof(tdata));
tdata.sh = context->shp; stkp = sh.stk;
stkp = tdata.sh->stk; if(!sh.pathlist)
if(!tdata.sh->pathlist) path_absolute(argv[0],NIL(Pathcomp_t*),0);
path_absolute(tdata.sh,argv[0],NIL(Pathcomp_t*),0);
while (n = optget(argv,sh_optbuiltin)) switch (n) while (n = optget(argv,sh_optbuiltin)) switch (n)
{ {
case 's': case 's':
@ -1164,7 +1150,7 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
UNREACHABLE(); UNREACHABLE();
} }
#endif #endif
if(tdata.sh->subshell && !tdata.sh->subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
} }
#if SHOPT_DYNAMIC #if SHOPT_DYNAMIC
@ -1177,13 +1163,13 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
} }
if(list) if(list)
sfprintf(sfstdout, "%s %08lu %s\n", arg, ver, path); sfprintf(sfstdout, "%s %08lu %s\n", arg, ver, path);
sh_addlib(tdata.sh,library,arg,NiL); sh_addlib(library,arg,NiL);
} }
else else
#endif /* SHOPT_DYNAMIC */ #endif /* SHOPT_DYNAMIC */
if(*argv==0 && !dlete) if(*argv==0 && !dlete)
{ {
print_scan(sfstdout, flag, tdata.sh->bltin_tree, 1, &tdata); print_scan(sfstdout, flag, sh.bltin_tree, 1, &tdata);
return(0); return(0);
} }
r = 0; r = 0;
@ -1221,7 +1207,7 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
break; break;
} }
} }
if(!addr && (np = nv_search(arg,context->shp->bltin_tree,0))) if(!addr && (np = nv_search(arg,sh.bltin_tree,0)))
{ {
if(nv_isattr(np,BLT_SPC)) if(nv_isattr(np,BLT_SPC))
errmsg = "restricted name"; errmsg = "restricted name";
@ -1244,11 +1230,10 @@ int b_set(int argc,register char *argv[],Shbltin_t *context)
{ {
struct tdata tdata; struct tdata tdata;
memset(&tdata,0,sizeof(tdata)); memset(&tdata,0,sizeof(tdata));
tdata.sh = context->shp;
tdata.prefix=0; tdata.prefix=0;
if(argv[1]) if(argv[1])
{ {
if(sh_argopts(argc,argv,tdata.sh) < 0) if(sh_argopts(argc,argv) < 0)
return(2); return(2);
if(sh_isoption(SH_VERBOSE)) if(sh_isoption(SH_VERBOSE))
sh_onstate(SH_VERBOSE); sh_onstate(SH_VERBOSE);
@ -1257,7 +1242,7 @@ int b_set(int argc,register char *argv[],Shbltin_t *context)
} }
else else
/* scan name chain and print */ /* scan name chain and print */
print_scan(sfstdout,0,tdata.sh->var_tree,0,&tdata); print_scan(sfstdout,0,sh.var_tree,0,&tdata);
return(0); return(0);
} }
@ -1270,19 +1255,19 @@ int b_set(int argc,register char *argv[],Shbltin_t *context)
int b_unalias(int argc,register char *argv[],Shbltin_t *context) int b_unalias(int argc,register char *argv[],Shbltin_t *context)
{ {
Shell_t *shp = context->shp; NOT_USED(context);
if(shp->subshell && !shp->subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
return(unall(argc,argv,shp->alias_tree,shp)); return(unall(argc,argv,sh.alias_tree));
} }
int b_unset(int argc,register char *argv[],Shbltin_t *context) int b_unset(int argc,register char *argv[],Shbltin_t *context)
{ {
Shell_t *shp = context->shp; NOT_USED(context);
return(unall(argc,argv,shp->var_tree,shp)); return(unall(argc,argv,sh.var_tree));
} }
static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp) static int unall(int argc, char **argv, register Dt_t *troot)
{ {
register Namval_t *np; register Namval_t *np;
register const char *name; register const char *name;
@ -1291,7 +1276,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
int nflag=0,all=0,isfun,jmpval,nofree_attr; int nflag=0,all=0,isfun,jmpval,nofree_attr;
struct checkpt buff; struct checkpt buff;
NOT_USED(argc); NOT_USED(argc);
if(troot==shp->alias_tree) if(troot==sh.alias_tree)
name = sh_optunalias; name = sh_optunalias;
else else
name = sh_optunset; name = sh_optunset;
@ -1307,7 +1292,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
nflag = NV_NOREF; nflag = NV_NOREF;
/* FALLTHROUGH */ /* FALLTHROUGH */
case 'v': case 'v':
troot = shp->var_tree; troot = sh.var_tree;
break; break;
case ':': case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg); errormsg(SH_DICT,2, "%s", opt_info.arg);
@ -1325,7 +1310,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
if(!troot) if(!troot)
return(1); return(1);
r = 0; r = 0;
if(troot==shp->var_tree) if(troot==sh.var_tree)
nflag |= NV_VARNAME; nflag |= NV_VARNAME;
else else
nflag = NV_NOSCOPE; nflag = NV_NOSCOPE;
@ -1334,7 +1319,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
dtclear(troot); dtclear(troot);
return(r); return(r);
} }
sh_pushcontext(shp,&buff,1); sh_pushcontext(&sh,&buff,1);
while(name = *argv++) while(name = *argv++)
{ {
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
@ -1342,8 +1327,8 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
if(jmpval==0) if(jmpval==0)
{ {
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(shp->namespace && troot!=shp->var_tree) if(sh.namespace && troot!=sh.var_tree)
np = sh_fsearch(shp,name,nflag?HASH_NOSCOPE:0); np = sh_fsearch(name,nflag?HASH_NOSCOPE:0);
if(!np) if(!np)
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
np=nv_open(name,troot,NV_NOADD|nflag); np=nv_open(name,troot,NV_NOADD|nflag);
@ -1363,7 +1348,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
continue; continue;
} }
isfun = is_afunction(np); isfun = is_afunction(np);
if(troot==shp->var_tree) if(troot==sh.var_tree)
{ {
Namarr_t *ap; Namarr_t *ap;
#if SHOPT_FIXEDARRAY #if SHOPT_FIXEDARRAY
@ -1375,7 +1360,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
r=1; r=1;
continue; continue;
} }
if(shp->subshell) if(sh.subshell)
{ {
/* /*
* Create local scope for virtual subshell. Variables with discipline functions * Create local scope for virtual subshell. Variables with discipline functions
@ -1391,33 +1376,33 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
* Preset aliases have the NV_NOFREE attribute and cannot be safely freed from memory. * Preset aliases have the NV_NOFREE attribute and cannot be safely freed from memory.
* _nv_unset discards this flag so it's obtained now to prevent an invalid free crash. * _nv_unset discards this flag so it's obtained now to prevent an invalid free crash.
*/ */
if(troot==shp->alias_tree) if(troot==sh.alias_tree)
nofree_attr = nv_isattr(np,NV_NOFREE); /* note: returns bitmask, not boolean */ nofree_attr = nv_isattr(np,NV_NOFREE); /* note: returns bitmask, not boolean */
if(!nv_isnull(np) || nv_size(np) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE))) if(!nv_isnull(np) || nv_size(np) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE)))
_nv_unset(np,0); _nv_unset(np,0);
if(troot==shp->var_tree && shp->st.real_fun && (dp=shp->var_tree->walk) && dp==shp->st.real_fun->sdict) if(troot==sh.var_tree && sh.st.real_fun && (dp=sh.var_tree->walk) && dp==sh.st.real_fun->sdict)
nv_delete(np,dp,NV_NOFREE); nv_delete(np,dp,NV_NOFREE);
else if(isfun) else if(isfun)
{ {
if(troot!=shp->fun_base) if(troot!=sh.fun_base)
nv_offattr(np,NV_FUNCTION); /* invalidate */ nv_offattr(np,NV_FUNCTION); /* invalidate */
else if(!(np->nvalue.rp && np->nvalue.rp->running)) else if(!(np->nvalue.rp && np->nvalue.rp->running))
nv_delete(np,troot,0); nv_delete(np,troot,0);
} }
/* The alias has been unset by call to _nv_unset, remove it from the tree */ /* The alias has been unset by call to _nv_unset, remove it from the tree */
else if(troot==shp->alias_tree) else if(troot==sh.alias_tree)
nv_delete(np,troot,nofree_attr); nv_delete(np,troot,nofree_attr);
else else
nv_close(np); nv_close(np);
} }
else if(troot==shp->alias_tree) else if(troot==sh.alias_tree)
r = 1; r = 1;
else if(troot==shp->fun_tree && troot!=shp->fun_base && nv_search(name,shp->fun_tree,0)) else if(troot==sh.fun_tree && troot!=sh.fun_base && nv_search(name,sh.fun_tree,0))
nv_open(name,troot,NV_NOSCOPE); /* create dummy virtual subshell node without NV_FUNCTION attribute */ nv_open(name,troot,NV_NOSCOPE); /* create dummy virtual subshell node without NV_FUNCTION attribute */
} }
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
return(r); return(r);
} }
@ -1429,7 +1414,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
{ {
register char *cp; register char *cp;
int indent=tp->indent, outname=0, isfun; int indent=tp->indent, outname=0, isfun;
sh_sigcheck(tp->sh); sh_sigcheck();
if(flag) if(flag)
flag = '\n'; flag = '\n';
if(tp->noref && nv_isref(np)) if(tp->noref && nv_isref(np))
@ -1489,7 +1474,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
if(flag) if(flag)
{ {
if(tp->pflag && np->nvalue.ip && np->nvalue.rp->hoffset>=0) if(tp->pflag && np->nvalue.ip && np->nvalue.rp->hoffset>=0)
sfprintf(file," #line %d %s\n",np->nvalue.rp->lineno,fname?sh_fmtq(fname):""); sfprintf(file," #line %d %s\n", np->nvalue.rp->lineno, fname ? sh_fmtq(fname) : Empty);
else else
sfputc(file, '\n'); sfputc(file, '\n');
} }
@ -1498,12 +1483,12 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
if(nv_isattr(np,NV_FTMP)) if(nv_isattr(np,NV_FTMP))
{ {
fname = 0; fname = 0;
iop = tp->sh->heredocs; iop = sh.heredocs;
} }
else if(fname) else if(fname)
iop = sfopen(iop,fname,"r"); iop = sfopen(iop,fname,"r");
else if(tp->sh->gd->hist_ptr) else if(sh.hist_ptr)
iop = (tp->sh->gd->hist_ptr)->histfp; iop = (sh.hist_ptr)->histfp;
if(iop && sfseek(iop,(Sfoff_t)np->nvalue.rp->hoffset,SEEK_SET)>=0) if(iop && sfseek(iop,(Sfoff_t)np->nvalue.rp->hoffset,SEEK_SET)>=0)
sfmove(iop,file, nv_size(np), -1); sfmove(iop,file, nv_size(np), -1);
else else
@ -1546,7 +1531,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
} }
return(1); return(1);
} }
else if(outname || (tp->scanmask && tp->scanroot==tp->sh->var_tree)) else if(outname || (tp->scanmask && tp->scanroot==sh.var_tree))
sfputr(file,nv_name(np),'\n'); sfputr(file,nv_name(np),'\n');
return(0); return(0);
} }
@ -1582,7 +1567,7 @@ static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tda
Namval_t *onp = 0; Namval_t *onp = 0;
char *name=0; char *name=0;
int len; int len;
tp->sh->last_table=0; sh.last_table=0;
flag &= ~NV_ASSIGN; flag &= ~NV_ASSIGN;
tp->scanmask = flag&~NV_NOSCOPE; tp->scanmask = flag&~NV_NOSCOPE;
tp->scanroot = root; tp->scanroot = root;
@ -1596,11 +1581,11 @@ static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tda
if(flag==NV_LTOU || flag==NV_UTOL) if(flag==NV_LTOU || flag==NV_UTOL)
tp->scanmask |= NV_UTOL|NV_LTOU; tp->scanmask |= NV_UTOL|NV_LTOU;
namec = nv_scan(root, nullscan, (void*)tp, tp->scanmask, flag&~NV_IARRAY); namec = nv_scan(root, nullscan, (void*)tp, tp->scanmask, flag&~NV_IARRAY);
argv = tp->argnam = (char**)stkalloc(tp->sh->stk,(namec+1)*sizeof(char*)); argv = tp->argnam = (char**)stkalloc(sh.stk,(namec+1)*sizeof(char*));
namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag&~NV_IARRAY); namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag&~NV_IARRAY);
if(mbcoll()) if(mbcoll())
strsort(argv,namec,strcoll); strsort(argv,namec,strcoll);
if(namec==0 && tp->sh->namespace && nv_dict(tp->sh->namespace)==root) if(namec==0 && sh.namespace && nv_dict(sh.namespace)==root)
{ {
sfnputc(file,'\t',tp->indent); sfnputc(file,'\t',tp->indent);
sfwrite(file,":\n",2); sfwrite(file,":\n",2);

View file

@ -70,7 +70,6 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
register char *limit; register char *limit;
register int mode=0, n; register int mode=0, n;
register unsigned long hit = 0; register unsigned long hit = 0;
Shell_t *shp = context->shp;
#ifdef _lib_getrlimit #ifdef _lib_getrlimit
struct rlimit rlp; struct rlimit rlp;
#endif /* _lib_getrlimit */ #endif /* _lib_getrlimit */
@ -80,6 +79,7 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
rlim_t i; rlim_t i;
char tmp[41]; char tmp[41];
Optdisc_t disc; Optdisc_t disc;
NOT_USED(context);
memset(&disc, 0, sizeof(disc)); memset(&disc, 0, sizeof(disc));
disc.version = OPT_VERSION; disc.version = OPT_VERSION;
disc.infof = infof; disc.infof = infof;
@ -135,7 +135,7 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
unit = shtab_units[tp->type]; unit = shtab_units[tp->type];
if(limit) if(limit)
{ {
if(shp->subshell && !shp->subshare) if(sh.subshell && !sh.subshare)
sh_subfork(); sh_subfork();
if(strcmp(limit,e_unlimited)==0) if(strcmp(limit,e_unlimited)==0)
i = INFINITY; i = INFINITY;

View file

@ -44,7 +44,7 @@
#define Q_FLAG (1 << 5) #define Q_FLAG (1 << 5)
#define T_FLAG (1 << 6) #define T_FLAG (1 << 6)
static int whence(Shell_t *,char**, int); static int whence(char**, int);
/* /*
* command is called with argc==0 when checking for -V or -v option * command is called with argc==0 when checking for -V or -v option
@ -54,7 +54,6 @@ static int whence(Shell_t *,char**, int);
int b_command(register int argc,char *argv[],Shbltin_t *context) int b_command(register int argc,char *argv[],Shbltin_t *context)
{ {
register int n, flags=0; register int n, flags=0;
register Shell_t *shp = context->shp;
opt_info.index = opt_info.offset = 0; opt_info.index = opt_info.offset = 0;
while((n = optget(argv,sh_optcommand))) switch(n) while((n = optget(argv,sh_optcommand))) switch(n)
{ {
@ -102,7 +101,7 @@ int b_command(register int argc,char *argv[],Shbltin_t *context)
} }
if(!*argv) if(!*argv)
return((flags & (X_FLAG|V_FLAG)) != 0 ? 2 : 0); return((flags & (X_FLAG|V_FLAG)) != 0 ? 2 : 0);
return(whence(shp,argv, flags)); return(whence(argv, flags));
} }
/* /*
@ -111,7 +110,6 @@ int b_command(register int argc,char *argv[],Shbltin_t *context)
int b_whence(int argc,char *argv[],Shbltin_t *context) int b_whence(int argc,char *argv[],Shbltin_t *context)
{ {
register int flags=0, n; register int flags=0, n;
register Shell_t *shp = context->shp;
NOT_USED(argc); NOT_USED(argc);
if(*argv[0]=='t') if(*argv[0]=='t')
flags = V_FLAG; /* <t>ype == whence -v */ flags = V_FLAG; /* <t>ype == whence -v */
@ -151,10 +149,10 @@ int b_whence(int argc,char *argv[],Shbltin_t *context)
errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0)); errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
UNREACHABLE(); UNREACHABLE();
} }
return(whence(shp, argv, flags)); return(whence(argv, flags));
} }
static int whence(Shell_t *shp,char **argv, register int flags) static int whence(char **argv, register int flags)
{ {
register const char *name; register const char *name;
register Namval_t *np; register Namval_t *np;
@ -187,7 +185,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
aflag++; aflag++;
} }
/* non-tracked aliases */ /* non-tracked aliases */
if((np=nv_search(name,shp->alias_tree,0)) if((np=nv_search(name,sh.alias_tree,0))
&& !nv_isnull(np) && !nv_isattr(np,NV_TAGGED) && !nv_isnull(np) && !nv_isattr(np,NV_TAGGED)
&& (cp=nv_getval(np))) && (cp=nv_getval(np)))
{ {
@ -207,7 +205,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
} }
bltins: bltins:
/* functions */ /* functions */
if(!(flags&F_FLAG) && (np = nv_bfsearch(name, shp->fun_tree, &nq, &notused)) && is_afunction(np)) if(!(flags&F_FLAG) && (np = nv_bfsearch(name, sh.fun_tree, &nq, &notused)) && is_afunction(np))
{ {
if(flags&Q_FLAG) if(flags&Q_FLAG)
continue; continue;
@ -219,7 +217,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
{ {
sfprintf(sfstdout,sh_translate(is_ufunction)); sfprintf(sfstdout,sh_translate(is_ufunction));
pp = 0; pp = 0;
while(!path_search(shp,name,&pp,3) && pp && (pp = pp->next)) while(!path_search(name,&pp,3) && pp && (pp = pp->next))
; ;
if(*stakptr(PATH_OFFSET)=='/') if(*stakptr(PATH_OFFSET)=='/')
sfprintf(sfstdout,sh_translate(e_autoloadfrom),sh_fmtq(stakptr(PATH_OFFSET))); sfprintf(sfstdout,sh_translate(e_autoloadfrom),sh_fmtq(stakptr(PATH_OFFSET)));
@ -235,7 +233,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
aflag++; aflag++;
} }
/* built-ins */ /* built-ins */
if((np = nv_bfsearch(name, shp->bltin_tree, &nq, &notused)) && !nv_isnull(np)) if((np = nv_bfsearch(name, sh.bltin_tree, &nq, &notused)) && !nv_isnull(np))
{ {
if(flags&V_FLAG) if(flags&V_FLAG)
if(nv_isattr(np,BLT_SPC)) if(nv_isattr(np,BLT_SPC))
@ -262,7 +260,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
/* /*
* See comments in sh/path.c for info on what path_search()'s true/false return values mean * See comments in sh/path.c for info on what path_search()'s true/false return values mean
*/ */
if(path_search(shp, name, &pp, aflag>1 ? 3 : 2)) if(path_search(name, &pp, aflag>1 ? 3 : 2))
{ {
cp = name; cp = name;
if(*cp!='/') if(*cp!='/')
@ -288,7 +286,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
else if(maybe_undef_fn) else if(maybe_undef_fn)
{ {
/* Skip defined function or builtin (already done above) */ /* Skip defined function or builtin (already done above) */
if(!nv_search(cp,shp->fun_tree,0)) if(!nv_search(cp,sh.fun_tree,0))
{ {
/* Undefined/autoloadable function on FPATH */ /* Undefined/autoloadable function on FPATH */
sfputr(sfstdout,sh_fmtq(cp),-1); sfputr(sfstdout,sh_fmtq(cp),-1);
@ -305,13 +303,13 @@ static int whence(Shell_t *shp,char **argv, register int flags)
else if(cp) else if(cp)
{ {
int is_pathbound_builtin = 0; int is_pathbound_builtin = 0;
cp = path_fullname(shp,cp); /* resolve '.' & '..' */ cp = path_fullname(cp); /* resolve '.' & '..' */
if(flags&(V_FLAG|T_FLAG)) if(flags&(V_FLAG|T_FLAG))
{ {
if(!(flags&T_FLAG)) if(!(flags&T_FLAG))
sfputr(sfstdout,sh_fmtq(name),' '); sfputr(sfstdout,sh_fmtq(name),' ');
/* built-in version of program */ /* built-in version of program */
if(nv_search(cp,shp->bltin_tree,0)) if(nv_search(cp,sh.bltin_tree,0))
{ {
if(flags&T_FLAG) if(flags&T_FLAG)
is_pathbound_builtin = 1; is_pathbound_builtin = 1;
@ -320,7 +318,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
} }
/* tracked aliases next */ /* tracked aliases next */
else if(!sh_isstate(SH_DEFPATH) else if(!sh_isstate(SH_DEFPATH)
&& (np = nv_search(name,shp->track_tree,0)) && (np = nv_search(name,sh.track_tree,0))
&& !nv_isattr(np,NV_NOALIAS) && !nv_isattr(np,NV_NOALIAS)
&& strcmp(cp,nv_getval(np))==0) && strcmp(cp,nv_getval(np))==0)
msg = sh_translate(is_talias); msg = sh_translate(is_talias);

View file

@ -331,7 +331,7 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
register int size='x'; register int size='x';
while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t')) while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t'))
cp--; cp--;
if(!var && !strchr(ap->argval,'/') && (((cp==outbuff&&ep->sh->nextprompt==1) || (strchr(";&|(",size)) && (cp==outbuff+1||size=='('||cp[-2]!='>') && *begin!='~' ))) if(!var && !strchr(ap->argval,'/') && (((cp==outbuff&&sh.nextprompt==1) || (strchr(";&|(",size)) && (cp==outbuff+1||size=='('||cp[-2]!='>') && *begin!='~' )))
{ {
cmd_completion=1; cmd_completion=1;
sh_onstate(SH_COMPLETE); sh_onstate(SH_COMPLETE);
@ -345,14 +345,14 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
} }
else else
{ {
com = sh_argbuild(ep->sh,&narg,comptr,0); com = sh_argbuild(&narg,comptr,0);
/* special handling for leading quotes */ /* special handling for leading quotes */
if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\'')) if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
begin--; begin--;
} }
sh_offstate(SH_COMPLETE); sh_offstate(SH_COMPLETE);
/* allow a search to be aborted */ /* allow a search to be aborted */
if(ep->sh->trapnote&SH_SIGSET) if(sh.trapnote&SH_SIGSET)
{ {
rval = -1; rval = -1;
goto done; goto done;
@ -461,7 +461,7 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
Namval_t *np; Namval_t *np;
/* add as tracked alias */ /* add as tracked alias */
Pathcomp_t *pp; Pathcomp_t *pp;
if(*cp=='/' && (pp=path_dirfind(ep->sh->pathlist,cp,'/')) && (np=nv_search(begin,ep->sh->track_tree,NV_ADD))) if(*cp=='/' && (pp=path_dirfind(sh.pathlist,cp,'/')) && (np=nv_search(begin,sh.track_tree,NV_ADD)))
path_alias(np,pp); path_alias(np,pp);
out = strcopy(begin,cp); out = strcopy(begin,cp);
} }
@ -552,7 +552,7 @@ int ed_macro(Edit_t *ep, register int i)
ep->e_macro[2] = ed_getchar(ep,1); ep->e_macro[2] = ed_getchar(ep,1);
else else
ep->e_macro[2] = 0; ep->e_macro[2] = 0;
if (isalnum(i)&&(np=nv_search(ep->e_macro,ep->sh->alias_tree,HASH_SCOPE))&&(out=nv_getval(np))) if (isalnum(i)&&(np=nv_search(ep->e_macro,sh.alias_tree,HASH_SCOPE))&&(out=nv_getval(np)))
{ {
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
/* copy to buff in internal representation */ /* copy to buff in internal representation */
@ -583,7 +583,7 @@ int ed_macro(Edit_t *ep, register int i)
int ed_fulledit(Edit_t *ep) int ed_fulledit(Edit_t *ep)
{ {
register char *cp; register char *cp;
if(!shgd->hist_ptr) if(!sh.hist_ptr)
return(-1); return(-1);
/* use EDITOR on current command */ /* use EDITOR on current command */
if(ep->e_hline == ep->e_hismax) if(ep->e_hline == ep->e_hismax)
@ -594,9 +594,9 @@ int ed_fulledit(Edit_t *ep)
ep->e_inbuf[ep->e_eol+1] = 0; ep->e_inbuf[ep->e_eol+1] = 0;
ed_external(ep->e_inbuf, (char *)ep->e_inbuf); ed_external(ep->e_inbuf, (char *)ep->e_inbuf);
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
sfwrite(shgd->hist_ptr->histfp,(char*)ep->e_inbuf,ep->e_eol+1); sfwrite(sh.hist_ptr->histfp,(char*)ep->e_inbuf,ep->e_eol+1);
sh_onstate(SH_HISTORY); sh_onstate(SH_HISTORY);
hist_flush(shgd->hist_ptr); hist_flush(sh.hist_ptr);
} }
cp = strcopy((char*)ep->e_inbuf,e_runvi); cp = strcopy((char*)ep->e_inbuf,e_runvi);
cp = strcopy(cp, fmtbase((long)ep->e_hline,10,0)); cp = strcopy(cp, fmtbase((long)ep->e_hline,10,0));

View file

@ -148,11 +148,11 @@ static const char bellchr[] = "\a"; /* bell char */
*/ */
int tty_check(int fd) int tty_check(int fd)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
struct termios tty; struct termios tty;
Sfio_t *sp; Sfio_t *sp;
ep->e_savefd = -1; ep->e_savefd = -1;
if(fd < 0 || fd > shgd->lim.open_max || sh.fdstatus[fd] == IOCLOSE if(fd < 0 || fd > sh.lim.open_max || sh.fdstatus[fd] == IOCLOSE
|| (sp = sh.sftable[fd]) && (sfset(sp,0,0) & SF_STRING)) || (sp = sh.sftable[fd]) && (sfset(sp,0,0) & SF_STRING))
return(0); return(0);
return(tty_get(fd,&tty)==0); return(tty_get(fd,&tty)==0);
@ -166,7 +166,7 @@ int tty_check(int fd)
int tty_get(register int fd, register struct termios *tty) int tty_get(register int fd, register struct termios *tty)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
if(fd == ep->e_savefd) if(fd == ep->e_savefd)
*tty = ep->e_savetty; *tty = ep->e_savetty;
else else
@ -194,7 +194,7 @@ int tty_get(register int fd, register struct termios *tty)
int tty_set(int fd, int action, struct termios *tty) int tty_set(int fd, int action, struct termios *tty)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
if(fd >=0) if(fd >=0)
{ {
while(tcsetattr(fd, action, tty) == SYSERR) while(tcsetattr(fd, action, tty) == SYSERR)
@ -218,9 +218,9 @@ int tty_set(int fd, int action, struct termios *tty)
void tty_cooked(register int fd) void tty_cooked(register int fd)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
if(ep->sh->st.trap[SH_KEYTRAP] && savelex) if(sh.st.trap[SH_KEYTRAP] && savelex)
memcpy(ep->sh->lex_context,savelex,sizeof(Lex_t)); memcpy(sh.lex_context,savelex,sizeof(Lex_t));
ep->e_keytrap = 0; ep->e_keytrap = 0;
if(ep->e_raw==0) if(ep->e_raw==0)
return; return;
@ -257,7 +257,7 @@ int tty_raw(register int fd, int echomode)
#ifdef L_MASK #ifdef L_MASK
struct ltchars lchars; struct ltchars lchars;
#endif /* L_MASK */ #endif /* L_MASK */
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
if(ep->e_raw==RAWMODE) if(ep->e_raw==RAWMODE)
return(echo?-1:0); return(echo?-1:0);
else if(ep->e_raw==ECHOMODE) else if(ep->e_raw==ECHOMODE)
@ -381,7 +381,7 @@ int tty_raw(register int fd, int echomode)
# ifdef TIOCGETC # ifdef TIOCGETC
int tty_alt(register int fd) int tty_alt(register int fd)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
int mask; int mask;
struct tchars ttychars; struct tchars ttychars;
switch(ep->e_raw) switch(ep->e_raw)
@ -429,7 +429,7 @@ int tty_alt(register int fd)
int tty_alt(register int fd) int tty_alt(register int fd)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
switch(ep->e_raw) switch(ep->e_raw)
{ {
case ECHOMODE: case ECHOMODE:
@ -580,7 +580,6 @@ void ed_crlf(register Edit_t *ep)
void ed_setup(register Edit_t *ep, int fd, int reedit) void ed_setup(register Edit_t *ep, int fd, int reedit)
{ {
Shell_t *shp = ep->sh;
register char *pp; register char *pp;
register char *last, *prev; register char *last, *prev;
char *ppmax; char *ppmax;
@ -590,16 +589,16 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
ep->e_fd = fd; ep->e_fd = fd;
ep->e_multiline = sh_isoption(SH_MULTILINE)!=0; ep->e_multiline = sh_isoption(SH_MULTILINE)!=0;
#ifdef SIGWINCH #ifdef SIGWINCH
if(!(shp->sigflag[SIGWINCH]&SH_SIGFAULT)) if(!(sh.sigflag[SIGWINCH]&SH_SIGFAULT))
{ {
signal(SIGWINCH,sh_fault); signal(SIGWINCH,sh_fault);
shp->sigflag[SIGWINCH] |= SH_SIGFAULT; sh.sigflag[SIGWINCH] |= SH_SIGFAULT;
} }
pp = shp->st.trapcom[SIGWINCH]; pp = sh.st.trapcom[SIGWINCH];
shp->st.trapcom[SIGWINCH] = 0; sh.st.trapcom[SIGWINCH] = 0;
sh_fault(SIGWINCH); sh_fault(SIGWINCH);
shp->st.trapcom[SIGWINCH] = pp; sh.st.trapcom[SIGWINCH] = pp;
ep->sh->winch = 0; sh.winch = 0;
#endif #endif
#if SHOPT_EDPREDICT #if SHOPT_EDPREDICT
ep->hlist = 0; ep->hlist = 0;
@ -608,12 +607,12 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
#endif /* SHOPT_EDPREDICT */ #endif /* SHOPT_EDPREDICT */
ep->e_stkoff = staktell(); ep->e_stkoff = staktell();
ep->e_stkptr = stakfreeze(0); ep->e_stkptr = stakfreeze(0);
if(!(last = shp->prompt)) if(!(last = sh.prompt))
last = ""; last = "";
shp->prompt = 0; sh.prompt = 0;
if(shp->gd->hist_ptr) if(sh.hist_ptr)
{ {
register History_t *hp = shp->gd->hist_ptr; register History_t *hp = sh.hist_ptr;
ep->e_hismax = hist_max(hp); ep->e_hismax = hist_max(hp);
ep->e_hismin = hist_min(hp); ep->e_hismin = hist_min(hp);
} }
@ -795,10 +794,10 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
#if defined(_pth_tput) && (_tput_terminfo || _tput_termcap) #if defined(_pth_tput) && (_tput_terminfo || _tput_termcap)
char *term; char *term;
if(!ep->e_term) if(!ep->e_term)
ep->e_term = nv_search("TERM",shp->var_tree,0); ep->e_term = nv_search("TERM",sh.var_tree,0);
if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname)) if(ep->e_term && (term=nv_getval(ep->e_term)) && strlen(term)<sizeof(ep->e_termname) && strcmp(term,ep->e_termname))
{ {
Shopt_t o = shp->options; Shopt_t o = sh.options;
sigblock(SIGINT); sigblock(SIGINT);
sh_offoption(SH_RESTRICTED); sh_offoption(SH_RESTRICTED);
sh_offoption(SH_VERBOSE); sh_offoption(SH_VERBOSE);
@ -817,7 +816,7 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
CURSOR_UP[0] = '\0'; /* no escape sequence is better than a faulty one */ CURSOR_UP[0] = '\0'; /* no escape sequence is better than a faulty one */
nv_unset(SH_SUBSCRNOD); nv_unset(SH_SUBSCRNOD);
strcpy(ep->e_termname,term); strcpy(ep->e_termname,term);
shp->options = o; sh.options = o;
sigrelease(SIGINT); sigrelease(SIGINT);
} }
#endif #endif
@ -833,11 +832,11 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
ep->e_lbuf[n] = *pp++; ep->e_lbuf[n] = *pp++;
ep->e_default = 0; ep->e_default = 0;
} }
if(ep->sh->st.trap[SH_KEYTRAP]) if(sh.st.trap[SH_KEYTRAP])
{ {
if(!savelex) if(!savelex)
savelex = (Lex_t*)sh_malloc(sizeof(Lex_t)); savelex = (Lex_t*)sh_malloc(sizeof(Lex_t));
memcpy(savelex, ep->sh->lex_context, sizeof(Lex_t)); memcpy(savelex, sh.lex_context, sizeof(Lex_t));
} }
} }
#endif /* SHOPT_ESH || SHOPT_VSH */ #endif /* SHOPT_ESH || SHOPT_VSH */
@ -871,9 +870,8 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
register Edit_t *ep = (Edit_t*)context; register Edit_t *ep = (Edit_t*)context;
register int rv= -1; register int rv= -1;
register int delim = ((ep->e_raw&RAWMODE)?nttyparm.c_cc[VEOL]:'\n'); register int delim = ((ep->e_raw&RAWMODE)?nttyparm.c_cc[VEOL]:'\n');
Shell_t *shp = ep->sh;
int mode = -1; int mode = -1;
int (*waitevent)(int,long,int) = shp->gd->waitevent; int (*waitevent)(int,long,int) = sh.waitevent;
/* sfpkrd must use select(2) to intercept SIGWINCH for ed_read */ /* sfpkrd must use select(2) to intercept SIGWINCH for ed_read */
if(ep->e_raw==ALTMODE) if(ep->e_raw==ALTMODE)
mode = 2; mode = 2;
@ -884,17 +882,17 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
} }
sh_onstate(SH_TTYWAIT); sh_onstate(SH_TTYWAIT);
errno = EINTR; errno = EINTR;
shp->gd->waitevent = 0; sh.waitevent = 0;
while(rv<0 && errno==EINTR) while(rv<0 && errno==EINTR)
{ {
if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP)) if(sh.trapnote&(SH_SIGSET|SH_SIGTRAP))
goto done; goto done;
#if SHOPT_ESH && SHOPT_VSH #if SHOPT_ESH && SHOPT_VSH
if(shp->winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_VI) || sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS))) if(sh.winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_VI) || sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS)))
#elif SHOPT_ESH #elif SHOPT_ESH
if(shp->winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS))) if(sh.winch && sh_isstate(SH_INTERACTIVE) && (sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS)))
#elif SHOPT_VSH #elif SHOPT_VSH
if(shp->winch && sh_isstate(SH_INTERACTIVE) && sh_isoption(SH_VI)) if(sh.winch && sh_isstate(SH_INTERACTIVE) && sh_isoption(SH_VI))
#else #else
if(0) if(0)
#endif #endif
@ -941,7 +939,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
emacs_redraw(ep->e_emacs); emacs_redraw(ep->e_emacs);
#endif #endif
} }
shp->winch = 0; sh.winch = 0;
/* an interrupt that should be ignored */ /* an interrupt that should be ignored */
errno = 0; errno = 0;
if(!waitevent || (rv=(*waitevent)(fd,-1L,0))>=0) if(!waitevent || (rv=(*waitevent)(fd,-1L,0))>=0)
@ -976,7 +974,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
rv = read(fd,buff,size); rv = read(fd,buff,size);
if(rv>=0 || errno!=EINTR) if(rv>=0 || errno!=EINTR)
break; break;
if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP)) if(sh.trapnote&(SH_SIGSET|SH_SIGTRAP))
goto done; goto done;
/* an interrupt that should be ignored */ /* an interrupt that should be ignored */
fixtime(); fixtime();
@ -985,7 +983,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
else if(rv>=0 && mode>0) else if(rv>=0 && mode>0)
rv = read(fd,buff,rv>0?rv:1); rv = read(fd,buff,rv>0?rv:1);
done: done:
shp->gd->waitevent = waitevent; sh.waitevent = waitevent;
sh_offstate(SH_TTYWAIT); sh_offstate(SH_TTYWAIT);
return(rv); return(rv);
} }
@ -1114,7 +1112,7 @@ int ed_getchar(register Edit_t *ep,int mode)
killpg(getpgrp(),SIGINT); killpg(getpgrp(),SIGINT);
siglongjmp(ep->e_env, UINTR); siglongjmp(ep->e_env, UINTR);
} }
if(mode<=0 && ep->sh->st.trap[SH_KEYTRAP]) if(mode<=0 && sh.st.trap[SH_KEYTRAP])
{ {
ep->e_keytrap = 1; ep->e_keytrap = 1;
n=1; n=1;
@ -1559,7 +1557,7 @@ int ed_genlen(register const genchar *str)
int tcgetattr(int fd, struct termios *tt) int tcgetattr(int fd, struct termios *tt)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
register int r,i; register int r,i;
ep->e_tcgeta = 0; ep->e_tcgeta = 0;
ep->e_echoctl = (ECHOCTL!=0); ep->e_echoctl = (ECHOCTL!=0);
@ -1581,7 +1579,7 @@ int tcgetattr(int fd, struct termios *tt)
int tcsetattr(int fd,int mode,struct termios *tt) int tcsetattr(int fd,int mode,struct termios *tt)
{ {
register Edit_t *ep = (Edit_t*)(shgd->ed_context); register Edit_t *ep = (Edit_t*)(sh.ed_context);
register int r; register int r;
if(ep->e_tcgeta) if(ep->e_tcgeta)
{ {
@ -1626,7 +1624,6 @@ static int keytrap(Edit_t *ep,char *inbuff,register int insize, int bufsize, int
{ {
register char *cp; register char *cp;
int savexit; int savexit;
Shell_t *shp = ep->sh;
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
char buff[MAXLINE]; char buff[MAXLINE];
ed_external(ep->e_inbuf,cp=buff); ed_external(ep->e_inbuf,cp=buff);
@ -1646,9 +1643,9 @@ static int keytrap(Edit_t *ep,char *inbuff,register int insize, int bufsize, int
nv_putval(ED_COLNOD,(char*)&ep->e_col,NV_NOFREE|NV_INTEGER); nv_putval(ED_COLNOD,(char*)&ep->e_col,NV_NOFREE|NV_INTEGER);
nv_putval(ED_TXTNOD,(char*)cp,NV_NOFREE); nv_putval(ED_TXTNOD,(char*)cp,NV_NOFREE);
nv_putval(ED_MODENOD,ep->e_vi_insert,NV_NOFREE); nv_putval(ED_MODENOD,ep->e_vi_insert,NV_NOFREE);
savexit = shp->savexit; savexit = sh.savexit;
sh_trap(shp->st.trap[SH_KEYTRAP],0); sh_trap(sh.st.trap[SH_KEYTRAP],0);
shp->savexit = savexit; sh.savexit = savexit;
if((cp = nv_getval(ED_CHRNOD)) == inbuff) if((cp = nv_getval(ED_CHRNOD)) == inbuff)
nv_unset(ED_CHRNOD); nv_unset(ED_CHRNOD);
else if(bufsize>0) else if(bufsize>0)
@ -1723,7 +1720,7 @@ int ed_histgen(Edit_t *ep,const char *pattern)
size_t m; size_t m;
char *cp, **argv=0, **av, **ar; char *cp, **argv=0, **av, **ar;
static int maxmatch; static int maxmatch;
if(!(hp=ep->sh->gd->hist_ptr) && (!nv_getval(HISTFILE) || !sh_histinit(ep->sh))) if(!(hp=sh.hist_ptr) && (!nv_getval(HISTFILE) || !sh_histinit()))
return(0); return(0);
if(ep->e_cur <=2) if(ep->e_cur <=2)
maxmatch = 0; maxmatch = 0;
@ -1733,7 +1730,7 @@ int ed_histgen(Edit_t *ep,const char *pattern)
ep->hfirst = 0; ep->hfirst = 0;
return(0); return(0);
} }
hp = ep->sh->gd->hist_ptr; hp = sh.hist_ptr;
if(*pattern=='#' && *++pattern=='#') if(*pattern=='#' && *++pattern=='#')
return(0); return(0);
cp = stakalloc(m=strlen(pattern)+6); cp = stakalloc(m=strlen(pattern)+6);
@ -1881,10 +1878,9 @@ void ed_histlist(Edit_t *ep,int n)
#endif /* SHOPT_EDPREDICT */ #endif /* SHOPT_EDPREDICT */
void *ed_open(Shell_t *shp) void *ed_open(void)
{ {
Edit_t *ed = sh_newof(0,Edit_t,1,0); Edit_t *ed = sh_newof(0,Edit_t,1,0);
ed->sh = shp;
strcpy(ed->e_macro,"_??"); strcpy(ed->e_macro,"_??");
return((void*)ed); return((void*)ed);
} }

View file

@ -263,7 +263,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
#ifdef ESH_NFIRST #ifdef ESH_NFIRST
ed_ungetchar(ep->ed,cntl('N')); ed_ungetchar(ep->ed,cntl('N'));
#else #else
location = hist_locate(shgd->hist_ptr,location.hist_command,location.hist_line,1); location = hist_locate(sh.hist_ptr,location.hist_command,location.hist_line,1);
if (location.hist_command < histlines) if (location.hist_command < histlines)
{ {
hline = location.hist_command; hline = location.hist_command;
@ -350,7 +350,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
continue; continue;
#endif /* u370 */ #endif /* u370 */
case '\t': case '\t':
if(cur>0 && ep->ed->sh->nextprompt) if(cur>0 && sh.nextprompt)
{ {
if(ep->ed->e_tabcount==0) if(ep->ed->e_tabcount==0)
{ {
@ -684,7 +684,7 @@ update:
hline = location.hist_command; /* start at saved position */ hline = location.hist_command; /* start at saved position */
hloff = location.hist_line; hloff = location.hist_line;
#endif /* ESH_NFIRST */ #endif /* ESH_NFIRST */
location = hist_locate(shgd->hist_ptr,hline,hloff,count); location = hist_locate(sh.hist_ptr,hline,hloff,count);
if (location.hist_command > histlines) if (location.hist_command > histlines)
{ {
beep(); beep();
@ -1348,7 +1348,7 @@ static void search(Emacs_t* ep,genchar *out,int direction)
} }
else else
direction = ep->prevdirection ; direction = ep->prevdirection ;
location = hist_find(shgd->hist_ptr,(char*)lstring,hline,1,direction); location = hist_find(sh.hist_ptr,(char*)lstring,hline,1,direction);
i = location.hist_command; i = location.hist_command;
if(i>0) if(i>0)
{ {

View file

@ -303,8 +303,8 @@ getline:
{ {
/* search history for string */ /* search history for string */
hl = hist_find(shgd->hist_ptr, str, hl = hist_find(sh.hist_ptr, str,
shgd->hist_ptr->histind, sh.hist_ptr->histind,
flag&HIST_QUESTION, -1); flag&HIST_QUESTION, -1);
if((n = hl.hist_command) == -1) if((n = hl.hist_command) == -1)
n = 0; /* not found */ n = 0; /* not found */
@ -312,10 +312,10 @@ getline:
if(n) if(n)
{ {
if(n < 0) /* determine index for backref */ if(n < 0) /* determine index for backref */
n = shgd->hist_ptr->histind + n; n = sh.hist_ptr->histind + n;
/* search and use history file if found */ /* search and use history file if found */
if(n > 0 && hist_seek(shgd->hist_ptr, n) != -1) if(n > 0 && hist_seek(sh.hist_ptr, n) != -1)
ref = shgd->hist_ptr->histfp; ref = sh.hist_ptr->histfp;
} }
if(!ref) if(!ref)

View file

@ -58,7 +58,6 @@
#endif #endif
#define _HIST_PRIVATE \ #define _HIST_PRIVATE \
void *histshell; \
off_t histcnt; /* offset into history file */\ off_t histcnt; /* offset into history file */\
off_t histmarker; /* offset of last command marker */ \ off_t histmarker; /* offset of last command marker */ \
int histflush; /* set if flushed outside of hflush() */\ int histflush; /* set if flushed outside of hflush() */\
@ -107,7 +106,7 @@ static History_t *hist_ptr;
static int acctinit(History_t *hp) static int acctinit(History_t *hp)
{ {
register char *cp, *acctfile; register char *cp, *acctfile;
Namval_t *np = nv_search("ACCTFILE",((Shell_t*)hp->histshell)->var_tree,0); Namval_t *np = nv_search("ACCTFILE",sh.var_tree,0);
if(!np || !(acctfile=nv_getval(np))) if(!np || !(acctfile=nv_getval(np)))
return(0); return(0);
@ -169,9 +168,9 @@ static int sh_checkaudit(History_t *hp, const char *name, char *logbuf, size_t l
id1 = id2 = strtol(cp,&last,10); id1 = id2 = strtol(cp,&last,10);
if(*last=='-') if(*last=='-')
id1 = strtol(last+1,&last,10); id1 = strtol(last+1,&last,10);
if(shgd->euserid >=id1 && shgd->euserid <= id2) if(sh.euserid >=id1 && sh.euserid <= id2)
r |= 1; r |= 1;
if(shgd->userid >=id1 && shgd->userid <= id2) if(sh.userid >=id1 && sh.userid <= id2)
r |= 2; r |= 2;
cp = last; cp = last;
} }
@ -198,9 +197,8 @@ static void hist_touch(void *handle)
* cleaned up. * cleaned up.
* hist_open() returns 1, if history file is open * hist_open() returns 1, if history file is open
*/ */
int sh_histinit(void *sh_context) int sh_histinit(void)
{ {
Shell_t *shp = (Shell_t*)sh_context;
register int fd; register int fd;
register History_t *hp; register History_t *hp;
register char *histname; register char *histname;
@ -209,7 +207,7 @@ int sh_histinit(void *sh_context)
register char *cp; register char *cp;
register off_t hsize = 0; register off_t hsize = 0;
if(shgd->hist_ptr=hist_ptr) if(sh.hist_ptr=hist_ptr)
return(1); return(1);
if(!(histname = nv_getval(HISTFILE))) if(!(histname = nv_getval(HISTFILE)))
{ {
@ -222,7 +220,7 @@ int sh_histinit(void *sh_context)
histname = stakptr(offset); histname = stakptr(offset);
} }
retry: retry:
cp = path_relative(shp,histname); cp = path_relative(histname);
if(!histinit) if(!histinit)
histmode = S_IRUSR|S_IWUSR; histmode = S_IRUSR|S_IWUSR;
if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT|O_cloexec,histmode))>=0) if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT|O_cloexec,histmode))>=0)
@ -250,7 +248,7 @@ retry:
if(fd < 0) if(fd < 0)
{ {
/* don't allow root a history_file in /tmp */ /* don't allow root a history_file in /tmp */
if(shgd->userid) if(sh.userid)
{ {
if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*)))) if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*))))
return(0); return(0);
@ -267,8 +265,7 @@ retry:
maxlines = HIST_DFLT; maxlines = HIST_DFLT;
for(histmask=16;histmask <= maxlines; histmask <<=1 ); for(histmask=16;histmask <= maxlines; histmask <<=1 );
hp = new_of(History_t,(--histmask)*sizeof(off_t)); hp = new_of(History_t,(--histmask)*sizeof(off_t));
shgd->hist_ptr = hist_ptr = hp; sh.hist_ptr = hist_ptr = hp;
hp->histshell = (void*)shp;
hp->histsize = maxlines; hp->histsize = maxlines;
hp->histmask = histmask; hp->histmask = histmask;
hp->histfp= sfnew(NIL(Sfio_t*),hp->histbuff,HIST_BSIZE,fd,SF_READ|SF_WRITE|SF_APPENDWR|SF_SHARE); hp->histfp= sfnew(NIL(Sfio_t*),hp->histbuff,HIST_BSIZE,fd,SF_READ|SF_WRITE|SF_APPENDWR|SF_SHARE);
@ -319,7 +316,7 @@ retry:
if(hist_clean(fd) && hist_start>1 && hsize > HIST_MAX) if(hist_clean(fd) && hist_start>1 && hsize > HIST_MAX)
{ {
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"%d: hist_trim hsize=%d\n",shgd->current_pid,hsize); sfprintf(sfstderr,"%d: hist_trim hsize=%d\n",sh.current_pid,hsize);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
hp = hist_trim(hp,(int)hp->histind-maxlines); hp = hist_trim(hp,(int)hp->histind-maxlines);
@ -375,7 +372,7 @@ void hist_close(register History_t *hp)
#endif /* SHOPT_AUDIT */ #endif /* SHOPT_AUDIT */
free((char*)hp); free((char*)hp);
hist_ptr = 0; hist_ptr = 0;
shgd->hist_ptr = 0; sh.hist_ptr = 0;
#if SHOPT_ACCTFILE #if SHOPT_ACCTFILE
if(acctfd) if(acctfd)
{ {
@ -450,7 +447,7 @@ static History_t* hist_trim(History_t *hp, int n)
histinit = 1; histinit = 1;
histmode = statb.st_mode; histmode = statb.st_mode;
} }
if(!sh_histinit(hp->histshell)) if(!sh_histinit())
{ {
/* use the old history file */ /* use the old history file */
return hist_ptr = hist_old; return hist_ptr = hist_old;
@ -722,7 +719,7 @@ void hist_flush(register History_t *hp)
if(sfsync(hp->histfp)<0) if(sfsync(hp->histfp)<0)
{ {
hist_close(hp); hist_close(hp);
if(!sh_histinit(hp->histshell)) if(!sh_histinit())
sh_offoption(SH_HISTORY); sh_offoption(SH_HISTORY);
} }
hp->histflush = 0; hp->histflush = 0;
@ -772,7 +769,9 @@ static ssize_t hist_write(Sfio_t *iop,const void *buff,register size_t insize,Sf
if(hp->auditfp) if(hp->auditfp)
{ {
time_t t=time((time_t*)0); time_t t=time((time_t*)0);
sfprintf(hp->auditfp,"%u;%lu;%s;%*s%c",sh_isoption(SH_PRIVILEGED)?shgd->euserid:shgd->userid,(unsigned long)t,hp->tty,size,buff,0); sfprintf(hp->auditfp, "%u;%lu;%s;%*s%c",
sh_isoption(SH_PRIVILEGED) ? sh.euserid : sh.userid,
(unsigned long)t, hp->tty, size, buff, 0);
sfsync(hp->auditfp); sfsync(hp->auditfp);
} }
#endif /* SHOPT_AUDIT */ #endif /* SHOPT_AUDIT */
@ -933,7 +932,7 @@ Histloc_t hist_find(register History_t*hp,char *string,register int index1,int f
return(location); return(location);
} }
/* allow a search to be aborted */ /* allow a search to be aborted */
if(((Shell_t*)hp->histshell)->trapnote&SH_SIGSET) if(sh.trapnote & SH_SIGSET)
break; break;
} }
return(location); return(location);
@ -989,7 +988,7 @@ int hist_match(register History_t *hp,off_t offset,char *string,int *coffset)
int hist_copy(char *s1,int size,int command,int line) int hist_copy(char *s1,int size,int command,int line)
{ {
register int c; register int c;
register History_t *hp = shgd->hist_ptr; register History_t *hp = sh.hist_ptr;
register int count = 0; register int count = 0;
register char *s1max = s1+size; register char *s1max = s1+size;
if(!hp) if(!hp)

View file

@ -217,7 +217,7 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit
#if SHOPT_RAWONLY #if SHOPT_RAWONLY
# define viraw 1 # define viraw 1
#else #else
int viraw = (sh_isoption(SH_VIRAW) || ed->sh->st.trap[SH_KEYTRAP]); int viraw = (sh_isoption(SH_VIRAW) || sh.st.trap[SH_KEYTRAP]);
# ifndef FIORDCHK # ifndef FIORDCHK
clock_t oldtime, newtime; clock_t oldtime, newtime;
struct tms dummy; struct tms dummy;
@ -252,7 +252,7 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit
oldtime = times(&dummy); oldtime = times(&dummy);
#endif /* FIORDCHK */ #endif /* FIORDCHK */
/* abort of interrupt has occurred */ /* abort of interrupt has occurred */
if(ed->sh->trapnote&SH_SIGSET) if(sh.trapnote&SH_SIGSET)
i = -1; i = -1;
else else
{ {
@ -1529,7 +1529,7 @@ static void getline(register Vi_t* vp,register int mode)
mode != SEARCH && mode != SEARCH &&
last_virt >= 0 && last_virt >= 0 &&
(vp->ed->e_tabcount || !isblank(cur_virt)) && (vp->ed->e_tabcount || !isblank(cur_virt)) &&
vp->ed->sh->nextprompt) sh.nextprompt)
{ {
if(virtual[cur_virt]=='\\') if(virtual[cur_virt]=='\\')
{ {
@ -2302,7 +2302,7 @@ static int search(register Vi_t* vp,register int mode)
i = INVALID; i = INVALID;
if( new_direction==1 && curhline >= histmax ) if( new_direction==1 && curhline >= histmax )
curhline = histmin + 1; curhline = histmin + 1;
location = hist_find(shgd->hist_ptr,((char*)virtual)+1, curhline, 1, new_direction); location = hist_find(sh.hist_ptr,((char*)virtual)+1, curhline, 1, new_direction);
} }
cur_virt = i; cur_virt = i;
strncpy(lsearch, ((char*)virtual)+1, SEARCHSIZE-1); strncpy(lsearch, ((char*)virtual)+1, SEARCHSIZE-1);

View file

@ -128,7 +128,7 @@ struct argnod
extern struct dolnod *sh_argcreate(char*[]); extern struct dolnod *sh_argcreate(char*[]);
extern char *sh_argdolminus(void*); extern char *sh_argdolminus(void*);
extern int sh_argopts(int,char*[],void*); extern int sh_argopts(int,char*[]);
extern const char e_heading[]; extern const char e_heading[];

View file

@ -33,33 +33,33 @@
* IMPORTANT: The offsets on these macros must be synchronous * IMPORTANT: The offsets on these macros must be synchronous
* with the order of shtab_builtins[] in data/builtins.c! * with the order of shtab_builtins[] in data/builtins.c!
*/ */
#define SYSEXEC (shgd->bltin_cmds) /* exec */ #define SYSEXEC (sh.bltin_cmds) /* exec */
#define SYSREDIR (shgd->bltin_cmds+1) /* redirect */ #define SYSREDIR (sh.bltin_cmds+1) /* redirect */
#define SYSSET (shgd->bltin_cmds+2) /* set */ #define SYSSET (sh.bltin_cmds+2) /* set */
/* : */ /* : */
#define SYSTRUE (shgd->bltin_cmds+4) /* true */ #define SYSTRUE (sh.bltin_cmds+4) /* true */
#define SYSCOMMAND (shgd->bltin_cmds+5) /* command */ #define SYSCOMMAND (sh.bltin_cmds+5) /* command */
#define SYSCD (shgd->bltin_cmds+6) /* cd */ #define SYSCD (sh.bltin_cmds+6) /* cd */
#define SYSBREAK (shgd->bltin_cmds+7) /* break */ #define SYSBREAK (sh.bltin_cmds+7) /* break */
#define SYSCONT (shgd->bltin_cmds+8) /* continue */ #define SYSCONT (sh.bltin_cmds+8) /* continue */
#define SYSTYPESET (shgd->bltin_cmds+9) /* typeset \ */ #define SYSTYPESET (sh.bltin_cmds+9) /* typeset \ */
/* autoload | */ /* autoload | */
#define SYSCOMPOUND (shgd->bltin_cmds+11) /* compound | */ #define SYSCOMPOUND (sh.bltin_cmds+11) /* compound | */
/* float >typeset range */ /* float >typeset range */
/* functions | */ /* functions | */
/* integer | */ /* integer | */
#define SYSNAMEREF (shgd->bltin_cmds+15) /* nameref | */ #define SYSNAMEREF (sh.bltin_cmds+15) /* nameref | */
#define SYSTYPESET_END (shgd->bltin_cmds+15) /* / */ #define SYSTYPESET_END (sh.bltin_cmds+15) /* / */
#define SYSTEST (shgd->bltin_cmds+16) /* test */ #define SYSTEST (sh.bltin_cmds+16) /* test */
#define SYSBRACKET (shgd->bltin_cmds+17) /* [ */ #define SYSBRACKET (sh.bltin_cmds+17) /* [ */
#define SYSLET (shgd->bltin_cmds+18) /* let */ #define SYSLET (sh.bltin_cmds+18) /* let */
#define SYSEXPORT (shgd->bltin_cmds+19) /* export */ #define SYSEXPORT (sh.bltin_cmds+19) /* export */
#define SYSDOT (shgd->bltin_cmds+20) /* . */ #define SYSDOT (sh.bltin_cmds+20) /* . */
#define SYSSOURCE (shgd->bltin_cmds+21) /* source */ #define SYSSOURCE (sh.bltin_cmds+21) /* source */
#define SYSRETURN (shgd->bltin_cmds+22) /* return */ #define SYSRETURN (sh.bltin_cmds+22) /* return */
#define SYSENUM (shgd->bltin_cmds+23) /* enum */ #define SYSENUM (sh.bltin_cmds+23) /* enum */
/* entry point for shell special builtins */ /* entry point for shell special builtins */

View file

@ -124,59 +124,56 @@ extern char* sh_setenviron(const char*);
#define SH_READEVAL 0x4000 /* for sh_eval */ #define SH_READEVAL 0x4000 /* for sh_eval */
#define SH_FUNEVAL 0x10000 /* for sh_eval for function load */ #define SH_FUNEVAL 0x10000 /* for sh_eval for function load */
extern void sh_applyopts(Shell_t*,Shopt_t); extern char **sh_argbuild(int*,const struct comnod*,int);
extern char **sh_argbuild(Shell_t*,int*,const struct comnod*,int); extern struct dolnod *sh_argfree(struct dolnod*,int);
extern struct dolnod *sh_argfree(Shell_t *, struct dolnod*,int); extern struct dolnod *sh_argnew(char*[],struct dolnod**);
extern struct dolnod *sh_argnew(Shell_t*,char*[],struct dolnod**); extern void *sh_argopen(void);
extern void *sh_argopen(Shell_t*); extern struct argnod *sh_argprocsub(struct argnod*);
extern struct argnod *sh_argprocsub(Shell_t*,struct argnod*); extern void sh_argreset(struct dolnod*,struct dolnod*);
extern void sh_argreset(Shell_t*,struct dolnod*,struct dolnod*);
extern Namval_t *sh_assignok(Namval_t*,int); extern Namval_t *sh_assignok(Namval_t*,int);
extern struct dolnod *sh_arguse(Shell_t*); extern struct dolnod *sh_arguse(void);
extern char *sh_checkid(char*,char*); extern char *sh_checkid(char*,char*);
extern void sh_chktrap(Shell_t*); extern void sh_chktrap(void);
extern void sh_deparse(Sfio_t*,const Shnode_t*,int); extern void sh_deparse(Sfio_t*,const Shnode_t*,int);
extern int sh_debug(Shell_t *shp,const char*,const char*,const char*,char *const[],int); extern int sh_debug(const char*,const char*,const char*,char *const[],int);
extern int sh_echolist(Shell_t*,Sfio_t*, int, char**);
extern struct argnod *sh_endword(Shell_t*,int);
extern char **sh_envgen(void); extern char **sh_envgen(void);
extern void sh_envnolocal(Namval_t*,void*); extern void sh_envnolocal(Namval_t*,void*);
extern Sfdouble_t sh_arith(Shell_t*,const char*); extern Sfdouble_t sh_arith(const char*);
extern void *sh_arithcomp(Shell_t *,char*); extern void *sh_arithcomp(char*);
extern pid_t sh_fork(Shell_t*,int,int*); extern pid_t sh_fork(int,int*);
extern pid_t _sh_fork(Shell_t*,pid_t, int ,int*); extern pid_t _sh_fork(pid_t, int ,int*);
extern char *sh_mactrim(Shell_t*,char*,int); extern char *sh_mactrim(char*,int);
extern int sh_macexpand(Shell_t*,struct argnod*,struct argnod**,int); extern int sh_macexpand(struct argnod*,struct argnod**,int);
extern int sh_macfun(Shell_t*,const char*,int); extern int sh_macfun(const char*,int);
extern void sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*); extern void sh_machere(Sfio_t*, Sfio_t*, char*);
extern void *sh_macopen(Shell_t*); extern void *sh_macopen(void);
extern char *sh_macpat(Shell_t*,struct argnod*,int); extern char *sh_macpat(struct argnod*,int);
extern Sfdouble_t sh_mathfun(Shell_t*, void*, int, Sfdouble_t*); extern Sfdouble_t sh_mathfun(void*, int, Sfdouble_t*);
extern int sh_outtype(Shell_t*, Sfio_t*); extern int sh_outtype(Sfio_t*);
extern char *sh_mactry(Shell_t*,char*); extern char *sh_mactry(char*);
extern int sh_mathstd(const char*); extern int sh_mathstd(const char*);
extern void sh_printopts(Shopt_t,int,Shopt_t*); extern void sh_printopts(Shopt_t,int,Shopt_t*);
extern int sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long); extern int sh_readline(char**,volatile int,int,ssize_t,long);
extern Sfio_t *sh_sfeval(char*[]); extern Sfio_t *sh_sfeval(char*[]);
extern void sh_setmatch(Shell_t*,const char*,int,int,int[],int); extern void sh_setmatch(const char*,int,int,int[],int);
extern void sh_scope(Shell_t*, struct argnod*, int); extern void sh_scope(struct argnod*, int);
extern Namval_t *sh_scoped(Shell_t*, Namval_t*); extern Namval_t *sh_scoped(Namval_t*);
extern Dt_t *sh_subtracktree(int); extern Dt_t *sh_subtracktree(int);
extern Dt_t *sh_subfuntree(int); extern Dt_t *sh_subfuntree(int);
extern void sh_subjobcheck(pid_t); extern void sh_subjobcheck(pid_t);
extern int sh_subsavefd(int); extern int sh_subsavefd(int);
extern void sh_subtmpfile(Shell_t*); extern void sh_subtmpfile(void);
extern char *sh_substitute(const char*,const char*,char*); extern char *sh_substitute(const char*,const char*,char*);
extern void sh_timetraps(Shell_t*); extern void sh_timetraps(void);
extern const char *_sh_translate(const char*); extern const char *_sh_translate(const char*);
extern int sh_trace(Shell_t*,char*[],int); extern int sh_trace(char*[],int);
extern void sh_trim(char*); extern void sh_trim(char*);
extern int sh_type(const char*); extern int sh_type(const char*);
extern void sh_unscope(Shell_t*); extern void sh_unscope(void);
extern void sh_utol(const char*, char*); extern void sh_utol(const char*, char*);
extern int sh_whence(char**,int); extern int sh_whence(char**,int);
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
extern Namval_t *sh_fsearch(Shell_t*,const char *,int); extern Namval_t *sh_fsearch(const char *,int);
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
/* malloc related wrappers */ /* malloc related wrappers */
@ -214,7 +211,7 @@ extern char *sh_getcwd(void);
#define sh_getstate() (sh.st.states) #define sh_getstate() (sh.st.states)
#define sh_setstate(x) (sh.st.states = (x)) #define sh_setstate(x) (sh.st.states = (x))
#define sh_sigcheck(shp) do{if((shp)->trapnote&SH_SIGSET)sh_exit(SH_EXITSIG);} while(0) #define sh_sigcheck() do { if(sh.trapnote & SH_SIGSET) sh_exit(SH_EXITSIG); } while(0)
extern int32_t sh_mailchk; extern int32_t sh_mailchk;
extern const char e_dict[]; extern const char e_dict[];
@ -243,7 +240,7 @@ extern const char e_dict[];
# define STAT_SPAWN 12 # define STAT_SPAWN 12
# define STAT_SUBSHELL 13 # define STAT_SUBSHELL 13
extern const Shtable_t shtab_stats[]; extern const Shtable_t shtab_stats[];
# define sh_stats(x) (shgd->stats[(x)]++) # define sh_stats(x) (sh.stats[(x)]++)
#else #else
# define sh_stats(x) # define sh_stats(x)
#endif /* SHOPT_STATS */ #endif /* SHOPT_STATS */

View file

@ -131,7 +131,6 @@ typedef struct edit
char e_macro[4]; /* macro buffer */ char e_macro[4]; /* macro buffer */
void *e_vi; /* vi specific data */ void *e_vi; /* vi specific data */
void *e_emacs; /* emacs specific data */ void *e_emacs; /* emacs specific data */
Shell_t *sh; /* interpreter pointer */
char *e_stkptr; /* saved stack pointer */ char *e_stkptr; /* saved stack pointer */
int e_stkoff; /* saved stack offset */ int e_stkoff; /* saved stack offset */
char **e_clist; /* completion list after <ESC>= */ char **e_clist; /* completion list after <ESC>= */
@ -190,7 +189,7 @@ extern int ed_setcursor(Edit_t*, genchar*, int, int, int);
extern int ed_macro(Edit_t*,int); extern int ed_macro(Edit_t*,int);
extern int ed_expand(Edit_t*, char[],int*,int*,int,int); extern int ed_expand(Edit_t*, char[],int*,int*,int,int);
extern int ed_fulledit(Edit_t*); extern int ed_fulledit(Edit_t*);
extern void *ed_open(Shell_t*); extern void *ed_open(void);
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
extern int ed_internal(const char*, genchar*); extern int ed_internal(const char*, genchar*);
extern int ed_external(const genchar*, char*); extern int ed_external(const genchar*, char*);

View file

@ -108,11 +108,11 @@ struct checkpt
) )
#define sh_popcontext(shp,bp) ((shp)->jmplist=(bp)->prev, errorpop(&((bp)->err))) #define sh_popcontext(shp,bp) ((shp)->jmplist=(bp)->prev, errorpop(&((bp)->err)))
extern noreturn void sh_done(void*,int); extern noreturn void sh_done(int);
extern void sh_fault(int); extern void sh_fault(int);
extern void sh_sigclear(int); extern void sh_sigclear(int);
extern void sh_sigdone(void); extern void sh_sigdone(void);
extern void sh_siginit(void*); extern void sh_siginit(void);
extern void sh_sigtrap(int); extern void sh_sigtrap(int);
extern void sh_sigreset(int); extern void sh_sigreset(int);
extern void *sh_timeradd(unsigned long,int ,void (*)(void*),void*); extern void *sh_timeradd(unsigned long,int ,void (*)(void*),void*);

View file

@ -56,7 +56,7 @@ extern int _Hist;
#define hist_min(hp) ((_Hist=((int)((hp)->histind-(hp)->histsize)))>=0?_Hist:0) #define hist_min(hp) ((_Hist=((int)((hp)->histind-(hp)->histsize)))>=0?_Hist:0)
#define hist_max(hp) ((int)((hp)->histind)) #define hist_max(hp) ((int)((hp)->histind))
/* these are the history interface routines */ /* these are the history interface routines */
extern int sh_histinit(void *); extern int sh_histinit(void);
extern void hist_cancel(History_t*); extern void hist_cancel(History_t*);
extern void hist_close(History_t*); extern void hist_close(History_t*);
extern int hist_copy(char*, int, int, int); extern int hist_copy(char*, int, int, int);

View file

@ -52,29 +52,28 @@
struct ionod; struct ionod;
#endif /* !ARG_RAW */ #endif /* !ARG_RAW */
extern int sh_iocheckfd(Shell_t*,int); extern int sh_iocheckfd(int);
extern void sh_ioinit(Shell_t*); extern void sh_ioinit(void);
extern int sh_iomovefd(int); extern int sh_iomovefd(int);
extern int sh_iorenumber(Shell_t*,int,int); extern int sh_iorenumber(int,int);
extern void sh_pclose(int[]); extern void sh_pclose(int[]);
extern int sh_rpipe(int[]); extern int sh_rpipe(int[]);
extern void sh_iorestore(Shell_t*,int,int); extern void sh_iorestore(int,int);
#if defined(__EXPORT__) && defined(_BLD_DLL) #if defined(__EXPORT__) && defined(_BLD_DLL)
__EXPORT__ __EXPORT__
#endif #endif
extern Sfio_t *sh_iostream(Shell_t*,int); extern Sfio_t *sh_iostream(int);
extern int sh_redirect(Shell_t*,struct ionod*,int); extern int sh_redirect(struct ionod*,int);
extern void sh_iosave(Shell_t *, int,int,char*); extern void sh_iosave(int,int,char*);
extern int sh_iovalidfd(Shell_t*, int); extern int sh_iovalidfd(int);
extern int sh_iosafefd(Shell_t*, int); extern int sh_iosafefd(int);
extern int sh_inuse(Shell_t*, int); extern int sh_inuse(int);
extern void sh_iounsave(Shell_t*); extern void sh_iounsave(void);
extern void sh_iounpipe(Shell_t*); extern void sh_iounpipe(void);
extern int sh_chkopen(const char*); extern int sh_chkopen(const char*);
extern int sh_ioaccess(int,int); extern int sh_ioaccess(int,int);
extern int sh_devtofd(const char*); extern int sh_devtofd(const char*);
extern int sh_isdevfd(const char*); extern int sh_isdevfd(const char*);
extern int sh_source(Shell_t*, Sfio_t*, const char*);
/* the following are readonly */ /* the following are readonly */
extern const char e_pexists[]; extern const char e_pexists[];

View file

@ -59,7 +59,6 @@ struct process
{ {
struct process *p_nxtjob; /* next job structure */ struct process *p_nxtjob; /* next job structure */
struct process *p_nxtproc; /* next process in current job */ struct process *p_nxtproc; /* next process in current job */
Shell_t *p_shp; /* shell that posted the job */
int *p_exitval; /* place to store the exitval */ int *p_exitval; /* place to store the exitval */
pid_t p_pid; /* process id */ pid_t p_pid; /* process id */
pid_t p_pgrp; /* process group */ pid_t p_pgrp; /* process group */
@ -167,23 +166,23 @@ extern void job_bwait(char**);
extern int job_walk(Sfio_t*,int(*)(struct process*,int),int,char*[]); extern int job_walk(Sfio_t*,int(*)(struct process*,int),int,char*[]);
extern int job_kill(struct process*,int); extern int job_kill(struct process*,int);
extern int job_wait(pid_t); extern int job_wait(pid_t);
extern int job_post(Shell_t*,pid_t,pid_t); extern int job_post(pid_t,pid_t);
extern void *job_subsave(void); extern void *job_subsave(void);
extern void job_subrestore(void*); extern void job_subrestore(void*);
#if SHOPT_BGX #if SHOPT_BGX
extern void job_chldtrap(Shell_t*, const char*,int); extern void job_chldtrap(const char*,int);
#endif /* SHOPT_BGX */ #endif /* SHOPT_BGX */
#ifdef JOBS #ifdef JOBS
extern void job_init(Shell_t*,int); extern void job_init(int);
extern int job_close(Shell_t*); extern int job_close(void);
extern int job_list(struct process*,int); extern int job_list(struct process*,int);
extern int job_hup(struct process *, int); extern int job_hup(struct process *, int);
extern int job_switch(struct process*,int); extern int job_switch(struct process*,int);
extern void job_fork(pid_t); extern void job_fork(pid_t);
extern int job_reap(int); extern int job_reap(int);
#else #else
# define job_init(s,flag) # define job_init(flag)
# define job_close(s) (0) # define job_close() (0)
# define job_fork(p) # define job_fork(p)
#endif /* JOBS */ #endif /* JOBS */

View file

@ -63,7 +63,6 @@ typedef struct pathcomp
char *blib; char *blib;
unsigned short len; unsigned short len;
unsigned short flags; unsigned short flags;
Shell_t *shp;
} Pathcomp_t; } Pathcomp_t;
#ifndef ARG_RAW #ifndef ARG_RAW
@ -71,38 +70,42 @@ typedef struct pathcomp
#endif /* !ARG_RAW */ #endif /* !ARG_RAW */
/* pathname handling routines */ /* pathname handling routines */
extern void path_newdir(Shell_t*,Pathcomp_t*); extern void path_newdir(Pathcomp_t*);
extern Pathcomp_t *path_dirfind(Pathcomp_t*,const char*,int); extern Pathcomp_t *path_dirfind(Pathcomp_t*,const char*,int);
extern Pathcomp_t *path_unsetfpath(Shell_t*); extern Pathcomp_t *path_unsetfpath(void);
extern Pathcomp_t *path_addpath(Shell_t*,Pathcomp_t*,const char*,int); extern Pathcomp_t *path_addpath(Pathcomp_t*,const char*,int);
extern Pathcomp_t *path_dup(Pathcomp_t*); extern Pathcomp_t *path_dup(Pathcomp_t*);
extern void path_delete(Pathcomp_t*); extern void path_delete(Pathcomp_t*);
extern void path_alias(Namval_t*,Pathcomp_t*); extern void path_alias(Namval_t*,Pathcomp_t*);
extern Pathcomp_t *path_absolute(Shell_t*, const char*, Pathcomp_t*, int); extern Pathcomp_t *path_absolute(const char*, Pathcomp_t*, int);
extern char *path_basename(const char*); extern char *path_basename(const char*);
extern char *path_fullname(Shell_t*,const char*); extern char *path_fullname(const char*);
extern int path_expand(Shell_t*,const char*, struct argnod**); extern int path_expand(const char*, struct argnod**);
extern noreturn void path_exec(Shell_t*,const char*,char*[],struct argnod*); extern noreturn void path_exec(const char*,char*[],struct argnod*);
extern pid_t path_spawn(Shell_t*,const char*,char*[],char*[],Pathcomp_t*,int); extern pid_t path_spawn(const char*,char*[],char*[],Pathcomp_t*,int);
#if defined(__EXPORT__) && defined(_BLD_DLL) #if defined(__EXPORT__) && defined(_BLD_DLL)
# define extern __EXPORT__ # define extern __EXPORT__
#endif #endif
extern int path_open(Shell_t*,const char*,Pathcomp_t*); extern int path_open(const char*,Pathcomp_t*);
extern Pathcomp_t *path_get(Shell_t*,const char*); extern Pathcomp_t *path_get(const char*);
#undef extern #undef extern
extern char *path_pwd(Shell_t*,int); extern char *path_pwd(void);
extern Pathcomp_t *path_nextcomp(Shell_t*,Pathcomp_t*,const char*,Pathcomp_t*); extern Pathcomp_t *path_nextcomp(Pathcomp_t*,const char*,Pathcomp_t*);
extern int path_search(Shell_t*,const char*,Pathcomp_t**,int); extern int path_search(const char*,Pathcomp_t**,int);
extern char *path_relative(Shell_t*,const char*); extern char *path_relative(const char*);
extern int path_complete(Shell_t*,const char*, const char*,struct argnod**); extern int path_complete(const char*, const char*,struct argnod**);
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
extern int path_generate(Shell_t*,struct argnod*,struct argnod**); extern int path_generate(struct argnod*,struct argnod**);
#endif /* SHOPT_BRACEPAT */ #endif /* SHOPT_BRACEPAT */
extern int path_xattr(Shell_t*, const char*, char*); #if SHOPT_PFSH
extern int path_xattr(const char*, char*);
#endif /* SHOPT_PFSH */
#if SHOPT_DYNAMIC
/* builtin/plugin routines */ /* builtin/plugin routines */
extern int sh_addlib(Shell_t*,void*,char*,Pathcomp_t*); extern int sh_addlib(void*,char*,Pathcomp_t*);
extern Shbltin_f sh_getlib(Shell_t*,char*,Pathcomp_t*); extern Shbltin_f sh_getlib(char*,Pathcomp_t*);
#endif /* SHOPT_DYNAMIC */
/* constant strings needed for whence */ /* constant strings needed for whence */
extern const char e_timeformat[]; extern const char e_timeformat[];

View file

@ -52,7 +52,7 @@ typedef struct Regress_s
#define SHOPT_P_SUID sh_regress_p_suid(__LINE__, __FILE__) #define SHOPT_P_SUID sh_regress_p_suid(__LINE__, __FILE__)
extern int b___regress__(int, char**, Shbltin_t*); extern int b___regress__(int, char**, Shbltin_t*);
extern void sh_regress_init(Shell_t*); extern void sh_regress_init(void);
extern void sh_regress(unsigned int, const char*, const char*, unsigned int, const char*); extern void sh_regress(unsigned int, const char*, const char*, unsigned int, const char*);
extern uid_t sh_regress_p_suid(unsigned int, const char*); extern uid_t sh_regress_p_suid(unsigned int, const char*);
extern char* sh_regress_etc(const char*, unsigned int, const char*); extern char* sh_regress_etc(const char*, unsigned int, const char*);

View file

@ -28,7 +28,7 @@
* *
*/ */
#define SH_VERSION 20211229 #define SH_VERSION 20220106
#include <ast.h> #include <ast.h>
#include <cdt.h> #include <cdt.h>
@ -226,13 +226,11 @@ struct Shell_s
Dt_t *fun_tree; /* for shell functions */ Dt_t *fun_tree; /* for shell functions */
Dt_t *alias_tree; /* for alias names */ Dt_t *alias_tree; /* for alias names */
Dt_t *bltin_tree; /* for builtin commands */ Dt_t *bltin_tree; /* for builtin commands */
Dt_t *track_tree; /* for tracked aliases */
Shscope_t *topscope; /* pointer to top-level scope */ Shscope_t *topscope; /* pointer to top-level scope */
int inlineno; /* line number of current input file */ int inlineno; /* line number of current input file */
int exitval; /* exit status of the command currently being run */ int exitval; /* exit status of the command currently being run */
int savexit; /* $? == exit status of the last command executed */ int savexit; /* $? == exit status of the last command executed */
unsigned char trapnote; /* set when trap/signal is pending */
char shcomp; /* set when running shcomp */
unsigned int subshell; /* set for virtual subshell */
/* These are the former 'struct shared' (shgd) members. */ /* These are the former 'struct shared' (shgd) members. */
struct limits lim; struct limits lim;
@ -243,7 +241,6 @@ struct Shell_s
pid_t pid; /* $$, the main shell's PID (invariable) */ pid_t pid; /* $$, the main shell's PID (invariable) */
pid_t ppid; /* $PPID, the main shell's parent's PID */ pid_t ppid; /* $PPID, the main shell's parent's PID */
pid_t current_pid; /* ${.sh.pid}, PID of current ksh process (updates when subshell forks) */ pid_t current_pid; /* ${.sh.pid}, PID of current ksh process (updates when subshell forks) */
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
unsigned char sigruntime[2]; unsigned char sigruntime[2];
Namval_t *bltin_nodes; Namval_t *bltin_nodes;
Namval_t *bltin_cmds; Namval_t *bltin_cmds;
@ -253,13 +250,18 @@ struct Shell_s
char **sigmsg; char **sigmsg;
char **login_files; char **login_files;
void *ed_context; void *ed_context;
int *stats;
int sigmax; int sigmax;
Shwait_f waitevent; Shwait_f waitevent;
#if SHOPT_STATS
int *stats;
#endif
/* These are the members formerly defined via the _SH_PRIVATE macro. /* The following members are not considered to be part of the documented API.
* Programs using libshell should not rely on them as they may change. */ * Programs using libshell should not rely on them as they may change. */
Shell_t *gd; /* pointer to self for backwards compatibility (was: global data) */ int subshell; /* set for virtual subshell */
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
char shcomp; /* set when running shcomp */
unsigned char trapnote; /* set when trap/signal is pending */
struct sh_scoped st; /* scoped information */ struct sh_scoped st; /* scoped information */
Stk_t *stk; /* stack pointer */ Stk_t *stk; /* stack pointer */
Sfio_t *heredocs; /* current here-doc temp file */ Sfio_t *heredocs; /* current here-doc temp file */
@ -268,7 +270,6 @@ struct Shell_s
char *lastarg; char *lastarg;
char *lastpath; /* last absolute path found */ char *lastpath; /* last absolute path found */
int path_err; /* last error on path search */ int path_err; /* last error on path search */
Dt_t *track_tree; /* for tracked aliases */
Dt_t *var_base; /* global level variables */ Dt_t *var_base; /* global level variables */
Dt_t *fun_base; /* global level functions */ Dt_t *fun_base; /* global level functions */
Dt_t *openmatch; Dt_t *openmatch;
@ -414,13 +415,12 @@ extern Libcomp_t *liblist;
# define extern __EXPORT__ # define extern __EXPORT__
#endif /* _DLL */ #endif /* _DLL */
extern Dt_t *sh_bltin_tree(void);
extern void sh_subfork(void); extern void sh_subfork(void);
extern Shell_t *sh_init(int,char*[],Shinit_f); extern Shell_t *sh_init(int,char*[],Shinit_f);
extern int sh_reinit(char*[]); extern int sh_reinit(char*[]);
extern int sh_eval(Sfio_t*,int); extern int sh_eval(Sfio_t*,int);
extern void sh_delay(double,int); extern void sh_delay(double,int);
extern void *sh_parse(Shell_t*, Sfio_t*,int); extern void *sh_parse(Sfio_t*,int);
extern int sh_trap(const char*,int); extern int sh_trap(const char*,int);
extern int sh_fun(Namval_t*,Namval_t*, char*[]); extern int sh_fun(Namval_t*,Namval_t*, char*[]);
extern int sh_funscope(int,char*[],int(*)(void*),void*,int); extern int sh_funscope(int,char*[],int(*)(void*),void*,int);
@ -452,7 +452,7 @@ extern mode_t sh_umask(mode_t);
extern void *sh_waitnotify(Shwait_f); extern void *sh_waitnotify(Shwait_f);
extern Shscope_t *sh_getscope(int,int); extern Shscope_t *sh_getscope(int,int);
extern Shscope_t *sh_setscope(Shscope_t*); extern Shscope_t *sh_setscope(Shscope_t*);
extern void sh_sigcheck(Shell_t*); extern void sh_sigcheck(void);
extern unsigned long sh_isoption(int); extern unsigned long sh_isoption(int);
extern unsigned long sh_onoption(int); extern unsigned long sh_onoption(int);
extern unsigned long sh_offoption(int); extern unsigned long sh_offoption(int);
@ -462,12 +462,10 @@ extern int sh_exec(const Shnode_t*,int);
/* /*
* As of 93u+m, direct access to sh is no longer obsolete, and * As of 93u+m, direct access to sh is no longer obsolete, and
* shgd ("global data") is no longer a separately allocated struct; * shgd ("global data") is no longer a separately allocated struct;
* sh_getinterp() and shgd are provided here for compatibility. * sh_getinterp() is here for compatibility with the documented interface.
*/ */
extern Shell_t sh; extern Shell_t sh;
extern Shell_t *sh_getinterp(void); /* for libshell ABI compatibility */
#define sh_getinterp() (&sh) #define sh_getinterp() (&sh)
#define shgd (&sh)
#ifdef _DLL #ifdef _DLL
# undef extern # undef extern

View file

@ -75,7 +75,6 @@ struct _shlex_pvt_lexdata_
*/ */
typedef struct _shlex_ typedef struct _shlex_
{ {
Shell_t *sh; /* pointer to the interpreter */
struct argnod *arg; /* current word */ struct argnod *arg; /* current word */
struct ionod *heredoc; /* pending here document list */ struct ionod *heredoc; /* pending here document list */
int token; /* current token number */ int token; /* current token number */
@ -187,7 +186,7 @@ extern const char e_newline[];
extern int sh_lex(Lex_t*); extern int sh_lex(Lex_t*);
extern Shnode_t *sh_dolparen(Lex_t*); extern Shnode_t *sh_dolparen(Lex_t*);
extern Lex_t *sh_lexopen(Lex_t*, Shell_t*, int); extern Lex_t *sh_lexopen(Lex_t*, int);
extern void sh_lexskip(Lex_t*,int,int,int); extern void sh_lexskip(Lex_t*,int,int,int);
extern noreturn void sh_syntax(Lex_t*); extern noreturn void sh_syntax(Lex_t*);
#if SHOPT_KIA #if SHOPT_KIA

View file

@ -209,13 +209,13 @@ union Shnode_u
struct arithnod ar; struct arithnod ar;
}; };
extern void sh_freeup(Shell_t*); extern void sh_freeup(void);
extern void sh_funstaks(struct slnod*,int); extern void sh_funstaks(struct slnod*,int);
extern Sfio_t *sh_subshell(Shell_t*,Shnode_t*, volatile int, int); extern Sfio_t *sh_subshell(Shnode_t*, volatile int, int);
#if defined(__EXPORT__) && defined(_BLD_DLL) #if defined(__EXPORT__) && defined(_BLD_DLL)
__EXPORT__ __EXPORT__
#endif #endif
extern int sh_tdump(Sfio_t*, const Shnode_t*); extern int sh_tdump(Sfio_t*, const Shnode_t*);
extern Shnode_t *sh_trestore(Shell_t*, Sfio_t*); extern Shnode_t *sh_trestore(Sfio_t*);
#endif /* _SHNODES_H */ #endif /* _SHNODES_H */

View file

@ -61,6 +61,6 @@ extern const struct shtable3 shtab_builtins[];
extern const Shtable_t shtab_reserved[]; extern const Shtable_t shtab_reserved[];
extern const Shtable_t *sh_locate(const char*, const Shtable_t*, int); extern const Shtable_t *sh_locate(const char*, const Shtable_t*, int);
extern int sh_lookopt(const char*, int*); extern int sh_lookopt(const char*, int*);
extern Dt_t *sh_inittree(Shell_t*, const struct shtable2*); extern Dt_t *sh_inittree(const struct shtable2*);
#endif /* SH_TABLE_H */ #endif /* SH_TABLE_H */

View file

@ -68,7 +68,6 @@
struct lval struct lval
{ {
Shell_t *shp;
char *value; char *value;
char *ovalue; char *ovalue;
Sfdouble_t (*fun)(Sfdouble_t,...); Sfdouble_t (*fun)(Sfdouble_t,...);
@ -93,7 +92,6 @@ struct mathtab
typedef struct _arith_ typedef struct _arith_
{ {
Shell_t *shp;
unsigned char *code; unsigned char *code;
const char *expr; const char *expr;
Sfdouble_t (*fun)(const char**,struct lval*,int,Sfdouble_t); Sfdouble_t (*fun)(const char**,struct lval*,int,Sfdouble_t);
@ -199,7 +197,7 @@ extern const struct mathtab shtab_math[];
#define VALUE 2 #define VALUE 2
#define MESSAGE 3 #define MESSAGE 3
extern Sfdouble_t strval(Shell_t*,const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int); extern Sfdouble_t arith_strval(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int);
extern Arith_t *arith_compile(Shell_t *,const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int); extern Arith_t *arith_compile(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int);
extern Sfdouble_t arith_exec(Arith_t*); extern Sfdouble_t arith_exec(Arith_t*);
#endif /* !SEQPOINT */ #endif /* !SEQPOINT */

View file

@ -57,9 +57,9 @@
#define TEST_SGT 17 #define TEST_SGT 17
#define TEST_REP 20 #define TEST_REP 20
extern int test_unop(Shell_t*,int, const char*); extern int test_unop(int, const char*);
extern int test_inode(const char*, const char*); extern int test_inode(const char*, const char*);
extern int test_binop(Shell_t*,int, const char*, const char*); extern int test_binop(int, const char*, const char*);
extern const char sh_opttest[]; extern const char sh_opttest[];
extern const char test_opchars[]; extern const char test_opchars[];

View file

@ -38,72 +38,72 @@ extern void sh_save_rand_seed(struct rand *, int);
/* The following defines must be kept synchronous with shtab_variables[] in data/variables.c */ /* The following defines must be kept synchronous with shtab_variables[] in data/variables.c */
#define PATHNOD (shgd->bltin_nodes) #define PATHNOD (sh.bltin_nodes)
#define PS1NOD (shgd->bltin_nodes+1) #define PS1NOD (sh.bltin_nodes+1)
#define PS2NOD (shgd->bltin_nodes+2) #define PS2NOD (sh.bltin_nodes+2)
#define IFSNOD (shgd->bltin_nodes+3) #define IFSNOD (sh.bltin_nodes+3)
#define PWDNOD (shgd->bltin_nodes+4) #define PWDNOD (sh.bltin_nodes+4)
#define HOME (shgd->bltin_nodes+5) #define HOME (sh.bltin_nodes+5)
#define MAILNOD (shgd->bltin_nodes+6) #define MAILNOD (sh.bltin_nodes+6)
#define REPLYNOD (shgd->bltin_nodes+7) #define REPLYNOD (sh.bltin_nodes+7)
#define SHELLNOD (shgd->bltin_nodes+8) #define SHELLNOD (sh.bltin_nodes+8)
#define EDITNOD (shgd->bltin_nodes+9) #define EDITNOD (sh.bltin_nodes+9)
#define MCHKNOD (shgd->bltin_nodes+10) #define MCHKNOD (sh.bltin_nodes+10)
#define RANDNOD (shgd->bltin_nodes+11) #define RANDNOD (sh.bltin_nodes+11)
#define ENVNOD (shgd->bltin_nodes+12) #define ENVNOD (sh.bltin_nodes+12)
#define HISTFILE (shgd->bltin_nodes+13) #define HISTFILE (sh.bltin_nodes+13)
#define HISTSIZE (shgd->bltin_nodes+14) #define HISTSIZE (sh.bltin_nodes+14)
#define HISTEDIT (shgd->bltin_nodes+15) #define HISTEDIT (sh.bltin_nodes+15)
#define HISTCUR (shgd->bltin_nodes+16) #define HISTCUR (sh.bltin_nodes+16)
#define FCEDNOD (shgd->bltin_nodes+17) #define FCEDNOD (sh.bltin_nodes+17)
#define CDPNOD (shgd->bltin_nodes+18) #define CDPNOD (sh.bltin_nodes+18)
#define MAILPNOD (shgd->bltin_nodes+19) #define MAILPNOD (sh.bltin_nodes+19)
#define PS3NOD (shgd->bltin_nodes+20) #define PS3NOD (sh.bltin_nodes+20)
#define OLDPWDNOD (shgd->bltin_nodes+21) #define OLDPWDNOD (sh.bltin_nodes+21)
#define VISINOD (shgd->bltin_nodes+22) #define VISINOD (sh.bltin_nodes+22)
#define COLUMNS (shgd->bltin_nodes+23) #define COLUMNS (sh.bltin_nodes+23)
#define LINES (shgd->bltin_nodes+24) #define LINES (sh.bltin_nodes+24)
#define PPIDNOD (shgd->bltin_nodes+25) #define PPIDNOD (sh.bltin_nodes+25)
#define L_ARGNOD (shgd->bltin_nodes+26) #define L_ARGNOD (sh.bltin_nodes+26)
#define TMOUTNOD (shgd->bltin_nodes+27) #define TMOUTNOD (sh.bltin_nodes+27)
#define SECONDS (shgd->bltin_nodes+28) #define SECONDS (sh.bltin_nodes+28)
#define LINENO (shgd->bltin_nodes+29) #define LINENO (sh.bltin_nodes+29)
#define OPTARGNOD (shgd->bltin_nodes+30) #define OPTARGNOD (sh.bltin_nodes+30)
#define OPTINDNOD (shgd->bltin_nodes+31) #define OPTINDNOD (sh.bltin_nodes+31)
#define PS4NOD (shgd->bltin_nodes+32) #define PS4NOD (sh.bltin_nodes+32)
#define FPATHNOD (shgd->bltin_nodes+33) #define FPATHNOD (sh.bltin_nodes+33)
#define LANGNOD (shgd->bltin_nodes+34) #define LANGNOD (sh.bltin_nodes+34)
#define LCALLNOD (shgd->bltin_nodes+35) #define LCALLNOD (sh.bltin_nodes+35)
#define LCCOLLNOD (shgd->bltin_nodes+36) #define LCCOLLNOD (sh.bltin_nodes+36)
#define LCTYPENOD (shgd->bltin_nodes+37) #define LCTYPENOD (sh.bltin_nodes+37)
#define LCMSGNOD (shgd->bltin_nodes+38) #define LCMSGNOD (sh.bltin_nodes+38)
#define LCNUMNOD (shgd->bltin_nodes+39) #define LCNUMNOD (sh.bltin_nodes+39)
#define LCTIMENOD (shgd->bltin_nodes+40) #define LCTIMENOD (sh.bltin_nodes+40)
#define FIGNORENOD (shgd->bltin_nodes+41) #define FIGNORENOD (sh.bltin_nodes+41)
#define VERSIONNOD (shgd->bltin_nodes+42) #define VERSIONNOD (sh.bltin_nodes+42)
#define JOBMAXNOD (shgd->bltin_nodes+43) #define JOBMAXNOD (sh.bltin_nodes+43)
#define DOTSHNOD (shgd->bltin_nodes+44) #define DOTSHNOD (sh.bltin_nodes+44)
#define ED_CHRNOD (shgd->bltin_nodes+45) #define ED_CHRNOD (sh.bltin_nodes+45)
#define ED_COLNOD (shgd->bltin_nodes+46) #define ED_COLNOD (sh.bltin_nodes+46)
#define ED_TXTNOD (shgd->bltin_nodes+47) #define ED_TXTNOD (sh.bltin_nodes+47)
#define ED_MODENOD (shgd->bltin_nodes+48) #define ED_MODENOD (sh.bltin_nodes+48)
#define SH_NAMENOD (shgd->bltin_nodes+49) #define SH_NAMENOD (sh.bltin_nodes+49)
#define SH_SUBSCRNOD (shgd->bltin_nodes+50) #define SH_SUBSCRNOD (sh.bltin_nodes+50)
#define SH_VALNOD (shgd->bltin_nodes+51) #define SH_VALNOD (sh.bltin_nodes+51)
#define SH_VERSIONNOD (shgd->bltin_nodes+52) #define SH_VERSIONNOD (sh.bltin_nodes+52)
#define SH_DOLLARNOD (shgd->bltin_nodes+53) #define SH_DOLLARNOD (sh.bltin_nodes+53)
#define SH_MATCHNOD (shgd->bltin_nodes+54) #define SH_MATCHNOD (sh.bltin_nodes+54)
#define SH_COMMANDNOD (shgd->bltin_nodes+55) #define SH_COMMANDNOD (sh.bltin_nodes+55)
#define SH_PATHNAMENOD (shgd->bltin_nodes+56) #define SH_PATHNAMENOD (sh.bltin_nodes+56)
#define SH_FUNNAMENOD (shgd->bltin_nodes+57) #define SH_FUNNAMENOD (sh.bltin_nodes+57)
#define SH_SUBSHELLNOD (shgd->bltin_nodes+58) #define SH_SUBSHELLNOD (sh.bltin_nodes+58)
#define SH_LEVELNOD (shgd->bltin_nodes+59) #define SH_LEVELNOD (sh.bltin_nodes+59)
#define SH_LINENO (shgd->bltin_nodes+60) #define SH_LINENO (sh.bltin_nodes+60)
#define SH_STATS (shgd->bltin_nodes+61) #define SH_STATS (sh.bltin_nodes+61)
#define SH_MATHNOD (shgd->bltin_nodes+62) #define SH_MATHNOD (sh.bltin_nodes+62)
#define SH_JOBPOOL (shgd->bltin_nodes+63) #define SH_JOBPOOL (sh.bltin_nodes+63)
#define SH_PIDNOD (shgd->bltin_nodes+64) #define SH_PIDNOD (sh.bltin_nodes+64)
#define SH_TILDENOD (shgd->bltin_nodes+65) #define SH_TILDENOD (sh.bltin_nodes+65)
#define SHLVL (shgd->bltin_nodes+66) #define SHLVL (sh.bltin_nodes+66)
#endif /* SH_VALNOD */ #endif /* SH_VALNOD */

View file

@ -83,7 +83,6 @@ static const int flagval[] =
typedef struct _arg_ typedef struct _arg_
{ {
Shell_t *sh;
struct dolnod *argfor; /* linked list of blocks to be cleaned up */ struct dolnod *argfor; /* linked list of blocks to be cleaned up */
struct dolnod *dolh; struct dolnod *dolh;
char flagadr[NUM_OPTS+1]; char flagadr[NUM_OPTS+1];
@ -92,18 +91,16 @@ typedef struct _arg_
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
} Arg_t; } Arg_t;
static int arg_expand(Shell_t*,struct argnod*,struct argnod**,int); static int arg_expand(struct argnod*,struct argnod**,int);
static void sh_argset(Arg_t*, char *[]); static void argset(Arg_t*, char *[]);
static void applyopts(Shopt_t);
/* ======== option handling ======== */ /* ======== option handling ======== */
void *sh_argopen(Shell_t *shp) void *sh_argopen(void)
{ {
void *addr = sh_newof(0,Arg_t,1,0); return(sh_newof(0,Arg_t,1,0));
Arg_t *ap = (Arg_t*)addr;
ap->sh = shp;
return(addr);
} }
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp) static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
@ -119,13 +116,12 @@ static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
* The -o option is used to set option by name * The -o option is used to set option by name
* This routine returns the number of non-option arguments * This routine returns the number of non-option arguments
*/ */
int sh_argopts(int argc,register char *argv[], void *context) int sh_argopts(int argc,register char *argv[])
{ {
Shell_t *shp = (Shell_t*)context;
register int n,o; register int n,o;
register Arg_t *ap = (Arg_t*)(shp->arg_context); register Arg_t *ap = (Arg_t*)(sh.arg_context);
#if SHOPT_KIA #if SHOPT_KIA
Lex_t *lp = (Lex_t*)(shp->lex_context); Lex_t *lp = (Lex_t*)(sh.lex_context);
#endif #endif
Shopt_t newflags; Shopt_t newflags;
int defaultflag=0, setflag=0, action=0, trace=(int)sh_isoption(SH_XTRACE); int defaultflag=0, setflag=0, action=0, trace=(int)sh_isoption(SH_XTRACE);
@ -133,7 +129,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
const char *cp; const char *cp;
int verbose,f; int verbose,f;
Optdisc_t disc; Optdisc_t disc;
newflags=ap->sh->options; newflags=sh.options;
memset(&disc, 0, sizeof(disc)); memset(&disc, 0, sizeof(disc));
disc.version = OPT_VERSION; disc.version = OPT_VERSION;
disc.infof = infof; disc.infof = infof;
@ -150,7 +146,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
switch(n) switch(n)
{ {
case 'A': case 'A':
np = nv_open(opt_info.arg,ap->sh->var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME); np = nv_open(opt_info.arg,sh.var_tree,NV_NOASSIGN|NV_ARRAY|NV_VARNAME);
if(f) if(f)
nv_unset(np); nv_unset(np);
continue; continue;
@ -193,9 +189,9 @@ int sh_argopts(int argc,register char *argv[], void *context)
goto skip; goto skip;
case 'T': case 'T':
if (opt_info.num) if (opt_info.num)
ap->sh->test |= opt_info.num; sh.test |= opt_info.num;
else else
ap->sh->test = 0; sh.test = 0;
continue; continue;
case 's': case 's':
if(setflag) if(setflag)
@ -263,7 +259,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
on_option(&newflags,SH_LETOCTAL); on_option(&newflags,SH_LETOCTAL);
} }
on_option(&newflags,o); on_option(&newflags,o);
off_option(&ap->sh->offoptions,o); off_option(&sh.offoptions,o);
} }
else else
{ {
@ -283,7 +279,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
trace = 0; trace = 0;
off_option(&newflags,o); off_option(&newflags,o);
if(setflag==0) if(setflag==0)
on_option(&ap->sh->offoptions,o); on_option(&sh.offoptions,o);
} }
} }
if(error_info.errors) if(error_info.errors)
@ -301,7 +297,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
trace = 0; trace = 0;
} }
if(trace) if(trace)
sh_trace(shp,argv,1); sh_trace(argv,1);
argc -= opt_info.index; argc -= opt_info.index;
argv += opt_info.index; argv += opt_info.index;
if(action==PRINT) if(action==PRINT)
@ -313,7 +309,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
if(argc>0) if(argc>0)
strsort(argv,argc,strcoll); strsort(argv,argc,strcoll);
else else
strsort(ap->sh->st.dolv+1,ap->sh->st.dolc,strcoll); strsort(sh.st.dolv+1,sh.st.dolc,strcoll);
} }
if(np) if(np)
{ {
@ -321,11 +317,11 @@ int sh_argopts(int argc,register char *argv[], void *context)
nv_close(np); nv_close(np);
} }
else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0)) else if(argc>0 || ((cp=argv[-1]) && strcmp(cp,"--")==0))
sh_argset(ap,argv-1); argset(ap,argv-1);
} }
else if(is_option(&newflags,SH_CFLAG)) else if(is_option(&newflags,SH_CFLAG))
{ {
if(!(ap->sh->comdiv = *argv++)) if(!(sh.comdiv = *argv++))
{ {
errormsg(SH_DICT,2,e_cneedsarg); errormsg(SH_DICT,2,e_cneedsarg);
errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*))); errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
@ -333,8 +329,8 @@ int sh_argopts(int argc,register char *argv[], void *context)
} }
argc--; argc--;
} }
/* SH_INTERACTIVE and SH_PRIVILEGED are handled in sh_applyopts() */ /* SH_INTERACTIVE and SH_PRIVILEGED are handled in applyopts() */
sh_applyopts(ap->sh,newflags); applyopts(newflags);
#if SHOPT_KIA #if SHOPT_KIA
if(ap->kiafile) if(ap->kiafile)
{ {
@ -370,28 +366,29 @@ int sh_argopts(int argc,register char *argv[], void *context)
/* apply new options */ /* apply new options */
void sh_applyopts(Shell_t* shp,Shopt_t newflags) static void applyopts(Shopt_t newflags)
{ {
/* cannot set -n for interactive shells since there is no way out */ /* cannot set -n for interactive shells since there is no way out */
if(sh_isoption(SH_INTERACTIVE)) if(sh_isoption(SH_INTERACTIVE))
off_option(&newflags,SH_NOEXEC); off_option(&newflags,SH_NOEXEC);
if(is_option(&newflags,SH_PRIVILEGED)) if(is_option(&newflags,SH_PRIVILEGED))
on_option(&newflags,SH_NOUSRPROFILE); on_option(&newflags,SH_NOUSRPROFILE);
if(!sh_isstate(SH_INIT) && is_option(&newflags,SH_PRIVILEGED) != sh_isoption(SH_PRIVILEGED) || sh_isstate(SH_INIT) && is_option(&((Arg_t*)shp->arg_context)->sh->offoptions,SH_PRIVILEGED) && shp->gd->userid!=shp->gd->euserid) if(!sh_isstate(SH_INIT) && is_option(&newflags,SH_PRIVILEGED) != sh_isoption(SH_PRIVILEGED)
|| sh_isstate(SH_INIT) && is_option(&sh.offoptions,SH_PRIVILEGED) && sh.userid!=sh.euserid)
{ {
if(!is_option(&newflags,SH_PRIVILEGED)) if(!is_option(&newflags,SH_PRIVILEGED))
{ {
setuid(shp->gd->userid); setuid(sh.userid);
setgid(shp->gd->groupid); setgid(sh.groupid);
if(shp->gd->euserid==0) if(sh.euserid==0)
{ {
shp->gd->euserid = shp->gd->userid; sh.euserid = sh.userid;
shp->gd->egroupid = shp->gd->groupid; sh.egroupid = sh.groupid;
} }
} }
else if((shp->gd->userid!=shp->gd->euserid && setuid(shp->gd->euserid)<0) || else if((sh.userid!=sh.euserid && setuid(sh.euserid)<0) ||
(shp->gd->groupid!=shp->gd->egroupid && setgid(shp->gd->egroupid)<0) || (sh.groupid!=sh.egroupid && setgid(sh.egroupid)<0) ||
(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid)) (sh.userid==sh.euserid && sh.groupid==sh.egroupid))
off_option(&newflags,SH_PRIVILEGED); off_option(&newflags,SH_PRIVILEGED);
} }
/* sync monitor (part of job control) state with -o monitor option change */ /* sync monitor (part of job control) state with -o monitor option change */
@ -399,7 +396,7 @@ void sh_applyopts(Shell_t* shp,Shopt_t newflags)
sh_onstate(SH_MONITOR); sh_onstate(SH_MONITOR);
else if(sh_isoption(SH_MONITOR) && !is_option(&newflags,SH_MONITOR)) else if(sh_isoption(SH_MONITOR) && !is_option(&newflags,SH_MONITOR))
sh_offstate(SH_MONITOR); sh_offstate(SH_MONITOR);
shp->options = newflags; sh.options = newflags;
} }
/* /*
@ -424,15 +421,15 @@ char *sh_argdolminus(void* context)
/* /*
* set up positional parameters * set up positional parameters
*/ */
static void sh_argset(Arg_t *ap,char *argv[]) static void argset(Arg_t *ap,char *argv[])
{ {
sh_argfree(ap->sh,ap->dolh,0); sh_argfree(ap->dolh,0);
ap->dolh = sh_argcreate(argv); ap->dolh = sh_argcreate(argv);
/* link into chain */ /* link into chain */
ap->dolh->dolnxt = ap->argfor; ap->dolh->dolnxt = ap->argfor;
ap->argfor = ap->dolh; ap->argfor = ap->dolh;
ap->sh->st.dolc = ap->dolh->dolnum-1; sh.st.dolc = ap->dolh->dolnum-1;
ap->sh->st.dolv = ap->dolh->dolval; sh.st.dolv = ap->dolh->dolval;
} }
/* /*
@ -442,11 +439,11 @@ static void sh_argset(Arg_t *ap,char *argv[])
* Delete the blk from the argfor chain * Delete the blk from the argfor chain
* If flag is set, then the block dolh is not freed * If flag is set, then the block dolh is not freed
*/ */
struct dolnod *sh_argfree(Shell_t *shp, struct dolnod *blk,int flag) struct dolnod *sh_argfree(struct dolnod *blk,int flag)
{ {
register struct dolnod* argr=blk; register struct dolnod* argr=blk;
register struct dolnod* argblk; register struct dolnod* argblk;
register Arg_t *ap = (Arg_t*)shp->arg_context; register Arg_t *ap = (Arg_t*)sh.arg_context;
if(argblk=argr) if(argblk=argr)
{ {
if((--argblk->dolrefcnt)==0) if((--argblk->dolrefcnt)==0)
@ -507,39 +504,39 @@ struct dolnod *sh_argcreate(register char *argv[])
/* /*
* used to set new arguments for functions * used to set new arguments for functions
*/ */
struct dolnod *sh_argnew(Shell_t *shp,char *argi[], struct dolnod **savargfor) struct dolnod *sh_argnew(char *argi[], struct dolnod **savargfor)
{ {
register Arg_t *ap = (Arg_t*)shp->arg_context; register Arg_t *ap = (Arg_t*)sh.arg_context;
register struct dolnod *olddolh = ap->dolh; register struct dolnod *olddolh = ap->dolh;
*savargfor = ap->argfor; *savargfor = ap->argfor;
ap->dolh = 0; ap->dolh = 0;
ap->argfor = 0; ap->argfor = 0;
sh_argset(ap,argi); argset(ap,argi);
return(olddolh); return(olddolh);
} }
/* /*
* reset arguments as they were before function * reset arguments as they were before function
*/ */
void sh_argreset(Shell_t *shp,struct dolnod *blk, struct dolnod *afor) void sh_argreset(struct dolnod *blk, struct dolnod *afor)
{ {
register Arg_t *ap = (Arg_t*)shp->arg_context; register Arg_t *ap = (Arg_t*)sh.arg_context;
while(ap->argfor=sh_argfree(shp,ap->argfor,0)); while(ap->argfor=sh_argfree(ap->argfor,0));
ap->argfor = afor; ap->argfor = afor;
if(ap->dolh = blk) if(ap->dolh = blk)
{ {
shp->st.dolc = ap->dolh->dolnum-1; sh.st.dolc = ap->dolh->dolnum-1;
shp->st.dolv = ap->dolh->dolval; sh.st.dolv = ap->dolh->dolval;
} }
} }
/* /*
* increase the use count so that an sh_argset will not make it go away * increase the use count so that an argset will not make it go away
*/ */
struct dolnod *sh_arguse(Shell_t* shp) struct dolnod *sh_arguse(void)
{ {
register struct dolnod *dh; register struct dolnod *dh;
register Arg_t *ap = (Arg_t*)shp->arg_context; register Arg_t *ap = (Arg_t*)sh.arg_context;
if(dh=ap->dolh) if(dh=ap->dolh)
dh->dolrefcnt++; dh->dolrefcnt++;
return(dh); return(dh);
@ -639,11 +636,11 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
/* /*
* build an argument list * build an argument list
*/ */
char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag) char **sh_argbuild(int *nargs, const struct comnod *comptr,int flag)
{ {
register struct argnod *argp=0; register struct argnod *argp=0;
struct argnod *arghead=0; struct argnod *arghead=0;
shp->xargmin = 0; sh.xargmin = 0;
{ {
register const struct comnod *ac = comptr; register const struct comnod *ac = comptr;
register int n; register int n;
@ -659,19 +656,19 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
*nargs = ap->dolnum; *nargs = ap->dolnum;
return(ap->dolval+ap->dolbot); return(ap->dolval+ap->dolbot);
} }
shp->lastpath = 0; sh.lastpath = 0;
*nargs = 0; *nargs = 0;
if(ac) if(ac)
{ {
argp = ac->comarg; argp = ac->comarg;
while(argp) while(argp)
{ {
n = arg_expand(shp,argp,&arghead,flag); n = arg_expand(argp,&arghead,flag);
if(n>1) if(n>1)
{ {
if(shp->xargmin==0) if(sh.xargmin==0)
shp->xargmin = *nargs; sh.xargmin = *nargs;
shp->xargmax = *nargs+n; sh.xargmax = *nargs+n;
} }
*nargs += n; *nargs += n;
argp = argp->argnxt.ap; argp = argp->argnxt.ap;
@ -687,7 +684,7 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
/* allow room to prepend args */ /* allow room to prepend args */
argn += 1; argn += 1;
comargn=(char**)stkalloc(shp->stk,(unsigned)(argn+1)*sizeof(char*)); comargn=(char**)stkalloc(sh.stk,(unsigned)(argn+1)*sizeof(char*));
comargm = comargn += argn; comargm = comargn += argn;
*comargn = NIL(char*); *comargn = NIL(char*);
if(!argp) if(!argp)
@ -710,7 +707,7 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
comargm = comargn; comargm = comargn;
} }
} }
shp->last_table = 0; sh.last_table = 0;
return(comargn); return(comargn);
} }
} }
@ -719,83 +716,83 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
# define sh_pipe(a) sh_rpipe(a) # define sh_pipe(a) sh_rpipe(a)
#endif #endif
struct argnod *sh_argprocsub(Shell_t *shp,struct argnod *argp) struct argnod *sh_argprocsub(struct argnod *argp)
{ {
/* argument of the form <(cmd) or >(cmd) */ /* argument of the form <(cmd) or >(cmd) */
register struct argnod *ap; register struct argnod *ap;
int fd, pv[3]; int fd, pv[3];
int savestates = sh_getstate(); int savestates = sh_getstate();
char savejobcontrol = job.jobcontrol; char savejobcontrol = job.jobcontrol;
unsigned int savesubshell = shp->subshell; unsigned int savesubshell = sh.subshell;
ap = (struct argnod*)stkseek(shp->stk,ARGVAL); ap = (struct argnod*)stkseek(sh.stk,ARGVAL);
ap->argflag |= ARG_MAKE; ap->argflag |= ARG_MAKE;
ap->argflag &= ~ARG_RAW; ap->argflag &= ~ARG_RAW;
fd = argp->argflag&ARG_RAW; fd = argp->argflag&ARG_RAW;
if(fd==0 && shp->subshell) if(fd==0 && sh.subshell)
sh_subtmpfile(shp); sh_subtmpfile();
#if SHOPT_DEVFD #if SHOPT_DEVFD
sfwrite(shp->stk,e_devfdNN,8); sfwrite(sh.stk,e_devfdNN,8);
pv[2] = 0; pv[2] = 0;
sh_pipe(pv); sh_pipe(pv);
#else #else
pv[0] = -1; pv[0] = -1;
while(shp->fifo = pathtemp(0,0,0,"ksh.fifo",0), shp->fifo && mkfifo(shp->fifo,0)<0) while(sh.fifo = pathtemp(0,0,0,"ksh.fifo",0), sh.fifo && mkfifo(sh.fifo,0)<0)
{ {
if(errno==EEXIST || errno==EACCES || errno==ENOENT || errno==ENOTDIR || errno==EROFS) if(errno==EEXIST || errno==EACCES || errno==ENOENT || errno==ENOTDIR || errno==EROFS)
continue; /* lost race (name conflict or tmp dir change); try again */ continue; /* lost race (name conflict or tmp dir change); try again */
shp->fifo = 0; sh.fifo = 0;
break; break;
} }
if(!shp->fifo) if(!sh.fifo)
{ {
errormsg(SH_DICT, ERROR_SYSTEM|ERROR_PANIC, "process substitution: FIFO creation failed"); errormsg(SH_DICT, ERROR_SYSTEM|ERROR_PANIC, "process substitution: FIFO creation failed");
UNREACHABLE(); UNREACHABLE();
} }
chmod(shp->fifo,S_IRUSR|S_IWUSR); /* mkfifo + chmod works regardless of umask */ chmod(sh.fifo,S_IRUSR|S_IWUSR); /* mkfifo + chmod works regardless of umask */
sfputr(shp->stk,shp->fifo,0); sfputr(sh.stk,sh.fifo,0);
#endif /* SHOPT_DEVFD */ #endif /* SHOPT_DEVFD */
sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0); sfputr(sh.stk,fmtbase((long)pv[fd],10,0),0);
ap = (struct argnod*)stkfreeze(shp->stk,0); ap = (struct argnod*)stkfreeze(sh.stk,0);
shp->inpipe = shp->outpipe = 0; sh.inpipe = sh.outpipe = 0;
/* turn off job control */ /* turn off job control */
sh_offstate(SH_INTERACTIVE); sh_offstate(SH_INTERACTIVE);
sh_offstate(SH_MONITOR); sh_offstate(SH_MONITOR);
sh_offstate(SH_PROFILE); sh_offstate(SH_PROFILE);
job.jobcontrol = 0; job.jobcontrol = 0;
/* run the process substitution */ /* run the process substitution */
shp->subshell = 0; sh.subshell = 0;
if(fd) if(fd)
shp->inpipe = pv; sh.inpipe = pv;
else else
shp->outpipe = pv; sh.outpipe = pv;
sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT)); sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT));
/* restore the previous state */ /* restore the previous state */
shp->subshell = savesubshell; sh.subshell = savesubshell;
job.jobcontrol = savejobcontrol; job.jobcontrol = savejobcontrol;
sh_setstate(savestates); sh_setstate(savestates);
#if SHOPT_DEVFD #if SHOPT_DEVFD
sh_close(pv[1-fd]); sh_close(pv[1-fd]);
sh_iosave(shp,-pv[fd], shp->topfd, (char*)0); sh_iosave(-pv[fd], sh.topfd, (char*)0);
#else #else
/* remember the FIFO for cleanup in case the command never opens it (see fifo_cleanup(), xec.c) */ /* remember the FIFO for cleanup in case the command never opens it (see fifo_cleanup(), xec.c) */
if(!shp->fifo_tree) if(!sh.fifo_tree)
shp->fifo_tree = dtopen(&_Nvdisc,Dtoset); sh.fifo_tree = dtopen(&_Nvdisc,Dtoset);
nv_search(shp->fifo,shp->fifo_tree,NV_ADD); nv_search(sh.fifo,sh.fifo_tree,NV_ADD);
free(shp->fifo); free(sh.fifo);
shp->fifo = 0; sh.fifo = 0;
#endif /* SHOPT_DEVFD */ #endif /* SHOPT_DEVFD */
return(ap); return(ap);
} }
/* Argument expansion */ /* Argument expansion */
static int arg_expand(Shell_t *shp,register struct argnod *argp, struct argnod **argchain,int flag) static int arg_expand(register struct argnod *argp, struct argnod **argchain,int flag)
{ {
register int count = 0; register int count = 0;
argp->argflag &= ~ARG_MAKE; argp->argflag &= ~ARG_MAKE;
if(*argp->argval==0 && (argp->argflag&ARG_EXP)) if(*argp->argval==0 && (argp->argflag&ARG_EXP))
{ {
struct argnod *ap; struct argnod *ap;
ap = sh_argprocsub(shp,argp); ap = sh_argprocsub(argp);
ap->argchn.ap = *argchain; ap->argchn.ap = *argchain;
*argchain = ap; *argchain = ap;
count++; count++;
@ -819,7 +816,7 @@ static int arg_expand(Shell_t *shp,register struct argnod *argp, struct argnod *
} }
else else
#endif /* SHOPT_OPTIMIZE */ #endif /* SHOPT_OPTIMIZE */
count = sh_macexpand(shp,argp,argchain,flag); count = sh_macexpand(argp,argchain,flag);
} }
else else
{ {

View file

@ -62,11 +62,10 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
register int flag = lvalue->flag; register int flag = lvalue->flag;
register char *sub=0, *cp=(char*)np; register char *sub=0, *cp=(char*)np;
register Namval_t *mp; register Namval_t *mp;
Shell_t *shp = lvalue->shp;
int c=0,nosub = lvalue->nosub; int c=0,nosub = lvalue->nosub;
Dt_t *sdict = (shp->st.real_fun? shp->st.real_fun->sdict:0); Dt_t *sdict = (sh.st.real_fun? sh.st.real_fun->sdict:0);
Dt_t *nsdict = (shp->namespace?nv_dict(shp->namespace):0); Dt_t *nsdict = (sh.namespace?nv_dict(sh.namespace):0);
Dt_t *root = shp->var_tree; Dt_t *root = sh.var_tree;
assign = assign?NV_ASSIGN:NV_NOASSIGN; assign = assign?NV_ASSIGN:NV_NOASSIGN;
lvalue->nosub = 0; lvalue->nosub = 0;
if(nosub<0 && lvalue->ovalue) if(nosub<0 && lvalue->ovalue)
@ -78,20 +77,21 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
/* do binding to node now */ /* do binding to node now */
int c = cp[flag]; int c = cp[flag];
cp[flag] = 0; cp[flag] = 0;
if((!(np = nv_open(cp,shp->var_tree,assign|NV_VARNAME|NV_NOADD|NV_NOFAIL)) || nv_isnull(np)) && sh_macfun(shp,cp, offset = staktell())) if((!(np = nv_open(cp,sh.var_tree,assign|NV_VARNAME|NV_NOADD|NV_NOFAIL)) || nv_isnull(np))
&& sh_macfun(cp, offset = staktell()))
{ {
Fun = sh_arith(shp,sub=stakptr(offset)); Fun = sh_arith(sub=stakptr(offset));
FunNode.nvalue.ldp = &Fun; FunNode.nvalue.ldp = &Fun;
nv_onattr(&FunNode,NV_NOFREE|NV_LDOUBLE|NV_RDONLY); nv_onattr(&FunNode,NV_NOFREE|NV_LDOUBLE|NV_RDONLY);
cp[flag] = c; cp[flag] = c;
return(&FunNode); return(&FunNode);
} }
if(!np && assign) if(!np && assign)
np = nv_open(cp,shp->var_tree,assign|NV_VARNAME); np = nv_open(cp,sh.var_tree,assign|NV_VARNAME);
cp[flag] = c; cp[flag] = c;
if(!np) if(!np)
return(0); return(0);
root = shp->last_root; root = sh.last_root;
if(cp[flag+1]=='[') if(cp[flag+1]=='[')
flag++; flag++;
else else
@ -156,13 +156,13 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
*cp = 0; *cp = 0;
if(c || hasdot) if(c || hasdot)
{ {
sfprintf(shp->strbuf,"%s%s%c",nv_name(np),sub,0); sfprintf(sh.strbuf,"%s%s%c",nv_name(np),sub,0);
sub = sfstruse(shp->strbuf); sub = sfstruse(sh.strbuf);
} }
*cp = flag; *cp = flag;
if(c || hasdot) if(c || hasdot)
{ {
np = nv_open(sub,shp->var_tree,NV_VARNAME|assign); np = nv_open(sub,sh.var_tree,NV_VARNAME|assign);
return(np); return(np);
} }
#if SHOPT_FIXEDARRAY #if SHOPT_FIXEDARRAY
@ -182,7 +182,7 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
if(ap && !ap->table) if(ap && !ap->table)
{ {
ap->table = dtopen(&_Nvdisc,Dtoset); ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,shp,1); dtuserdata(ap->table,&sh,1);
} }
if(ap && ap->table && (nq=nv_search(nv_getsub(np),ap->table,NV_ADD))) if(ap && ap->table && (nq=nv_search(nv_getsub(np),ap->table,NV_ADD)))
nq->nvenv = (char*)np; nq->nvenv = (char*)np;
@ -222,7 +222,6 @@ int sh_mathstd(const char *name)
static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdouble_t n) static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdouble_t n)
{ {
Shell_t *shp = lvalue->shp;
register Sfdouble_t r= 0; register Sfdouble_t r= 0;
char *str = (char*)*ptr; char *str = (char*)*ptr;
register char *cp; register char *cp;
@ -293,14 +292,14 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl
} }
if(c=='(') if(c=='(')
{ {
int off=stktell(shp->stk); int off=stktell(sh.stk);
int fsize = str- (char*)(*ptr); int fsize = str- (char*)(*ptr);
const struct mathtab *tp; const struct mathtab *tp;
c = **ptr; c = **ptr;
lvalue->fun = 0; lvalue->fun = 0;
sfprintf(shp->stk,".sh.math.%.*s%c",fsize,*ptr,0); sfprintf(sh.stk,".sh.math.%.*s%c",fsize,*ptr,0);
stkseek(shp->stk,off); stkseek(sh.stk,off);
if(np=nv_search(stkptr(shp->stk,off),shp->fun_tree,0)) if(np=nv_search(stkptr(sh.stk,off),sh.fun_tree,0))
{ {
lvalue->nargs = -np->nvalue.rp->argc; lvalue->nargs = -np->nvalue.rp->argc;
lvalue->fun = (Math_f)np; lvalue->fun = (Math_f)np;
@ -329,7 +328,7 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl
{ {
int offset = staktell(); int offset = staktell();
char *saveptr = stakfreeze(0); char *saveptr = stakfreeze(0);
Dt_t *root = (lvalue->emode&ARITH_COMP)?shp->var_base:shp->var_tree; Dt_t *root = (lvalue->emode&ARITH_COMP)?sh.var_base:sh.var_tree;
*str = c; *str = c;
cp = str; cp = str;
while(c=='[' || c=='.') while(c=='[' || c=='.')
@ -410,7 +409,7 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl
const char radix = GETDECIMAL(0); const char radix = GETDECIMAL(0);
lvalue->eflag = 0; lvalue->eflag = 0;
errno = 0; errno = 0;
if(!sh_isoption(shp->bltindata.bnode==SYSLET ? SH_LETOCTAL : SH_POSIX)) if(!sh_isoption(sh.bltindata.bnode==SYSLET ? SH_LETOCTAL : SH_POSIX))
{ {
/* Skip leading zeros to avoid parsing as octal */ /* Skip leading zeros to avoid parsing as octal */
while(*val=='0' && isdigit(val[1])) while(*val=='0' && isdigit(val[1]))
@ -535,9 +534,8 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl
Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode) Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
{ {
Shell_t *shp = sh_getinterp();
register Sfdouble_t d; register Sfdouble_t d;
char base = (sh_isoption(shp->bltindata.bnode==SYSLET ? SH_LETOCTAL : SH_POSIX) ? 0 : 10), *last; char base = (sh_isoption(sh.bltindata.bnode==SYSLET ? SH_LETOCTAL : SH_POSIX) ? 0 : 10), *last;
if(*str==0) if(*str==0)
{ {
d = 0.0; d = 0.0;
@ -558,14 +556,14 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
if(sh_isstate(SH_INIT)) if(sh_isstate(SH_INIT))
/* /*
* Initializing means importing untrusted env vars. The string does not appear to be * Initializing means importing untrusted env vars. The string does not appear to be
* a recognized numeric literal, so give up. We can't safely call strval(), because * a recognized numeric literal, so give up. We can't safely call arith_strval(), because
* that allows arbitrary expressions, causing security vulnerability CVE-2019-14868. * that allows arbitrary expressions, causing security vulnerability CVE-2019-14868.
*/ */
d = 0.0; d = 0.0;
else else
{ {
if(!last || *last!='.' || last[1]!='.') if(!last || *last!='.' || last[1]!='.')
d = strval(shp,str,&last,arith,mode); d = arith_strval(str,&last,arith,mode);
if(!ptr && *last && mode>0) if(!ptr && *last && mode>0)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str); errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str);
@ -581,17 +579,16 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
return(d); return(d);
} }
Sfdouble_t sh_arith(Shell_t *shp,register const char *str) Sfdouble_t sh_arith(register const char *str)
{ {
NOT_USED(shp);
return(sh_strnum(str, (char**)0, 1)); return(sh_strnum(str, (char**)0, 1));
} }
void *sh_arithcomp(Shell_t *shp,register char *str) void *sh_arithcomp(register char *str)
{ {
const char *ptr = str; const char *ptr = str;
Arith_t *ep; Arith_t *ep;
ep = arith_compile(shp,str,(char**)&ptr,arith,ARITH_COMP|1); ep = arith_compile(str,(char**)&ptr,arith,ARITH_COMP|1);
if(*ptr) if(*ptr)
{ {
errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*ptr,str); errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*ptr,str);

View file

@ -1194,7 +1194,7 @@ Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode)
size = nv_getnum(mp); size = nv_getnum(mp);
} }
else else
size = (int)sh_arith(&sh,(char*)sp); size = (int)sh_arith((char*)sp);
} }
if(size <0 && ap) if(size <0 && ap)
size += array_maxindex(np); size += array_maxindex(np);
@ -1410,12 +1410,12 @@ static int array_fixed_init(Namval_t *np, char *sub, char *cp)
fp->max = (int*)(fp+1); fp->max = (int*)(fp+1);
fp->incr = fp->max+n; fp->incr = fp->max+n;
fp->cur = fp->incr+n; fp->cur = fp->incr+n;
fp->max[0] = (int)sh_arith(&sh,(char*)sub); fp->max[0] = (int)sh_arith((char*)sub);
for(n=1,ep=cp;*ep=='['; ep=cp) for(n=1,ep=cp;*ep=='['; ep=cp)
{ {
cp = nv_endsubscript(np,ep,0); cp = nv_endsubscript(np,ep,0);
cp[-1]=0; cp[-1]=0;
fp->max[n++] = sz = (int)sh_arith(&sh,(char*)ep+1); fp->max[n++] = sz = (int)sh_arith((char*)ep+1);
if(sz<0) if(sz<0)
{ {
free((void*)ap); free((void*)ap);
@ -1454,7 +1454,7 @@ static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
} }
else else
fp->curi = 0; fp->curi = 0;
size = (int)sh_arith(&sh,(char*)sub); size = (int)sh_arith((char*)sub);
fp->cur[n] = size; fp->cur[n] = size;
if(size >= fp->max[n] || (size < 0)) if(size >= fp->max[n] || (size < 0))
{ {
@ -1472,7 +1472,7 @@ static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
} }
cp = nv_endsubscript(np,ep,0); cp = nv_endsubscript(np,ep,0);
cp[-1]=0; cp[-1]=0;
size = (int)sh_arith(&sh,(char*)ep+1); size = (int)sh_arith((char*)ep+1);
if(size >= fp->max[n] || (size < 0)) if(size >= fp->max[n] || (size < 0))
{ {
errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np)); errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np));

View file

@ -54,10 +54,9 @@ static int scantree(Dt_t*,const char*, struct argnod**);
static char *nextdir(glob_t *gp, char *dir) static char *nextdir(glob_t *gp, char *dir)
{ {
Shell_t *shp = sh_getinterp();
Pathcomp_t *pp = (Pathcomp_t*)gp->gl_handle; Pathcomp_t *pp = (Pathcomp_t*)gp->gl_handle;
if(!dir) if(!dir)
pp = path_get(shp,""); pp = path_get(Empty);
else else
pp = pp->next; pp = pp->next;
gp->gl_handle = (void*)pp; gp->gl_handle = (void*)pp;
@ -66,7 +65,7 @@ static char *nextdir(glob_t *gp, char *dir)
return(0); return(0);
} }
int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead) int path_expand(const char *pattern, struct argnod **arghead)
{ {
glob_t gdata; glob_t gdata;
register struct argnod *ap; register struct argnod *ap;
@ -85,23 +84,23 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
#endif #endif
if(sh_isstate(SH_COMPLETE)) /* command completion */ if(sh_isstate(SH_COMPLETE)) /* command completion */
{ {
extra += scantree(shp->alias_tree,pattern,arghead); extra += scantree(sh.alias_tree,pattern,arghead);
extra += scantree(shp->fun_tree,pattern,arghead); extra += scantree(sh.fun_tree,pattern,arghead);
gp->gl_nextdir = nextdir; gp->gl_nextdir = nextdir;
flags |= GLOB_COMPLETE; flags |= GLOB_COMPLETE;
flags &= ~GLOB_NOCHECK; flags &= ~GLOB_NOCHECK;
} }
if(sh_isstate(SH_FCOMPLETE)) /* file name completion */ if(sh_isstate(SH_FCOMPLETE)) /* file name completion */
flags |= GLOB_FCOMPLETE; flags |= GLOB_FCOMPLETE;
gp->gl_fignore = nv_getval(sh_scoped(shp,FIGNORENOD)); gp->gl_fignore = nv_getval(sh_scoped(FIGNORENOD));
if(suflen) if(suflen)
gp->gl_suffix = sufstr; gp->gl_suffix = sufstr;
gp->gl_intr = &shp->trapnote; gp->gl_intr = &sh.trapnote;
suflen = 0; suflen = 0;
if(memcmp(pattern,"~(N",3)==0) if(memcmp(pattern,"~(N",3)==0)
flags &= ~GLOB_NOCHECK; flags &= ~GLOB_NOCHECK;
glob(pattern, flags, 0, gp); glob(pattern, flags, 0, gp);
sh_sigcheck(shp); sh_sigcheck();
for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap) for(ap= (struct argnod*)gp->gl_list; ap; ap = ap->argnxt.ap)
{ {
ap->argchn.ap = ap->argnxt.ap; ap->argchn.ap = ap->argnxt.ap;
@ -146,11 +145,11 @@ static int scantree(Dt_t *tree, const char *pattern, struct argnod **arghead)
* The number of matches is returned * The number of matches is returned
*/ */
int path_complete(Shell_t *shp,const char *name,register const char *suffix, struct argnod **arghead) int path_complete(const char *name,register const char *suffix, struct argnod **arghead)
{ {
sufstr = suffix; sufstr = suffix;
suflen = strlen(suffix); suflen = strlen(suffix);
return(path_expand(shp,name,arghead)); return(path_expand(name,arghead));
} }
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
@ -160,7 +159,7 @@ static int checkfmt(Sfio_t* sp, void* vp, Sffmt_t* fp)
return -1; return -1;
} }
int path_generate(Shell_t *shp,struct argnod *todo, struct argnod **arghead) int path_generate(struct argnod *todo, struct argnod **arghead)
/*@ /*@
assume todo!=0; assume todo!=0;
return count satisfying count>=1; return count satisfying count>=1;
@ -286,7 +285,7 @@ again:
{ {
apin = ap->argchn.ap; apin = ap->argchn.ap;
if(!sh_isoption(SH_NOGLOB)) if(!sh_isoption(SH_NOGLOB))
brace=path_expand(shp,ap->argval,arghead); brace=path_expand(ap->argval,arghead);
else else
{ {
ap->argchn.ap = *arghead; ap->argchn.ap = *arghead;
@ -347,7 +346,7 @@ endloop1:
endloop2: endloop2:
brace = *cp; brace = *cp;
*cp = 0; *cp = 0;
sh_sigcheck(shp); sh_sigcheck();
ap = (struct argnod*)stakseek(ARGVAL); ap = (struct argnod*)stakseek(ARGVAL);
ap->argflag = ARG_RAW; ap->argflag = ARG_RAW;
ap->argchn.ap = todo; ap->argchn.ap = todo;

View file

@ -62,10 +62,9 @@ static int cursig = -1;
*/ */
void sh_fault(register int sig) void sh_fault(register int sig)
{ {
register Shell_t *shp = sh_getinterp();
register int flag=0; register int flag=0;
register char *trap; register char *trap;
register struct checkpt *pp = (struct checkpt*)shp->jmplist; register struct checkpt *pp = (struct checkpt*)sh.jmplist;
int action=0; int action=0;
/* reset handler */ /* reset handler */
if(!(sig&SH_TRAP)) if(!(sig&SH_TRAP))
@ -81,79 +80,79 @@ void sh_fault(register int sig)
nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY); nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY);
if(v = rows) if(v = rows)
nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY); nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY);
shp->winch++; sh.winch++;
} }
#endif /* SIGWINCH */ #endif /* SIGWINCH */
trap = shp->st.trapcom[sig]; trap = sh.st.trapcom[sig];
if(shp->savesig) if(sh.savesig)
{ {
/* critical region, save and process later */ /* critical region, save and process later */
if(!(shp->sigflag[sig]&SH_SIGIGNORE)) if(!(sh.sigflag[sig]&SH_SIGIGNORE))
shp->savesig = sig; sh.savesig = sig;
return; return;
} }
if(sig==SIGALRM && shp->bltinfun==b_sleep) if(sig==SIGALRM && sh.bltinfun==b_sleep)
{ {
if(trap && *trap) if(trap && *trap)
{ {
shp->trapnote |= SH_SIGTRAP; sh.trapnote |= SH_SIGTRAP;
shp->sigflag[sig] |= SH_SIGTRAP; sh.sigflag[sig] |= SH_SIGTRAP;
} }
return; return;
} }
if(shp->subshell && trap && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH && sig!=SIGCONT) if(sh.subshell && trap && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH && sig!=SIGCONT)
{ {
shp->exitval = SH_EXITSIG|sig; sh.exitval = SH_EXITSIG|sig;
sh_subfork(); sh_subfork();
shp->exitval = 0; sh.exitval = 0;
return; return;
} }
/* handle ignored signals */ /* handle ignored signals */
if(trap && *trap==0) if(trap && *trap==0)
return; return;
flag = shp->sigflag[sig]&~SH_SIGOFF; flag = sh.sigflag[sig]&~SH_SIGOFF;
if(!trap) if(!trap)
{ {
if(sig==SIGINT && (shp->trapnote&SH_SIGIGNORE)) if(sig==SIGINT && (sh.trapnote&SH_SIGIGNORE))
return; return;
if(flag&SH_SIGIGNORE) if(flag&SH_SIGIGNORE)
{ {
if(shp->subshell) if(sh.subshell)
shp->ignsig = sig; sh.ignsig = sig;
sigrelease(sig); sigrelease(sig);
return; return;
} }
if(flag&SH_SIGDONE) if(flag&SH_SIGDONE)
{ {
void *ptr=0; void *ptr=0;
if((flag&SH_SIGINTERACTIVE) && sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_FORKED) && ! shp->subshell) if((flag&SH_SIGINTERACTIVE) && sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_FORKED) && ! sh.subshell)
{ {
/* check for TERM signal between fork/exec */ /* check for TERM signal between fork/exec */
if(sig==SIGTERM && job.in_critical) if(sig==SIGTERM && job.in_critical)
shp->trapnote |= SH_SIGTERM; sh.trapnote |= SH_SIGTERM;
return; return;
} }
shp->lastsig = sig; sh.lastsig = sig;
sigrelease(sig); sigrelease(sig);
if(pp->mode != SH_JMPSUB) if(pp->mode != SH_JMPSUB)
{ {
if(pp->mode < SH_JMPSUB) if(pp->mode < SH_JMPSUB)
pp->mode = shp->subshell?SH_JMPSUB:SH_JMPFUN; pp->mode = sh.subshell?SH_JMPSUB:SH_JMPFUN;
else else
pp->mode = SH_JMPEXIT; pp->mode = SH_JMPEXIT;
} }
if(shp->subshell) if(sh.subshell)
sh_exit(SH_EXITSIG); sh_exit(SH_EXITSIG);
if(sig==SIGABRT || (abortsig(sig) && (ptr = malloc(1)))) if(sig==SIGABRT || (abortsig(sig) && (ptr = malloc(1))))
{ {
if(ptr) if(ptr)
free(ptr); free(ptr);
sh_done(shp,sig); sh_done(sig);
} }
/* mark signal and continue */ /* mark signal and continue */
shp->trapnote |= SH_SIGSET; sh.trapnote |= SH_SIGSET;
if(sig <= shp->gd->sigmax) if(sig <= sh.sigmax)
shp->sigflag[sig] |= SH_SIGSET; sh.sigflag[sig] |= SH_SIGSET;
#if defined(VMFL) #if defined(VMFL)
if(abortsig(sig)) if(abortsig(sig))
{ {
@ -168,8 +167,8 @@ void sh_fault(register int sig)
} }
} }
errno = 0; errno = 0;
if(pp->mode==SH_JMPCMD || (pp->mode==1 && shp->bltinfun) && !(flag&SH_SIGIGNORE)) if(pp->mode==SH_JMPCMD || (pp->mode==1 && sh.bltinfun) && !(flag&SH_SIGIGNORE))
shp->lastsig = sig; sh.lastsig = sig;
if(trap) if(trap)
{ {
/* /*
@ -181,12 +180,12 @@ void sh_fault(register int sig)
} }
else else
{ {
shp->lastsig = sig; sh.lastsig = sig;
flag = SH_SIGSET; flag = SH_SIGSET;
#ifdef SIGTSTP #ifdef SIGTSTP
if(sig==SIGTSTP) if(sig==SIGTSTP)
{ {
shp->trapnote |= SH_SIGTSTP; sh.trapnote |= SH_SIGTSTP;
if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK)) if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
{ {
sigrelease(sig); sigrelease(sig);
@ -197,19 +196,19 @@ void sh_fault(register int sig)
#endif /* SIGTSTP */ #endif /* SIGTSTP */
} }
#ifdef ERROR_NOTIFY #ifdef ERROR_NOTIFY
if((error_info.flags&ERROR_NOTIFY) && shp->bltinfun) if((error_info.flags&ERROR_NOTIFY) && sh.bltinfun)
action = (*shp->bltinfun)(-sig,(char**)0,(void*)0); action = (*sh.bltinfun)(-sig,(char**)0,(void*)0);
if(action>0) if(action>0)
return; return;
#endif #endif
if(shp->bltinfun && shp->bltindata.notify) if(sh.bltinfun && sh.bltindata.notify)
{ {
shp->bltindata.sigset = 1; sh.bltindata.sigset = 1;
return; return;
} }
shp->trapnote |= flag; sh.trapnote |= flag;
if(sig <= shp->gd->sigmax) if(sig <= sh.sigmax)
shp->sigflag[sig] |= flag; sh.sigflag[sig] |= flag;
if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK)) if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
{ {
if(action<0) if(action<0)
@ -222,9 +221,8 @@ void sh_fault(register int sig)
/* /*
* initialize signal handling * initialize signal handling
*/ */
void sh_siginit(void *ptr) void sh_siginit(void)
{ {
Shell_t *shp = (Shell_t*)ptr;
register int sig, n; register int sig, n;
register const struct shtable2 *tp = shtab_signals; register const struct shtable2 *tp = shtab_signals;
sig_begin(); sig_begin();
@ -232,8 +230,8 @@ void sh_siginit(void *ptr)
#if defined(SIGRTMIN) && defined(SIGRTMAX) #if defined(SIGRTMIN) && defined(SIGRTMAX)
if ((n = SIGRTMIN) > 0 && (sig = SIGRTMAX) > n && sig < SH_TRAP) if ((n = SIGRTMIN) > 0 && (sig = SIGRTMAX) > n && sig < SH_TRAP)
{ {
shp->gd->sigruntime[SH_SIGRTMIN] = n; sh.sigruntime[SH_SIGRTMIN] = n;
shp->gd->sigruntime[SH_SIGRTMAX] = sig; sh.sigruntime[SH_SIGRTMAX] = sig;
} }
#endif /* SIGRTMIN && SIGRTMAX */ #endif /* SIGRTMIN && SIGRTMAX */
n = SIGTERM; n = SIGTERM;
@ -243,29 +241,29 @@ void sh_siginit(void *ptr)
if (!(sig-- & SH_TRAP)) if (!(sig-- & SH_TRAP))
{ {
if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME)
sig = shp->gd->sigruntime[sig]; sig = sh.sigruntime[sig];
if(sig>n && sig<SH_TRAP) if(sig>n && sig<SH_TRAP)
n = sig; n = sig;
} }
tp++; tp++;
} }
shp->gd->sigmax = n++; sh.sigmax = n++;
shp->st.trapcom = (char**)sh_calloc(n,sizeof(char*)); sh.st.trapcom = (char**)sh_calloc(n,sizeof(char*));
shp->sigflag = (unsigned char*)sh_calloc(n,1); sh.sigflag = (unsigned char*)sh_calloc(n,1);
shp->gd->sigmsg = (char**)sh_calloc(n,sizeof(char*)); sh.sigmsg = (char**)sh_calloc(n,sizeof(char*));
for(tp=shtab_signals; sig=tp->sh_number; tp++) for(tp=shtab_signals; sig=tp->sh_number; tp++)
{ {
n = (sig>>SH_SIGBITS); n = (sig>>SH_SIGBITS);
if((sig &= ((1<<SH_SIGBITS)-1)) > (shp->gd->sigmax+1)) if((sig &= ((1<<SH_SIGBITS)-1)) > (sh.sigmax+1))
continue; continue;
sig--; sig--;
if(n&SH_SIGRUNTIME) if(n&SH_SIGRUNTIME)
sig = shp->gd->sigruntime[sig]; sig = sh.sigruntime[sig];
if(sig>=0) if(sig>=0)
{ {
shp->sigflag[sig] = n; sh.sigflag[sig] = n;
if(*tp->sh_name) if(*tp->sh_name)
shp->gd->sigmsg[sig] = (char*)tp->sh_value; sh.sigmsg[sig] = (char*)tp->sh_value;
} }
} }
} }
@ -304,9 +302,9 @@ void sh_sigtrap(register int sig)
*/ */
void sh_sigdone(void) void sh_sigdone(void)
{ {
register int flag, sig = shgd->sigmax; register int flag, sig = sh.sigmax;
sh.sigflag[0] |= SH_SIGFAULT; sh.sigflag[0] |= SH_SIGFAULT;
for(sig=shgd->sigmax; sig>0; sig--) for(sig=sh.sigmax; sig>0; sig--)
{ {
flag = sh.sigflag[sig]; flag = sh.sigflag[sig];
if((flag&(SH_SIGDONE|SH_SIGIGNORE|SH_SIGINTERACTIVE)) && !(flag&(SH_SIGFAULT|SH_SIGOFF))) if((flag&(SH_SIGDONE|SH_SIGIGNORE|SH_SIGINTERACTIVE)) && !(flag&(SH_SIGFAULT|SH_SIGOFF)))
@ -384,38 +382,38 @@ void sh_sigclear(register int sig)
* check for traps * check for traps
*/ */
void sh_chktrap(Shell_t* shp) void sh_chktrap(void)
{ {
register int sig=shp->st.trapmax; register int sig=sh.st.trapmax;
register char *trap; register char *trap;
if(!(shp->trapnote&~SH_SIGIGNORE)) if(!(sh.trapnote&~SH_SIGIGNORE))
sig=0; sig=0;
shp->trapnote &= ~SH_SIGTRAP; sh.trapnote &= ~SH_SIGTRAP;
/* execute errexit trap first */ /* execute errexit trap first */
if(sh_isstate(SH_ERREXIT) && shp->exitval) if(sh_isstate(SH_ERREXIT) && sh.exitval)
{ {
int sav_trapnote = shp->trapnote; int sav_trapnote = sh.trapnote;
shp->trapnote &= ~SH_SIGSET; sh.trapnote &= ~SH_SIGSET;
if(shp->st.trap[SH_ERRTRAP]) if(sh.st.trap[SH_ERRTRAP])
{ {
trap = shp->st.trap[SH_ERRTRAP]; trap = sh.st.trap[SH_ERRTRAP];
shp->st.trap[SH_ERRTRAP] = 0; sh.st.trap[SH_ERRTRAP] = 0;
sh_trap(trap,0); sh_trap(trap,0);
shp->st.trap[SH_ERRTRAP] = trap; sh.st.trap[SH_ERRTRAP] = trap;
} }
shp->trapnote = sav_trapnote; sh.trapnote = sav_trapnote;
if(sh_isoption(SH_ERREXIT)) if(sh_isoption(SH_ERREXIT))
{ {
struct checkpt *pp = (struct checkpt*)shp->jmplist; struct checkpt *pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPEXIT; pp->mode = SH_JMPEXIT;
sh_exit(shp->exitval); sh_exit(sh.exitval);
} }
} }
if(shp->sigflag[SIGALRM]&SH_SIGALRM) if(sh.sigflag[SIGALRM]&SH_SIGALRM)
sh_timetraps(shp); sh_timetraps();
#if SHOPT_BGX #if SHOPT_BGX
if((shp->sigflag[SIGCHLD]&SH_SIGTRAP) && shp->st.trapcom[SIGCHLD]) if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
job_chldtrap(shp,shp->st.trapcom[SIGCHLD],1); job_chldtrap(sh.st.trapcom[SIGCHLD],1);
#endif /* SHOPT_BGX */ #endif /* SHOPT_BGX */
while(--sig>=0) while(--sig>=0)
{ {
@ -425,10 +423,10 @@ void sh_chktrap(Shell_t* shp)
if(sig==SIGCHLD) if(sig==SIGCHLD)
continue; continue;
#endif /* SHOPT_BGX */ #endif /* SHOPT_BGX */
if(shp->sigflag[sig]&SH_SIGTRAP) if(sh.sigflag[sig]&SH_SIGTRAP)
{ {
shp->sigflag[sig] &= ~SH_SIGTRAP; sh.sigflag[sig] &= ~SH_SIGTRAP;
if(trap=shp->st.trapcom[sig]) if(trap=sh.st.trapcom[sig])
{ {
cursig = sig; cursig = sig;
sh_trap(trap,0); sh_trap(trap,0);
@ -455,8 +453,7 @@ void sh_chktrap(Shell_t* shp)
*/ */
int sh_trap(const char *trap, int mode) int sh_trap(const char *trap, int mode)
{ {
Shell_t *shp = sh_getinterp(); int jmpval, savxit = sh.exitval, savxit_return;
int jmpval, savxit = shp->exitval, savxit_return;
int was_history = sh_isstate(SH_HISTORY); int was_history = sh_isstate(SH_HISTORY);
int was_verbose = sh_isstate(SH_VERBOSE); int was_verbose = sh_isstate(SH_VERBOSE);
int staktop = staktell(); int staktop = staktell();
@ -466,8 +463,8 @@ int sh_trap(const char *trap, int mode)
fcsave(&savefc); fcsave(&savefc);
sh_offstate(SH_HISTORY); sh_offstate(SH_HISTORY);
sh_offstate(SH_VERBOSE); sh_offstate(SH_VERBOSE);
shp->intrap++; sh.intrap++;
sh_pushcontext(shp,&buff,SH_JMPTRAP); sh_pushcontext(&sh,&buff,SH_JMPTRAP);
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
if(jmpval == 0) if(jmpval == 0)
{ {
@ -490,16 +487,16 @@ int sh_trap(const char *trap, int mode)
else else
{ {
if(jmpval==SH_JMPEXIT) if(jmpval==SH_JMPEXIT)
savxit = shp->exitval; savxit = sh.exitval;
jmpval=SH_JMPTRAP; jmpval=SH_JMPTRAP;
} }
} }
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
shp->intrap--; sh.intrap--;
sfsync(shp->outpool); sfsync(sh.outpool);
savxit_return = shp->exitval; savxit_return = sh.exitval;
if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN) if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
shp->exitval=savxit; sh.exitval=savxit;
stakset(savptr,staktop); stakset(savptr,staktop);
fcrestore(&savefc); fcrestore(&savefc);
if(was_history) if(was_history)
@ -507,8 +504,8 @@ int sh_trap(const char *trap, int mode)
if(was_verbose) if(was_verbose)
sh_onstate(SH_VERBOSE); sh_onstate(SH_VERBOSE);
exitset(); exitset();
if(jmpval>SH_JMPTRAP && (((struct checkpt*)shp->jmpbuffer)->prev || ((struct checkpt*)shp->jmpbuffer)->mode==SH_JMPSCRIPT)) if(jmpval>SH_JMPTRAP && (((struct checkpt*)sh.jmpbuffer)->prev || ((struct checkpt*)sh.jmpbuffer)->mode==SH_JMPSCRIPT))
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
return(savxit_return); return(savxit_return);
} }
@ -517,86 +514,85 @@ int sh_trap(const char *trap, int mode)
*/ */
void sh_exit(register int xno) void sh_exit(register int xno)
{ {
Shell_t *shp = sh_getinterp(); register struct checkpt *pp = (struct checkpt*)sh.jmplist;
register struct checkpt *pp = (struct checkpt*)shp->jmplist;
register int sig=0; register int sig=0;
register Sfio_t* pool; register Sfio_t* pool;
/* POSIX requires exit status >= 2 for error in 'test'/'[' */ /* POSIX requires exit status >= 2 for error in 'test'/'[' */
if(xno == 1 && (shp->bltindata.bnode==SYSTEST || shp->bltindata.bnode==SYSBRACKET)) if(xno == 1 && (sh.bltindata.bnode==SYSTEST || sh.bltindata.bnode==SYSBRACKET))
shp->exitval = 2; sh.exitval = 2;
else else
shp->exitval = xno; sh.exitval = xno;
if(xno==SH_EXITSIG) if(xno==SH_EXITSIG)
shp->exitval |= (sig=shp->lastsig); sh.exitval |= (sig=sh.lastsig);
if(pp && pp->mode>1) if(pp && pp->mode>1)
cursig = -1; cursig = -1;
#ifdef SIGTSTP #ifdef SIGTSTP
if((shp->trapnote&SH_SIGTSTP) && job.jobcontrol) if((sh.trapnote&SH_SIGTSTP) && job.jobcontrol)
{ {
/* ^Z detected by the shell */ /* ^Z detected by the shell */
shp->trapnote = 0; sh.trapnote = 0;
shp->sigflag[SIGTSTP] = 0; sh.sigflag[SIGTSTP] = 0;
if(!shp->subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK)) if(!sh.subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK))
return; return;
if(sh_isstate(SH_TIMING)) if(sh_isstate(SH_TIMING))
return; return;
/* Handles ^Z for shell builtins, subshells, and functs */ /* Handles ^Z for shell builtins, subshells, and functs */
shp->lastsig = 0; sh.lastsig = 0;
sh_onstate(SH_MONITOR); sh_onstate(SH_MONITOR);
sh_offstate(SH_STOPOK); sh_offstate(SH_STOPOK);
shp->trapnote = 0; sh.trapnote = 0;
shp->forked = 1; sh.forked = 1;
if(sh_isstate(SH_INTERACTIVE) && (sig=sh_fork(shp,0,NIL(int*)))) if(sh_isstate(SH_INTERACTIVE) && (sig=sh_fork(0,NIL(int*))))
{ {
job.curpgid = 0; job.curpgid = 0;
job.parent = (pid_t)-1; job.parent = (pid_t)-1;
job_wait(sig); job_wait(sig);
shp->forked = 0; sh.forked = 0;
job.parent = 0; job.parent = 0;
shp->sigflag[SIGTSTP] = 0; sh.sigflag[SIGTSTP] = 0;
/* wait for child to stop */ /* wait for child to stop */
shp->exitval = (SH_EXITSIG|SIGTSTP); sh.exitval = (SH_EXITSIG|SIGTSTP);
/* return to prompt mode */ /* return to prompt mode */
pp->mode = SH_JMPERREXIT; pp->mode = SH_JMPERREXIT;
} }
else else
{ {
if(shp->subshell) if(sh.subshell)
sh_subfork(); sh_subfork();
/* script or child process; put to sleep */ /* script or child process; put to sleep */
sh_offstate(SH_STOPOK); sh_offstate(SH_STOPOK);
sh_offstate(SH_MONITOR); sh_offstate(SH_MONITOR);
shp->sigflag[SIGTSTP] = 0; sh.sigflag[SIGTSTP] = 0;
/* stop child job */ /* stop child job */
killpg(job.curpgid,SIGTSTP); killpg(job.curpgid,SIGTSTP);
/* child resumes */ /* child resumes */
job_clear(); job_clear();
shp->exitval = (xno&SH_EXITMASK); sh.exitval = (xno&SH_EXITMASK);
return; return;
} }
} }
#endif /* SIGTSTP */ #endif /* SIGTSTP */
/* unlock output pool */ /* unlock output pool */
sh_offstate(SH_NOTRACK); sh_offstate(SH_NOTRACK);
if(!(pool=sfpool(NIL(Sfio_t*),shp->outpool,SF_WRITE))) if(!(pool=sfpool(NIL(Sfio_t*),sh.outpool,SF_WRITE)))
pool = shp->outpool; /* can't happen? */ pool = sh.outpool; /* can't happen? */
sfclrlock(pool); sfclrlock(pool);
#ifdef SIGPIPE #ifdef SIGPIPE
if(shp->lastsig==SIGPIPE) if(sh.lastsig==SIGPIPE)
sfpurge(pool); sfpurge(pool);
#endif /* SIGPIPE */ #endif /* SIGPIPE */
sfclrlock(sfstdin); sfclrlock(sfstdin);
if(!pp) if(!pp)
sh_done(shp,sig); sh_done(sig);
shp->arithrecursion = 0; sh.arithrecursion = 0;
shp->prefix = 0; sh.prefix = 0;
#if SHOPT_TYPEDEF #if SHOPT_TYPEDEF
shp->mktype = 0; sh.mktype = 0;
#endif /* SHOPT_TYPEDEF */ #endif /* SHOPT_TYPEDEF */
if(job.in_critical) if(job.in_critical)
job_unlock(); job_unlock();
if(pp->mode == SH_JMPSCRIPT && !pp->prev) if(pp->mode == SH_JMPSCRIPT && !pp->prev)
sh_done(shp,sig); sh_done(sig);
if(pp->mode) if(pp->mode)
siglongjmp(pp->buff,pp->mode); siglongjmp(pp->buff,pp->mode);
} }
@ -613,31 +609,30 @@ static void array_notify(Namval_t *np, void *data)
* This is the exit routine for the shell * This is the exit routine for the shell
*/ */
noreturn void sh_done(void *ptr, register int sig) noreturn void sh_done(register int sig)
{ {
Shell_t *shp = (Shell_t*)ptr;
register char *t; register char *t;
register int savxit = shp->exitval; register int savxit = sh.exitval;
shp->trapnote = 0; sh.trapnote = 0;
indone=1; indone=1;
if(sig) if(sig)
savxit = SH_EXITSIG|sig; savxit = SH_EXITSIG|sig;
if(shp->userinit) if(sh.userinit)
(*shp->userinit)(shp, -1); (*sh.userinit)(&sh, -1);
if(t=shp->st.trapcom[0]) if(t=sh.st.trapcom[0])
{ {
shp->st.trapcom[0]=0; /* should free but not long */ sh.st.trapcom[0]=0; /* should free but not long */
sh_trap(t,0); sh_trap(t,0);
savxit = shp->exitval; savxit = sh.exitval;
} }
else else
{ {
/* avoid recursive call for set -e */ /* avoid recursive call for set -e */
sh_offstate(SH_ERREXIT); sh_offstate(SH_ERREXIT);
sh_chktrap(shp); sh_chktrap();
} }
nv_scan(shp->var_tree,array_notify,(void*)0,NV_ARRAY,NV_ARRAY); nv_scan(sh.var_tree,array_notify,(void*)0,NV_ARRAY,NV_ARRAY);
sh_freeup(shp); sh_freeup();
#if SHOPT_ACCT #if SHOPT_ACCT
sh_accend(); sh_accend();
#endif /* SHOPT_ACCT */ #endif /* SHOPT_ACCT */
@ -654,16 +649,16 @@ noreturn void sh_done(void *ptr, register int sig)
tty_cooked(-1); tty_cooked(-1);
#endif /* SHOPT_VSH || SHOPT_ESH */ #endif /* SHOPT_VSH || SHOPT_ESH */
#ifdef JOBS #ifdef JOBS
if((sh_isoption(SH_INTERACTIVE) && shp->login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP))) if((sh_isoption(SH_INTERACTIVE) && sh.login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
job_walk(sfstderr, job_hup, SIGHUP, NIL(char**)); job_walk(sfstderr, job_hup, SIGHUP, NIL(char**));
#endif /* JOBS */ #endif /* JOBS */
job_close(shp); job_close();
if(nv_search("VMTRACE", shp->var_tree,0)) if(nv_search("VMTRACE", sh.var_tree,0))
strmatch((char*)0,(char*)0); strmatch((char*)0,(char*)0);
sfsync((Sfio_t*)sfstdin); sfsync((Sfio_t*)sfstdin);
sfsync((Sfio_t*)shp->outpool); sfsync((Sfio_t*)sh.outpool);
sfsync((Sfio_t*)sfstdout); sfsync((Sfio_t*)sfstdout);
if(savxit&SH_EXITSIG && (savxit&SH_EXITMASK) == shp->lastsig) if(savxit&SH_EXITSIG && (savxit&SH_EXITMASK) == sh.lastsig)
sig = savxit&SH_EXITMASK; sig = savxit&SH_EXITMASK;
if(sig) if(sig)
{ {
@ -681,12 +676,12 @@ noreturn void sh_done(void *ptr, register int sig)
} }
signal(sig,SIG_DFL); signal(sig,SIG_DFL);
sigrelease(sig); sigrelease(sig);
kill(shgd->current_pid,sig); kill(sh.current_pid,sig);
pause(); pause();
} }
#if SHOPT_KIA #if SHOPT_KIA
if(sh_isoption(SH_NOEXEC)) if(sh_isoption(SH_NOEXEC))
kiaclose((Lex_t*)shp->lex_context); kiaclose((Lex_t*)sh.lex_context);
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
/* Exit with portable 8-bit status (128 + signum) if last child process exits due to signal */ /* Exit with portable 8-bit status (128 + signum) if last child process exits due to signal */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -219,34 +219,34 @@ static struct back_save bck;
typedef int (*Waitevent_f)(int,long,int); typedef int (*Waitevent_f)(int,long,int);
#if SHOPT_BGX #if SHOPT_BGX
void job_chldtrap(Shell_t *shp, const char *trap, int unpost) void job_chldtrap(const char *trap, int unpost)
{ {
register struct process *pw,*pwnext; register struct process *pw,*pwnext;
pid_t bckpid; pid_t bckpid;
int oldexit,trapnote; int oldexit,trapnote;
job_lock(); job_lock();
shp->sigflag[SIGCHLD] &= ~SH_SIGTRAP; sh.sigflag[SIGCHLD] &= ~SH_SIGTRAP;
trapnote = shp->trapnote; trapnote = sh.trapnote;
shp->trapnote = 0; sh.trapnote = 0;
for(pw=job.pwlist;pw;pw=pwnext) for(pw=job.pwlist;pw;pw=pwnext)
{ {
pwnext = pw->p_nxtjob; pwnext = pw->p_nxtjob;
if((pw->p_flag&(P_BG|P_DONE)) != (P_BG|P_DONE)) if((pw->p_flag&(P_BG|P_DONE)) != (P_BG|P_DONE))
continue; continue;
pw->p_flag &= ~P_BG; pw->p_flag &= ~P_BG;
bckpid = shp->bckpid; bckpid = sh.bckpid;
oldexit = shp->savexit; oldexit = sh.savexit;
shp->bckpid = pw->p_pid; sh.bckpid = pw->p_pid;
shp->savexit = pw->p_exit; sh.savexit = pw->p_exit;
if(pw->p_flag&P_SIGNALLED) if(pw->p_flag&P_SIGNALLED)
shp->savexit |= SH_EXITSIG; sh.savexit |= SH_EXITSIG;
sh_trap(trap,0); sh_trap(trap,0);
if(pw->p_pid==bckpid && unpost) if(pw->p_pid==bckpid && unpost)
job_unpost(pw,0); job_unpost(pw,0);
shp->savexit = oldexit; sh.savexit = oldexit;
shp->bckpid = bckpid; sh.bckpid = bckpid;
} }
shp->trapnote = trapnote; sh.trapnote = trapnote;
job_unlock(); job_unlock();
} }
#endif /* SHOPT_BGX */ #endif /* SHOPT_BGX */
@ -258,7 +258,7 @@ static struct jobsave *jobsave_create(pid_t pid)
{ {
register struct jobsave *jp = job_savelist; register struct jobsave *jp = job_savelist;
job_chksave(pid); job_chksave(pid);
if(++bck.count > shgd->lim.child_max) if(++bck.count > sh.lim.child_max)
job_chksave(0); job_chksave(0);
if(jp) if(jp)
{ {
@ -283,14 +283,13 @@ static struct jobsave *jobsave_create(pid_t pid)
*/ */
int job_reap(register int sig) int job_reap(register int sig)
{ {
Shell_t *shp = sh_getinterp();
register pid_t pid; register pid_t pid;
register struct process *pw = NIL(struct process*); register struct process *pw = NIL(struct process*);
struct process *px; struct process *px;
register int flags; register int flags;
struct jobsave *jp; struct jobsave *jp;
int nochild=0, oerrno, wstat; int nochild=0, oerrno, wstat;
Waitevent_f waitevent = shp->gd->waitevent; Waitevent_f waitevent = sh.waitevent;
static int wcontinued = WCONTINUED; static int wcontinued = WCONTINUED;
int was_ttywait_on; int was_ttywait_on;
if (vmbusy()) if (vmbusy())
@ -300,7 +299,7 @@ int job_reap(register int sig)
abort(); abort();
} }
#ifdef DEBUG #ifdef DEBUG
if(sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d signal=%d\n",__LINE__,shgd->current_pid,job.in_critical,sig) <=0) if(sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d signal=%d\n",__LINE__,sh.current_pid,job.in_critical,sig) <=0)
write(2,"waitsafe\n",9); write(2,"waitsafe\n",9);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
@ -309,7 +308,7 @@ int job_reap(register int sig)
flags = WNOHANG|WUNTRACED|wcontinued; flags = WNOHANG|WUNTRACED|wcontinued;
else else
flags = WUNTRACED|wcontinued; flags = WUNTRACED|wcontinued;
shp->gd->waitevent = 0; sh.waitevent = 0;
oerrno = errno; oerrno = errno;
was_ttywait_on = sh_isstate(SH_TTYWAIT); /* save tty wait state */ was_ttywait_on = sh_isstate(SH_TTYWAIT); /* save tty wait state */
while(1) while(1)
@ -331,7 +330,7 @@ int job_reap(register int sig)
if (pid<0 && errno==EINVAL && (flags&WCONTINUED)) if (pid<0 && errno==EINVAL && (flags&WCONTINUED))
pid = waitpid((pid_t)-1,&wstat,flags&=~WCONTINUED); pid = waitpid((pid_t)-1,&wstat,flags&=~WCONTINUED);
sh_sigcheck(shp); sh_sigcheck();
if(pid<0 && errno==EINTR && (sig||job.savesig)) if(pid<0 && errno==EINTR && (sig||job.savesig))
{ {
errno = 0; errno = 0;
@ -348,7 +347,7 @@ int job_reap(register int sig)
if(!(pw=job_bypid(pid))) if(!(pw=job_bypid(pid)))
{ {
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d unknown job pid=%d pw=%x\n",__LINE__,shgd->current_pid,job.in_critical,pid,pw); sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d unknown job pid=%d pw=%x\n",__LINE__,sh.current_pid,job.in_critical,pid,pw);
#endif /* DEBUG */ #endif /* DEBUG */
if (WIFCONTINUED(wstat) && wcontinued) if (WIFCONTINUED(wstat) && wcontinued)
continue; continue;
@ -378,7 +377,7 @@ int job_reap(register int sig)
pw->p_flag |= (P_NOTIFY|P_SIGNALLED|P_STOPPED); pw->p_flag |= (P_NOTIFY|P_SIGNALLED|P_STOPPED);
pw->p_exit = WSTOPSIG(wstat); pw->p_exit = WSTOPSIG(wstat);
if(pw->p_pgrp && pw->p_pgrp==job.curpgid && sh_isstate(SH_STOPOK)) if(pw->p_pgrp && pw->p_pgrp==job.curpgid && sh_isstate(SH_STOPOK))
kill(shgd->current_pid,pw->p_exit); kill(sh.current_pid,pw->p_exit);
if(px) if(px)
{ {
/* move to top of job list */ /* move to top of job list */
@ -392,14 +391,14 @@ int job_reap(register int sig)
#endif /* SIGTSTP */ #endif /* SIGTSTP */
{ {
/* check for coprocess completion */ /* check for coprocess completion */
if(pid==shp->cpid) if(pid==sh.cpid)
{ {
sh_close(sh.coutpipe); sh_close(sh.coutpipe);
sh_close(sh.cpipe[1]); sh_close(sh.cpipe[1]);
sh.cpipe[1] = -1; sh.cpipe[1] = -1;
sh.coutpipe = -1; sh.coutpipe = -1;
} }
else if(shp->subshell) else if(sh.subshell)
sh_subjobcheck(pid); sh_subjobcheck(pid);
pw->p_flag &= ~(P_STOPPED|P_SIGNALLED); pw->p_flag &= ~(P_STOPPED|P_SIGNALLED);
@ -416,7 +415,7 @@ int job_reap(register int sig)
{ {
pw->p_flag &= ~P_NOTIFY; pw->p_flag &= ~P_NOTIFY;
sh_offstate(SH_STOPOK); sh_offstate(SH_STOPOK);
kill(shgd->current_pid,SIGINT); kill(sh.current_pid,SIGINT);
sh_onstate(SH_STOPOK); sh_onstate(SH_STOPOK);
} }
} }
@ -431,13 +430,13 @@ int job_reap(register int sig)
if((pw->p_flag&P_DONE) && (pw->p_flag&P_BG)) if((pw->p_flag&P_DONE) && (pw->p_flag&P_BG))
{ {
job.numbjob--; job.numbjob--;
if(shp->st.trapcom[SIGCHLD]) if(sh.st.trapcom[SIGCHLD])
{ {
shp->sigflag[SIGCHLD] |= SH_SIGTRAP; sh.sigflag[SIGCHLD] |= SH_SIGTRAP;
if(sig==0) if(sig==0)
job_chldtrap(shp,shp->st.trapcom[SIGCHLD],0); job_chldtrap(sh.st.trapcom[SIGCHLD],0);
else else
shp->trapnote |= SH_SIGTRAP; sh.trapnote |= SH_SIGTRAP;
} }
else else
pw->p_flag &= ~P_BG; pw->p_flag &= ~P_BG;
@ -453,7 +452,7 @@ int job_reap(register int sig)
jp->exitval |= SH_EXITSIG; jp->exitval |= SH_EXITSIG;
} }
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d job %d with pid %d flags=%o complete with status=%x exit=%d\n",__LINE__,shgd->current_pid,job.in_critical,pw->p_job,pid,pw->p_flag,wstat,pw->p_exit); sfprintf(sfstderr,"ksh: job line %4d: reap pid=%d critical=%d job %d with pid %d flags=%o complete with status=%x exit=%d\n",__LINE__,sh.current_pid,job.in_critical,pw->p_job,pid,pw->p_flag,wstat,pw->p_exit);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
/* only top-level process in job should have notify set */ /* only top-level process in job should have notify set */
@ -467,10 +466,10 @@ int job_reap(register int sig)
tcsetpgrp(JOBTTY,job.mypid); tcsetpgrp(JOBTTY,job.mypid);
} }
#if !SHOPT_BGX #if !SHOPT_BGX
if(!shp->intrap && shp->st.trapcom[SIGCHLD] && pid>0 && (pwfg!=job_bypid(pid))) if(!sh.intrap && sh.st.trapcom[SIGCHLD] && pid>0 && (pwfg!=job_bypid(pid)))
{ {
shp->sigflag[SIGCHLD] |= SH_SIGTRAP; sh.sigflag[SIGCHLD] |= SH_SIGTRAP;
shp->trapnote |= SH_SIGTRAP; sh.trapnote |= SH_SIGTRAP;
} }
#endif #endif
} }
@ -482,7 +481,7 @@ int job_reap(register int sig)
#endif /* SHOPT_BGX */ #endif /* SHOPT_BGX */
nochild = 1; nochild = 1;
} }
shp->gd->waitevent = waitevent; sh.waitevent = waitevent;
if(pw && sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT)) if(pw && sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT))
{ {
outfile = sfstderr; outfile = sfstderr;
@ -513,7 +512,7 @@ static void job_waitsafe(int sig)
* initialize job control if possible * initialize job control if possible
* if lflag is set the switching driver message will not print * if lflag is set the switching driver message will not print
*/ */
void job_init(Shell_t *shp, int lflag) void job_init(int lflag)
{ {
register int ntry=0; register int ntry=0;
job.fd = JOBTTY; job.fd = JOBTTY;
@ -555,7 +554,7 @@ void job_init(Shell_t *shp, int lflag)
register int fd; register int fd;
register char *ttynam; register char *ttynam;
#ifndef SIGTSTP #ifndef SIGTSTP
setpgid(0,shp->gd->pid); setpgid(0,sh.pid);
#endif /*SIGTSTP */ #endif /*SIGTSTP */
if(sh_isoption(SH_INTERACTIVE)) if(sh_isoption(SH_INTERACTIVE))
{ {
@ -566,12 +565,12 @@ void job_init(Shell_t *shp, int lflag)
if((fd = open(ttynam,O_RDWR)) <0) if((fd = open(ttynam,O_RDWR)) <0)
return; return;
if(fd!=JOBTTY) if(fd!=JOBTTY)
sh_iorenumber(shp,fd,JOBTTY); sh_iorenumber(fd,JOBTTY);
#ifdef SIGTSTP #ifdef SIGTSTP
tcsetpgrp(JOBTTY,shp->gd->pid); tcsetpgrp(JOBTTY,sh.pid);
#endif /* SIGTSTP */ #endif /* SIGTSTP */
} }
job.mypgid = shp->gd->pid; job.mypgid = sh.pid;
} }
#ifdef SIGTSTP #ifdef SIGTSTP
possible = (setpgid(0,job.mypgid) >= 0) || errno==EPERM; possible = (setpgid(0,job.mypgid) >= 0) || errno==EPERM;
@ -584,7 +583,7 @@ void job_init(Shell_t *shp, int lflag)
return; return;
/* Stop this shell until continued */ /* Stop this shell until continued */
signal(SIGTTIN,SIG_DFL); signal(SIGTTIN,SIG_DFL);
kill(shp->gd->pid,SIGTTIN); kill(sh.pid,SIGTTIN);
/* resumes here after continue tries again */ /* resumes here after continue tries again */
if(ntry++ > IOMAXTRY) if(ntry++ > IOMAXTRY)
{ {
@ -625,8 +624,8 @@ void job_init(Shell_t *shp, int lflag)
#ifdef SIGTSTP #ifdef SIGTSTP
/* make sure that we are a process group leader */ /* make sure that we are a process group leader */
setpgid(0,shp->gd->pid); setpgid(0,sh.pid);
job.mypid = shp->gd->pid; job.mypid = sh.pid;
if(!sh_isoption(SH_INTERACTIVE)) if(!sh_isoption(SH_INTERACTIVE))
return; return;
# if defined(SA_NOCLDSTOP) || defined(SA_NOCLDWAIT) # if defined(SA_NOCLDSTOP) || defined(SA_NOCLDWAIT)
@ -642,7 +641,7 @@ void job_init(Shell_t *shp, int lflag)
signal(SIGTTOU,SIG_IGN); signal(SIGTTOU,SIG_IGN);
/* The shell now handles ^Z */ /* The shell now handles ^Z */
signal(SIGTSTP,sh_fault); signal(SIGTSTP,sh_fault);
tcsetpgrp(JOBTTY,shp->gd->pid); tcsetpgrp(JOBTTY,sh.pid);
# ifdef CNSUSP # ifdef CNSUSP
/* set the switch character */ /* set the switch character */
tty_get(JOBTTY,&my_stty); tty_get(JOBTTY,&my_stty);
@ -664,7 +663,7 @@ void job_init(Shell_t *shp, int lflag)
* see if there are any stopped jobs * see if there are any stopped jobs
* restore tty driver and pgrp * restore tty driver and pgrp
*/ */
int job_close(Shell_t* shp) int job_close(void)
{ {
register struct process *pw; register struct process *pw;
register int count = 0, running = 0; register int count = 0, running = 0;
@ -672,7 +671,7 @@ int job_close(Shell_t* shp)
return(0); return(0);
else if(!possible && (!sh_isstate(SH_MONITOR) || sh_isstate(SH_FORKED))) else if(!possible && (!sh_isstate(SH_MONITOR) || sh_isstate(SH_FORKED)))
return(0); return(0);
else if(shgd->current_pid != job.mypid) else if(sh.current_pid != job.mypid)
return(0); return(0);
job_lock(); job_lock();
if(!tty_check(0)) if(!tty_check(0))
@ -696,7 +695,7 @@ int job_close(Shell_t* shp)
errormsg(SH_DICT,0,e_terminate); errormsg(SH_DICT,0,e_terminate);
return(-1); return(-1);
} }
else if(running && shp->login_sh) else if(running && sh.login_sh)
{ {
errormsg(SH_DICT,0,e_jobsrunning); errormsg(SH_DICT,0,e_jobsrunning);
return(-1); return(-1);
@ -743,7 +742,6 @@ int job_close(Shell_t* shp)
static void job_set(register struct process *pw) static void job_set(register struct process *pw)
{ {
Shell_t *shp = pw->p_shp;
if(!job.jobcontrol) if(!job.jobcontrol)
return; return;
/* save current terminal state */ /* save current terminal state */
@ -754,12 +752,12 @@ static void job_set(register struct process *pw)
tty_set(job.fd,TCSAFLUSH,&pw->p_stty); tty_set(job.fd,TCSAFLUSH,&pw->p_stty);
} }
#ifdef SIGTSTP #ifdef SIGTSTP
if((pw->p_flag&P_STOPPED) || tcgetpgrp(job.fd) == shp->gd->pid) if((pw->p_flag&P_STOPPED) || tcgetpgrp(job.fd) == sh.pid)
tcsetpgrp(job.fd,pw->p_fgrp); tcsetpgrp(job.fd,pw->p_fgrp);
/* if job is stopped, resume it in the background */ /* if job is stopped, resume it in the background */
if(!shp->forked) if(!sh.forked)
job_unstop(pw); job_unstop(pw);
shp->forked = 0; sh.forked = 0;
#endif /* SIGTSTP */ #endif /* SIGTSTP */
} }
@ -875,7 +873,6 @@ int job_walk(Sfio_t *file,int (*fun)(struct process*,int),int arg,char *joblist[
if(!(pw = job_bypid(pid))) if(!(pw = job_bypid(pid)))
{ {
pw = &dummy; pw = &dummy;
pw->p_shp = sh_getinterp();
pw->p_pid = pid; pw->p_pid = pid;
pw->p_pgrp = pid; pw->p_pgrp = pid;
} }
@ -898,14 +895,13 @@ int job_walk(Sfio_t *file,int (*fun)(struct process*,int),int arg,char *joblist[
int job_list(struct process *pw,register int flag) int job_list(struct process *pw,register int flag)
{ {
Shell_t *shp = sh_getinterp();
register struct process *px = pw; register struct process *px = pw;
register int n; register int n;
register const char *msg; register const char *msg;
register int msize; register int msize;
if(!pw || pw->p_job<=0) if(!pw || pw->p_job<=0)
return(1); return(1);
if(pw->p_env != shp->jobenv) if(pw->p_env != sh.jobenv)
return(0); return(0);
if((flag&JOB_NFLAG) && (!(px->p_flag&P_NOTIFY)||px->p_pgrp==0)) if((flag&JOB_NFLAG) && (!(px->p_flag&P_NOTIFY)||px->p_pgrp==0))
return(0); return(0);
@ -965,7 +961,7 @@ int job_list(struct process *pw,register int flag)
px = 0; px = 0;
} }
if(!px) if(!px)
hist_list(shgd->hist_ptr,outfile,pw->p_name,0,";"); hist_list(sh.hist_ptr,outfile,pw->p_name,0,";");
else else
sfputr(outfile, e_nlspace, -1); sfputr(outfile, e_nlspace, -1);
} }
@ -1007,7 +1003,6 @@ static struct process *job_bystring(register char *ajob)
int job_kill(register struct process *pw,register int sig) int job_kill(register struct process *pw,register int sig)
{ {
Shell_t *shp;
register pid_t pid; register pid_t pid;
register int r; register int r;
const char *msg; const char *msg;
@ -1020,14 +1015,13 @@ int job_kill(register struct process *pw,register int sig)
errno = ECHILD; errno = ECHILD;
if(!pw) if(!pw)
goto error; /* not an actual shell job */ goto error; /* not an actual shell job */
shp = pw->p_shp;
pid = pw->p_pid; pid = pw->p_pid;
if(by_number) if(by_number)
{ {
if(pid==0 && job.jobcontrol) if(pid==0 && job.jobcontrol)
r = job_walk(outfile, job_kill,sig, (char**)0); r = job_walk(outfile, job_kill,sig, (char**)0);
#ifdef SIGTSTP #ifdef SIGTSTP
if(sig==SIGSTOP && pid==shp->gd->pid && shp->gd->ppid==1) if(sig==SIGSTOP && pid==sh.pid && sh.ppid==1)
{ {
/* can't stop login shell */ /* can't stop login shell */
errno = EPERM; errno = EPERM;
@ -1139,13 +1133,12 @@ static struct process *job_byname(char *name)
register int *flag = 0; register int *flag = 0;
register char *cp = name; register char *cp = name;
int offset; int offset;
if(!shgd->hist_ptr) if(!sh.hist_ptr)
return(NIL(struct process*)); return(NIL(struct process*));
if(*cp=='?') if(*cp=='?')
cp++,flag= &offset; cp++,flag= &offset;
for(;pw;pw=pw->p_nxtjob)
{ {
if(hist_match(shgd->hist_ptr,pw->p_name,cp,flag)>=0) if(hist_match(sh.hist_ptr,pw->p_name,cp,flag)>=0)
{ {
if(pz) if(pz)
{ {
@ -1171,10 +1164,9 @@ static struct process *job_byname(char *name)
void job_clear(void) void job_clear(void)
{ {
Shell_t *shp = sh_getinterp();
register struct process *pw, *px; register struct process *pw, *px;
register struct process *pwnext; register struct process *pwnext;
register int j = BYTE(shp->gd->lim.child_max); register int j = BYTE(sh.lim.child_max);
register struct jobsave *jp,*jpnext; register struct jobsave *jp,*jpnext;
job_lock(); job_lock();
for(pw=job.pwlist; pw; pw=pwnext) for(pw=job.pwlist; pw; pw=pwnext)
@ -1214,16 +1206,16 @@ void job_clear(void)
* if non-zero, <join> is the process id of the job to join * if non-zero, <join> is the process id of the job to join
*/ */
int job_post(Shell_t *shp,pid_t pid, pid_t join) int job_post(pid_t pid, pid_t join)
{ {
register struct process *pw; register struct process *pw;
register History_t *hp = shp->gd->hist_ptr; register History_t *hp = sh.hist_ptr;
#if SHOPT_BGX #if SHOPT_BGX
int val,bg=0; int val,bg=0;
#else #else
int val; int val;
#endif #endif
shp->jobenv = shp->curenv; sh.jobenv = sh.curenv;
if(job.toclear) if(job.toclear)
{ {
job_clear(); job_clear();
@ -1279,12 +1271,11 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
} }
pw->p_exitval = job.exitval; pw->p_exitval = job.exitval;
job.pwlist = pw; job.pwlist = pw;
pw->p_shp = shp; pw->p_env = sh.curenv;
pw->p_env = shp->curenv;
pw->p_pid = pid; pw->p_pid = pid;
if(!shp->outpipe || shp->cpid==pid) if(!sh.outpipe || sh.cpid==pid)
pw->p_flag = P_EXITSAVE; pw->p_flag = P_EXITSAVE;
pw->p_exitmin = shp->xargexit; pw->p_exitmin = sh.xargexit;
pw->p_exit = 0; pw->p_exit = 0;
if(sh_isstate(SH_MONITOR)) if(sh_isstate(SH_MONITOR))
{ {
@ -1296,13 +1287,13 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
pw->p_fgrp = 0; pw->p_fgrp = 0;
pw->p_pgrp = pw->p_fgrp; pw->p_pgrp = pw->p_fgrp;
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: post pid=%d critical=%d job=%d pid=%d pgid=%d savesig=%d join=%d\n",__LINE__,shgd->current_pid,job.in_critical,pw->p_job, sfprintf(sfstderr,"ksh: job line %4d: post pid=%d critical=%d job=%d pid=%d pgid=%d savesig=%d join=%d\n",__LINE__,sh.current_pid,job.in_critical,pw->p_job,
pw->p_pid,pw->p_pgrp,job.savesig,join); pw->p_pid,pw->p_pgrp,job.savesig,join);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
#ifdef JOBS #ifdef JOBS
if(hp && !sh_isstate(SH_PROFILE)) if(hp && !sh_isstate(SH_PROFILE))
pw->p_name=hist_tell(shgd->hist_ptr,(int)hp->histind-1); pw->p_name=hist_tell(sh.hist_ptr,(int)hp->histind-1);
else else
pw->p_name = -1; pw->p_name = -1;
#endif /* JOBS */ #endif /* JOBS */
@ -1398,7 +1389,6 @@ static void job_prmsg(register struct process *pw)
int job_wait(register pid_t pid) int job_wait(register pid_t pid)
{ {
Shell_t *shp = sh_getinterp();
register struct process *pw=0,*px; register struct process *pw=0,*px;
register int jobid = 0; register int jobid = 0;
int nochild = 1; int nochild = 1;
@ -1423,20 +1413,20 @@ int job_wait(register pid_t pid)
} }
if(pid > 1) if(pid > 1)
{ {
if(pid==shp->spid) if(pid==sh.spid)
shp->spid = 0; sh.spid = 0;
if(!(pw=job_bypid(pid))) if(!(pw=job_bypid(pid)))
{ {
/* check to see whether job status has been saved */ /* check to see whether job status has been saved */
if((shp->exitval = job_chksave(pid)) < 0) if((sh.exitval = job_chksave(pid)) < 0)
shp->exitval = ERROR_NOENT; sh.exitval = ERROR_NOENT;
exitset(); exitset();
job_unlock(); job_unlock();
return(nochild); return(nochild);
} }
else if(intr && pw->p_env!=shp->curenv) else if(intr && pw->p_env!=sh.curenv)
{ {
shp->exitval = ERROR_NOENT; sh.exitval = ERROR_NOENT;
job_unlock(); job_unlock();
return(nochild); return(nochild);
} }
@ -1448,16 +1438,16 @@ int job_wait(register pid_t pid)
} }
pwfg = pw; pwfg = pw;
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: wait pid=%d critical=%d job=%d pid=%d\n",__LINE__,shgd->current_pid,job.in_critical,jobid,pid); sfprintf(sfstderr,"ksh: job line %4d: wait pid=%d critical=%d job=%d pid=%d\n",__LINE__,sh.current_pid,job.in_critical,jobid,pid);
if(pw) if(pw)
sfprintf(sfstderr,"ksh: job line %4d: wait pid=%d critical=%d flags=%o\n",__LINE__,shgd->current_pid,job.in_critical,pw->p_flag); sfprintf(sfstderr,"ksh: job line %4d: wait pid=%d critical=%d flags=%o\n",__LINE__,sh.current_pid,job.in_critical,pw->p_flag);
#endif /* DEBUG */ #endif /* DEBUG */
errno = 0; errno = 0;
if(shp->coutpipe>=0 && lastpid && shp->cpid==lastpid) if(sh.coutpipe>=0 && lastpid && sh.cpid==lastpid)
{ {
sh_close(shp->coutpipe); sh_close(sh.coutpipe);
sh_close(shp->cpipe[1]); sh_close(sh.cpipe[1]);
shp->cpipe[1] = shp->coutpipe = -1; sh.cpipe[1] = sh.coutpipe = -1;
} }
while(1) while(1)
{ {
@ -1516,9 +1506,9 @@ int job_wait(register pid_t pid)
px = 0; px = 0;
if(px) if(px)
{ {
shp->exitval=px->p_exit; sh.exitval=px->p_exit;
if(px->p_flag&P_SIGNALLED) if(px->p_flag&P_SIGNALLED)
shp->exitval |= SH_EXITSIG; sh.exitval |= SH_EXITSIG;
if(intr) if(intr)
px->p_flag &= ~P_EXITSAVE; px->p_flag &= ~P_EXITSAVE;
} }
@ -1537,13 +1527,13 @@ int job_wait(register pid_t pid)
continue; continue;
if(nochild) if(nochild)
break; break;
if(shp->sigflag[SIGALRM]&SH_SIGTRAP) if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
sh_timetraps(shp); sh_timetraps();
if((intr && shp->trapnote) || (pid==1 && !intr)) if((intr && sh.trapnote) || (pid==1 && !intr))
break; break;
} }
if(intr && shp->trapnote) if(intr && sh.trapnote)
shp->exitval = 1; sh.exitval = 1;
pwfg = 0; pwfg = 0;
job_unlock(); job_unlock();
if(pid==1) if(pid==1)
@ -1555,13 +1545,13 @@ int job_wait(register pid_t pid)
{ {
job_reset(pw); job_reset(pw);
/* propagate keyboard interrupts to parent */ /* propagate keyboard interrupts to parent */
if((pw->p_flag&P_SIGNALLED) && pw->p_exit==SIGINT && !(shp->sigflag[SIGINT]&SH_SIGOFF)) if((pw->p_flag&P_SIGNALLED) && pw->p_exit==SIGINT && !(sh.sigflag[SIGINT]&SH_SIGOFF))
kill(shgd->current_pid,SIGINT); kill(sh.current_pid,SIGINT);
#ifdef SIGTSTP #ifdef SIGTSTP
else if((pw->p_flag&P_STOPPED) && pw->p_exit==SIGTSTP) else if((pw->p_flag&P_STOPPED) && pw->p_exit==SIGTSTP)
{ {
job.parent = 0; job.parent = 0;
kill(shgd->current_pid,SIGTSTP); kill(sh.current_pid,SIGTSTP);
} }
#endif /* SIGTSTP */ #endif /* SIGTSTP */
} }
@ -1578,7 +1568,7 @@ int job_wait(register pid_t pid)
done: done:
if(!job.waitall && sh_isoption(SH_PIPEFAIL)) if(!job.waitall && sh_isoption(SH_PIPEFAIL))
return(nochild); return(nochild);
if(!shp->intrap) if(!sh.intrap)
{ {
job_lock(); job_lock();
for(pw=job.pwlist; pw; pw=px) for(pw=job.pwlist; pw; pw=px)
@ -1630,7 +1620,7 @@ int job_switch(register struct process *pw,int bgflag)
job.pwlist = pw; job.pwlist = pw;
msg = ""; msg = "";
} }
hist_list(shgd->hist_ptr,outfile,pw->p_name,'&',";"); hist_list(sh.hist_ptr,outfile,pw->p_name,'&',";");
sfputr(outfile,msg,'\n'); sfputr(outfile,msg,'\n');
sfsync(outfile); sfsync(outfile);
if(bgflag=='f') if(bgflag=='f')
@ -1705,7 +1695,7 @@ static struct process *job_unpost(register struct process *pwtop,int notify)
register struct process *pw; register struct process *pw;
/* make sure all processes are done */ /* make sure all processes are done */
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: drop pid=%d critical=%d pid=%d env=%u\n",__LINE__,shgd->current_pid,job.in_critical,pwtop->p_pid,pwtop->p_env); sfprintf(sfstderr,"ksh: job line %4d: drop pid=%d critical=%d pid=%d env=%u\n",__LINE__,sh.current_pid,job.in_critical,pwtop->p_pid,pwtop->p_env);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
pwtop = pw = job_byjid((int)pwtop->p_job); pwtop = pw = job_byjid((int)pwtop->p_job);
@ -1746,7 +1736,7 @@ static struct process *job_unpost(register struct process *pwtop,int notify)
} }
pwtop->p_pid = 0; pwtop->p_pid = 0;
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: free pid=%d critical=%d job=%d\n",__LINE__,shgd->current_pid,job.in_critical,pwtop->p_job); sfprintf(sfstderr,"ksh: job line %4d: free pid=%d critical=%d job=%d\n",__LINE__,sh.current_pid,job.in_critical,pwtop->p_job);
sfsync(sfstderr); sfsync(sfstderr);
#endif /* DEBUG */ #endif /* DEBUG */
job_free((int)pwtop->p_job); job_free((int)pwtop->p_job);
@ -1783,13 +1773,13 @@ static int job_alloc(void)
register int j=0; register int j=0;
register unsigned mask = 1; register unsigned mask = 1;
register unsigned char *freeword; register unsigned char *freeword;
register int jmax = BYTE(shgd->lim.child_max); register int jmax = BYTE(sh.lim.child_max);
/* skip to first word with a free slot */ /* skip to first word with a free slot */
for(j=0;job.freejobs[j] == UCHAR_MAX; j++); for(j=0;job.freejobs[j] == UCHAR_MAX; j++);
if(j >= jmax) if(j >= jmax)
{ {
register struct process *pw; register struct process *pw;
for(j=1; j < shgd->lim.child_max; j++) for(j=1; j < sh.lim.child_max; j++)
{ {
if((pw=job_byjid(j))&& !job_unpost(pw,0)) if((pw=job_byjid(j))&& !job_unpost(pw,0))
break; break;
@ -1821,16 +1811,16 @@ static void job_free(register int n)
static char *job_sigmsg(int sig) static char *job_sigmsg(int sig)
{ {
static char signo[40]; static char signo[40];
if(sig<=shgd->sigmax && shgd->sigmsg[sig]) if(sig<=sh.sigmax && sh.sigmsg[sig])
return(shgd->sigmsg[sig]); return(sh.sigmsg[sig]);
#if defined(SIGRTMIN) && defined(SIGRTMAX) #if defined(SIGRTMIN) && defined(SIGRTMAX)
if(sig>=sh.gd->sigruntime[SH_SIGRTMIN] && sig<=sh.gd->sigruntime[SH_SIGRTMAX]) if(sig>=sh.sigruntime[SH_SIGRTMIN] && sig<=sh.sigruntime[SH_SIGRTMAX])
{ {
static char sigrt[20]; static char sigrt[20];
if(sig>sh.gd->sigruntime[SH_SIGRTMIN]+(sh.gd->sigruntime[SH_SIGRTMAX]-sig<=sh.gd->sigruntime[SH_SIGRTMIN])/2) if(sig>sh.sigruntime[SH_SIGRTMIN]+(sh.sigruntime[SH_SIGRTMAX]-sig<=sh.sigruntime[SH_SIGRTMIN])/2)
sfsprintf(sigrt,sizeof(sigrt),"SIGRTMAX-%d",sh.gd->sigruntime[SH_SIGRTMAX]-sig); sfsprintf(sigrt,sizeof(sigrt),"SIGRTMAX-%d",sh.sigruntime[SH_SIGRTMAX]-sig);
else else
sfsprintf(sigrt,sizeof(sigrt),"SIGRTMIN+%d",sig-sh.gd->sigruntime[SH_SIGRTMIN]); sfsprintf(sigrt,sizeof(sigrt),"SIGRTMIN+%d",sig-sh.sigruntime[SH_SIGRTMIN]);
return(sigrt); return(sigrt);
} }
#endif #endif
@ -1925,7 +1915,7 @@ void job_subrestore(void* ptr)
bck.list = bp->list; bck.list = bp->list;
bck.count += bp->count; bck.count += bp->count;
bck.prev = bp->prev; bck.prev = bp->prev;
while(bck.count > shgd->lim.child_max) while(bck.count > sh.lim.child_max)
job_chksave(0); job_chksave(0);
for(pw=job.pwlist; pw; pw=pwnext) for(pw=job.pwlist; pw; pw=pwnext)
{ {
@ -1949,7 +1939,7 @@ int sh_waitsafe(void)
void job_fork(pid_t parent) void job_fork(pid_t parent)
{ {
#ifdef DEBUG #ifdef DEBUG
sfprintf(sfstderr,"ksh: job line %4d: fork pid=%d critical=%d parent=%d\n",__LINE__,shgd->current_pid,job.in_critical,parent); sfprintf(sfstderr,"ksh: job line %4d: fork pid=%d critical=%d parent=%d\n",__LINE__,sh.current_pid,job.in_critical,parent);
#endif /* DEBUG */ #endif /* DEBUG */
switch (parent) switch (parent)
{ {

View file

@ -69,6 +69,7 @@ local_iswblank(wchar_t wc)
#define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level]) #define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level])
static char *fmttoken(Lex_t*, int); static char *fmttoken(Lex_t*, int);
static struct argnod *endword(int);
static int alias_exceptf(Sfio_t*, int, void*, Sfdisc_t*); static int alias_exceptf(Sfio_t*, int, void*, Sfdisc_t*);
static void setupalias(Lex_t*,const char*, Namval_t*); static void setupalias(Lex_t*,const char*, Namval_t*);
static int comsub(Lex_t*,int); static int comsub(Lex_t*,int);
@ -81,8 +82,6 @@ static const Sfdisc_t alias_disc = { NULL, NULL, NULL, alias_exceptf, NULL };
static void refvar(Lex_t *lp, int type) static void refvar(Lex_t *lp, int type)
{ {
register Shell_t *shp = lp->sh;
register Stk_t *stkp = shp->stk;
off_t off = (fcseek(0)-(type+1))-(lp->lexd.first?lp->lexd.first:fcfirst()); off_t off = (fcseek(0)-(type+1))-(lp->lexd.first?lp->lexd.first:fcfirst());
unsigned long r; unsigned long r;
if(lp->lexd.first) if(lp->lexd.first)
@ -92,16 +91,16 @@ static void refvar(Lex_t *lp, int type)
} }
else else
{ {
int n,offset = stktell(stkp); int n,offset = stktell(sh.stk);
char *savptr,*begin; char *savptr,*begin;
off = offset + (fcseek(0)-(type+1)) - fcfirst(); off = offset + (fcseek(0)-(type+1)) - fcfirst();
if(lp->lexd.kiaoff < offset) if(lp->lexd.kiaoff < offset)
{ {
/* variable starts on stak, copy remainder */ /* variable starts on stak, copy remainder */
if(off>offset) if(off>offset)
sfwrite(stkp,fcfirst()+type,off-offset); sfwrite(sh.stk,fcfirst()+type,off-offset);
n = stktell(stkp)-lp->lexd.kiaoff; n = stktell(sh.stk)-lp->lexd.kiaoff;
begin = stkptr(stkp,lp->lexd.kiaoff); begin = stkptr(sh.stk,lp->lexd.kiaoff);
} }
else else
{ {
@ -109,11 +108,11 @@ static void refvar(Lex_t *lp, int type)
begin = fcfirst()+(type+lp->lexd.kiaoff-offset); begin = fcfirst()+(type+lp->lexd.kiaoff-offset);
n = off-lp->lexd.kiaoff; n = off-lp->lexd.kiaoff;
} }
savptr = stkfreeze(stkp,0); savptr = stkfreeze(sh.stk,0);
r=kiaentity(lp,begin,n,'v',-1,-1,lp->current,'v',0,""); r=kiaentity(lp,begin,n,'v',-1,-1,lp->current,'v',0,"");
stkset(stkp,savptr,offset); stkset(sh.stk,savptr,offset);
} }
sfprintf(lp->kiatmp,"p;%..64d;v;%..64d;%d;%d;r;\n",lp->current,r,shp->inlineno,shp->inlineno); sfprintf(lp->kiatmp,"p;%..64d;v;%..64d;%d;%d;r;\n",lp->current,r,sh.inlineno,sh.inlineno);
} }
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
@ -124,14 +123,12 @@ static void refvar(Lex_t *lp, int type)
static void lex_advance(Sfio_t *iop, const char *buff, register int size, void *context) static void lex_advance(Sfio_t *iop, const char *buff, register int size, void *context)
{ {
register Lex_t *lp = (Lex_t*)context; register Lex_t *lp = (Lex_t*)context;
register Shell_t *shp = lp->sh; register Sfio_t *log= sh.funlog;
register Sfio_t *log= shp->funlog;
Stk_t *stkp = shp->stk;
/* write to history file and to stderr if necessary */ /* write to history file and to stderr if necessary */
if(iop && !sfstacked(iop)) if(iop && !sfstacked(iop))
{ {
if(sh_isstate(SH_HISTORY) && shp->gd->hist_ptr) if(sh_isstate(SH_HISTORY) && sh.hist_ptr)
log = shp->gd->hist_ptr->histfp; log = sh.hist_ptr->histfp;
sfwrite(log, (void*)buff, size); sfwrite(log, (void*)buff, size);
if(sh_isstate(SH_VERBOSE)) if(sh_isstate(SH_VERBOSE))
sfwrite(sfstderr, buff, size); sfwrite(sfstderr, buff, size);
@ -141,7 +138,7 @@ static void lex_advance(Sfio_t *iop, const char *buff, register int size, void *
if(lp->lexd.dolparen && lp->lexd.docword && lp->lexd.docend) if(lp->lexd.dolparen && lp->lexd.docword && lp->lexd.docend)
{ {
int n = size - (lp->lexd.docend-(char*)buff); int n = size - (lp->lexd.docend-(char*)buff);
sfwrite(shp->strbuf,lp->lexd.docend,n); sfwrite(sh.strbuf,lp->lexd.docend,n);
lp->lexd.docextra += n; lp->lexd.docextra += n;
if(sffileno(iop)>=0) if(sffileno(iop)>=0)
lp->lexd.docend = sfsetbuf(iop,(void*)iop,0); lp->lexd.docend = sfsetbuf(iop,(void*)iop,0);
@ -153,14 +150,14 @@ static void lex_advance(Sfio_t *iop, const char *buff, register int size, void *
size -= (lp->lexd.first-(char*)buff); size -= (lp->lexd.first-(char*)buff);
buff = lp->lexd.first; buff = lp->lexd.first;
if(!lp->lexd.noarg) if(!lp->lexd.noarg)
lp->arg = (struct argnod*)stkseek(stkp,ARGVAL); lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
#if SHOPT_KIA #if SHOPT_KIA
lp->lexd.kiaoff += ARGVAL; lp->lexd.kiaoff += ARGVAL;
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
} }
if(size>0 && (lp->arg||lp->lexd.noarg)) if(size>0 && (lp->arg||lp->lexd.noarg))
{ {
sfwrite(stkp,buff,size); sfwrite(sh.stk,buff,size);
lp->lexd.first = 0; lp->lexd.first = 0;
} }
} }
@ -201,13 +198,10 @@ static int lexfill(Lex_t *lp)
/* /*
* mode=1 for reinitialization * mode=1 for reinitialization
*/ */
Lex_t *sh_lexopen(Lex_t *lp, Shell_t *sp, int mode) Lex_t *sh_lexopen(Lex_t *lp, int mode)
{ {
if(!lp) if(!lp)
{
lp = (Lex_t*)sh_newof(0,Lex_t,1,0); lp = (Lex_t*)sh_newof(0,Lex_t,1,0);
lp->sh = sp;
}
fcnotify(lex_advance,lp); fcnotify(lex_advance,lp);
lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 0; lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 0;
lp->comp_assign = 0; lp->comp_assign = 0;
@ -230,7 +224,6 @@ Lex_t *sh_lexopen(Lex_t *lp, Shell_t *sp, int mode)
extern int lextoken(Lex_t*); extern int lextoken(Lex_t*);
int sh_lex(Lex_t *lp) int sh_lex(Lex_t *lp)
{ {
Shell_t *shp = lp->sh;
register int flag; register int flag;
char *quoted, *macro, *split, *expand; char *quoted, *macro, *split, *expand;
register int tok = lextoken(lp); register int tok = lextoken(lp);
@ -244,7 +237,7 @@ int sh_lex(Lex_t *lp)
if(flag&ARG_QUOTED) if(flag&ARG_QUOTED)
quoted = "quoted:"; quoted = "quoted:";
} }
sfprintf(sfstderr,"%d: line %d: %o:%s%s%s%s %s\n",shgd->current_pid,shp->inlineno,tok,quoted, sfprintf(sfstderr,"%d: line %d: %o:%s%s%s%s %s\n",sh.current_pid,sh.inlineno,tok,quoted,
macro, split, expand, fmttoken(lp,tok)); macro, split, expand, fmttoken(lp,tok));
return(tok); return(tok);
} }
@ -258,10 +251,8 @@ int sh_lex(Lex_t *lp)
*/ */
int sh_lex(Lex_t* lp) int sh_lex(Lex_t* lp)
{ {
register Shell_t *shp = lp->sh;
register const char *state; register const char *state;
register int n, c, mode=ST_BEGIN, wordflags=0; register int n, c, mode=ST_BEGIN, wordflags=0;
Stk_t *stkp = shp->stk;
int inlevel=lp->lexd.level, assignment=0, ingrave=0; int inlevel=lp->lexd.level, assignment=0, ingrave=0;
int epatchar=0; int epatchar=0;
#if SHOPT_MULTIBYTE #if SHOPT_MULTIBYTE
@ -316,7 +307,7 @@ int sh_lex(Lex_t* lp)
else else
lp->lexd.first = 0; lp->lexd.first = 0;
} }
lp->lastline = lp->sh->inlineno; lp->lastline = sh.inlineno;
while(1) while(1)
{ {
/* skip over characters in the current state */ /* skip over characters in the current state */
@ -342,11 +333,11 @@ int sh_lex(Lex_t* lp)
/* check for zero byte in file */ /* check for zero byte in file */
if(n==0 && fcfile()) if(n==0 && fcfile())
{ {
if(shp->readscript) if(sh.readscript)
{ {
char *cp = error_info.id; char *cp = error_info.id;
errno = ENOEXEC; errno = ENOEXEC;
error_info.id = shp->readscript; error_info.id = sh.readscript;
errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,cp); errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,cp);
UNREACHABLE(); UNREACHABLE();
} }
@ -400,10 +391,10 @@ int sh_lex(Lex_t* lp)
while(fcgetc(c)>0 && c!='\n'); while(fcgetc(c)>0 && c!='\n');
if(c<=0 || lp->heredoc) if(c<=0 || lp->heredoc)
{ {
shp->inlineno++; sh.inlineno++;
break; break;
} }
while(shp->inlineno++,fcpeek(0)=='\n') while(sh.inlineno++,fcpeek(0)=='\n')
fcseek(1); fcseek(1);
while(state[c=fcpeek(0)]==0) while(state[c=fcpeek(0)]==0)
fcseek(1); fcseek(1);
@ -413,7 +404,7 @@ int sh_lex(Lex_t* lp)
if(c<0) if(c<0)
return(lp->token=EOFSYM); return(lp->token=EOFSYM);
n = S_NLTOK; n = S_NLTOK;
shp->inlineno--; sh.inlineno--;
/* FALLTHROUGH */ /* FALLTHROUGH */
case S_NLTOK: case S_NLTOK:
/* check for here-document */ /* check for here-document */
@ -421,7 +412,7 @@ int sh_lex(Lex_t* lp)
{ {
if(!lp->lexd.dolparen) if(!lp->lexd.dolparen)
lp->lexd.nocopy++; lp->lexd.nocopy++;
c = shp->inlineno; c = sh.inlineno;
if(here_copy(lp,lp->heredoc)<=0 && lp->lasttok) if(here_copy(lp,lp->heredoc)<=0 && lp->lasttok)
{ {
lp->lasttok = IODOCSYM; lp->lasttok = IODOCSYM;
@ -439,7 +430,7 @@ int sh_lex(Lex_t* lp)
case S_NL: case S_NL:
/* skip over new-lines */ /* skip over new-lines */
lp->lex.last_quote = 0; lp->lex.last_quote = 0;
while(shp->inlineno++,fcget()=='\n'); while(sh.inlineno++,fcget()=='\n');
fcseek(-LEN); fcseek(-LEN);
if(n==S_NLTOK) if(n==S_NLTOK)
{ {
@ -498,7 +489,7 @@ int sh_lex(Lex_t* lp)
if(lp->lex.intest) if(lp->lex.intest)
return(c); return(c);
lp->lexd.nest=1; lp->lexd.nest=1;
lp->lastline = shp->inlineno; lp->lastline = sh.inlineno;
lp->lexd.lex_state = ST_NESTED; lp->lexd.lex_state = ST_NESTED;
fcseek(1); fcseek(1);
return(sh_lex(lp)); return(sh_lex(lp));
@ -568,7 +559,7 @@ int sh_lex(Lex_t* lp)
else else
{ {
if(lp->lexd.warn && (n=fcpeek(0))!=RPAREN && n!=' ' && n!='\t') if(lp->lexd.warn && (n=fcpeek(0))!=RPAREN && n!=' ' && n!='\t')
errormsg(SH_DICT,ERROR_warn(0),e_lexspace,shp->inlineno,c,n); errormsg(SH_DICT,ERROR_warn(0),e_lexspace,sh.inlineno,c,n);
} }
} }
if(c==LPAREN && lp->comp_assign && !lp->lex.intest && !lp->lex.incase) if(c==LPAREN && lp->comp_assign && !lp->lex.intest && !lp->lex.incase)
@ -596,7 +587,7 @@ int sh_lex(Lex_t* lp)
{ {
Sfio_t *sp; Sfio_t *sp;
struct argnod *ap; struct argnod *ap;
shp->inlineno++; sh.inlineno++;
/* synchronize */ /* synchronize */
if(!(sp=fcfile())) if(!(sp=fcfile()))
state=fcseek(0); state=fcseek(0);
@ -607,8 +598,8 @@ int sh_lex(Lex_t* lp)
else else
fcsopen((char*)state); fcsopen((char*)state);
/* remove \new-line */ /* remove \new-line */
n = stktell(stkp)-c; n = stktell(sh.stk)-c;
stkseek(stkp,n); stkseek(sh.stk,n);
lp->arg = ap; lp->arg = ap;
if(n<=ARGVAL) if(n<=ARGVAL)
{ {
@ -625,7 +616,7 @@ int sh_lex(Lex_t* lp)
endchar(lp)==RBRACE && endchar(lp)==RBRACE &&
sh_lexstates[ST_DOL][n]==S_DIG sh_lexstates[ST_DOL][n]==S_DIG
) )
errormsg(SH_DICT,ERROR_warn(0),e_lexfuture,shp->inlineno,n); errormsg(SH_DICT,ERROR_warn(0),e_lexfuture,sh.inlineno,n);
#endif /* STR_MAXIMAL */ #endif /* STR_MAXIMAL */
break; break;
case S_NAME: case S_NAME:
@ -683,7 +674,7 @@ int sh_lex(Lex_t* lp)
/* skip new-line joining */ /* skip new-line joining */
if(c=='\\' && fcpeek(0)=='\n') if(c=='\\' && fcpeek(0)=='\n')
{ {
shp->inlineno++; sh.inlineno++;
fcseek(1); fcseek(1);
continue; continue;
} }
@ -718,23 +709,23 @@ int sh_lex(Lex_t* lp)
if(oldmode(lp)==ST_QUOTE) /* $' within "" or `` */ if(oldmode(lp)==ST_QUOTE) /* $' within "" or `` */
{ {
if(lp->lexd.warn) if(lp->lexd.warn)
errormsg(SH_DICT,ERROR_warn(0),e_lexslash,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexslash,sh.inlineno);
mode = ST_LIT; mode = ST_LIT;
} }
} }
if(mode!=ST_LIT) if(mode!=ST_LIT)
{ {
if(lp->lexd.warn && lp->lex.last_quote && shp->inlineno > lp->lastline && fcpeek(-2)!='$') if(lp->lexd.warn && lp->lex.last_quote && sh.inlineno > lp->lastline && fcpeek(-2)!='$')
errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote); errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote);
lp->lex.last_quote = 0; lp->lex.last_quote = 0;
lp->lastline = shp->inlineno; lp->lastline = sh.inlineno;
if(mode!=ST_DOL) if(mode!=ST_DOL)
pushlevel(lp,'\'',mode); pushlevel(lp,'\'',mode);
mode = ST_LIT; mode = ST_LIT;
continue; continue;
} }
/* check for multi-line single-quoted string */ /* check for multi-line single-quoted string */
else if(shp->inlineno > lp->lastline) else if(sh.inlineno > lp->lastline)
lp->lex.last_quote = '\''; lp->lex.last_quote = '\'';
mode = oldmode(lp); mode = oldmode(lp);
poplevel(lp); poplevel(lp);
@ -745,12 +736,12 @@ int sh_lex(Lex_t* lp)
{ {
fcgetc(n); fcgetc(n);
if(n=='\n') if(n=='\n')
shp->inlineno++; sh.inlineno++;
} }
continue; continue;
case S_GRAVE: case S_GRAVE:
if(lp->lexd.warn && (mode!=ST_QUOTE || endchar(lp)!='`')) if(lp->lexd.warn && (mode!=ST_QUOTE || endchar(lp)!='`'))
errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete1,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete1,sh.inlineno);
wordflags |=(ARG_MAC|ARG_EXP); wordflags |=(ARG_MAC|ARG_EXP);
if(mode==ST_QUOTE) if(mode==ST_QUOTE)
ingrave = !ingrave; ingrave = !ingrave;
@ -767,10 +758,10 @@ int sh_lex(Lex_t* lp)
{ {
if(c!='"' || mode!=ST_QNEST) if(c!='"' || mode!=ST_QNEST)
{ {
if(lp->lexd.warn && lp->lex.last_quote && shp->inlineno > lp->lastline) if(lp->lexd.warn && lp->lex.last_quote && sh.inlineno > lp->lastline)
errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote); errormsg(SH_DICT,ERROR_warn(0),e_lexlongquote,lp->lastline,lp->lex.last_quote);
lp->lex.last_quote=0; lp->lex.last_quote=0;
lp->lastline = shp->inlineno; lp->lastline = sh.inlineno;
pushlevel(lp,c,mode); pushlevel(lp,c,mode);
} }
ingrave ^= (c=='`'); ingrave ^= (c=='`');
@ -779,7 +770,7 @@ int sh_lex(Lex_t* lp)
} }
else if((n=endchar(lp))==c) else if((n=endchar(lp))==c)
{ {
if(shp->inlineno > lp->lastline) if(sh.inlineno > lp->lastline)
lp->lex.last_quote = c; lp->lex.last_quote = c;
mode = oldmode(lp); mode = oldmode(lp);
poplevel(lp); poplevel(lp);
@ -795,7 +786,7 @@ int sh_lex(Lex_t* lp)
if(lp->lexd.first) if(lp->lexd.first)
lp->lexd.kiaoff = fcseek(0)-lp->lexd.first; lp->lexd.kiaoff = fcseek(0)-lp->lexd.first;
else else
lp->lexd.kiaoff = stktell(stkp)+fcseek(0)-fcfirst(); lp->lexd.kiaoff = stktell(sh.stk)+fcseek(0)-fcfirst();
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
pushlevel(lp,'$',mode); pushlevel(lp,'$',mode);
mode = ST_DOL; mode = ST_DOL;
@ -826,7 +817,7 @@ int sh_lex(Lex_t* lp)
refvar(lp,0); refvar(lp,0);
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
if(lp->lexd.warn && c==LBRACT && !lp->lex.intest && !lp->lexd.arith && oldmode(lp)!= ST_NESTED) if(lp->lexd.warn && c==LBRACT && !lp->lex.intest && !lp->lexd.arith && oldmode(lp)!= ST_NESTED)
errormsg(SH_DICT,ERROR_warn(0),e_lexusebrace,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexusebrace,sh.inlineno);
fcseek(-LEN); fcseek(-LEN);
mode = oldmode(lp); mode = oldmode(lp);
poplevel(lp); poplevel(lp);
@ -957,7 +948,7 @@ int sh_lex(Lex_t* lp)
sh_syntax(lp); sh_syntax(lp);
} }
else if(lp->lexd.warn) else if(lp->lexd.warn)
errormsg(SH_DICT,ERROR_warn(0),e_lexquote,shp->inlineno,'%'); errormsg(SH_DICT,ERROR_warn(0),e_lexquote,sh.inlineno,'%');
} }
} }
} }
@ -992,7 +983,7 @@ int sh_lex(Lex_t* lp)
else else
{ {
if(lp->lexd.warn && c!='/' && sh_lexstates[ST_NORM][c]!=S_BREAK && (c!='"' || mode==ST_QUOTE)) if(lp->lexd.warn && c!='/' && sh_lexstates[ST_NORM][c]!=S_BREAK && (c!='"' || mode==ST_QUOTE))
errormsg(SH_DICT,ERROR_warn(0),e_lexslash,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexslash,sh.inlineno);
else if(c=='"' && mode!=ST_QUOTE && !ingrave) else if(c=='"' && mode!=ST_QUOTE && !ingrave)
wordflags |= ARG_MESSAGE; wordflags |= ARG_MESSAGE;
fcseek(-LEN); fcseek(-LEN);
@ -1000,7 +991,7 @@ int sh_lex(Lex_t* lp)
continue; continue;
case S_META: case S_META:
if(lp->lexd.warn && endchar(lp)==RBRACE && !lp->lexd.nested_tilde) if(lp->lexd.warn && endchar(lp)==RBRACE && !lp->lexd.nested_tilde)
errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,shp->inlineno,c); errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,sh.inlineno,c);
continue; continue;
case S_PUSH: case S_PUSH:
fcgetc(n); fcgetc(n);
@ -1045,13 +1036,13 @@ int sh_lex(Lex_t* lp)
if(c==';' && n!=';') if(c==';' && n!=';')
{ {
if(lp->lexd.warn && n==RBRACE) if(lp->lexd.warn && n==RBRACE)
errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,shp->inlineno,c); errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,sh.inlineno,c);
continue; continue;
} }
if(mode==ST_QNEST) if(mode==ST_QNEST)
{ {
if(lp->lexd.warn) if(lp->lexd.warn)
errormsg(SH_DICT,ERROR_warn(0),e_lexescape,shp->inlineno,c); errormsg(SH_DICT,ERROR_warn(0),e_lexescape,sh.inlineno,c);
continue; continue;
} }
mode = oldmode(lp); mode = oldmode(lp);
@ -1075,7 +1066,7 @@ int sh_lex(Lex_t* lp)
/* backward compatibility */ /* backward compatibility */
{ {
if(lp->lexd.warn) if(lp->lexd.warn)
errormsg(SH_DICT,ERROR_warn(0),e_lexnested,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexnested,sh.inlineno);
if(!(state=lp->lexd.first)) if(!(state=lp->lexd.first))
state = fcfirst(); state = fcfirst();
else else
@ -1135,7 +1126,7 @@ int sh_lex(Lex_t* lp)
{ {
if(mode==ST_NAME) if(mode==ST_NAME)
{ {
errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1, shp->inlineno, "[]", "empty subscript"); errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1, sh.inlineno, "[]", "empty subscript");
UNREACHABLE(); UNREACHABLE();
} }
if(!epatchar || epatchar=='%') if(!epatchar || epatchar=='%')
@ -1224,7 +1215,7 @@ int sh_lex(Lex_t* lp)
continue; continue;
} }
if(lp->lexd.warn && c=='[' && n=='^') if(lp->lexd.warn && c=='[' && n=='^')
errormsg(SH_DICT,ERROR_warn(0),e_lexcharclass,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexcharclass,sh.inlineno);
if(n>0) if(n>0)
fcseek(-LEN); fcseek(-LEN);
if(n=='=' && c=='+' && mode==ST_NAME) if(n=='=' && c=='+' && mode==ST_NAME)
@ -1251,13 +1242,13 @@ breakloop:
state = fcfirst(); state = fcfirst();
n = fcseek(0)-(char*)state; n = fcseek(0)-(char*)state;
if(!lp->arg) if(!lp->arg)
lp->arg = (struct argnod*)stkseek(stkp,ARGVAL); lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
if(n>0) if(n>0)
sfwrite(stkp,state,n); sfwrite(sh.stk,state,n);
sfputc(stkp,0); sfputc(sh.stk,0);
stkseek(stkp,stktell(stkp)-1); stkseek(sh.stk,stktell(sh.stk)-1);
state = stkptr(stkp,ARGVAL); state = stkptr(sh.stk,ARGVAL);
n = stktell(stkp)-ARGVAL; n = stktell(sh.stk)-ARGVAL;
lp->lexd.first=0; lp->lexd.first=0;
if(n==1) if(n==1)
{ {
@ -1284,8 +1275,8 @@ breakloop:
if(!strchr(state,',')) if(!strchr(state,','))
{ {
/* Redirection of the form {varname}>file, etc. */ /* Redirection of the form {varname}>file, etc. */
stkseek(stkp,stktell(stkp)-1); stkseek(sh.stk,stktell(sh.stk)-1);
lp->arg = (struct argnod*)stkfreeze(stkp,1); lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
return(lp->token=IOVNAME); return(lp->token=IOVNAME);
} }
c = wordflags; c = wordflags;
@ -1294,8 +1285,8 @@ breakloop:
c = wordflags; c = wordflags;
if(assignment<0) if(assignment<0)
{ {
stkseek(stkp,stktell(stkp)-1); stkseek(sh.stk,stktell(sh.stk)-1);
lp->arg = (struct argnod*)stkfreeze(stkp,1); lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
lp->lex.reservok = 1; lp->lex.reservok = 1;
return(lp->token=LABLSYM); return(lp->token=LABLSYM);
} }
@ -1306,23 +1297,23 @@ breakloop:
if(mode==ST_NONE) if(mode==ST_NONE)
{ {
/* eliminate trailing )) */ /* eliminate trailing )) */
stkseek(stkp,stktell(stkp)-2); stkseek(sh.stk,stktell(sh.stk)-2);
} }
if(c&ARG_MESSAGE) if(c&ARG_MESSAGE)
{ {
if(sh_isoption(SH_DICTIONARY)) if(sh_isoption(SH_DICTIONARY))
lp->arg = sh_endword(shp,2); lp->arg = endword(2);
c |= ARG_MAC; c |= ARG_MAC;
} }
if(c==0 || (c&(ARG_MAC|ARG_EXP|ARG_MESSAGE))) if(c==0 || (c&(ARG_MAC|ARG_EXP|ARG_MESSAGE)))
{ {
lp->arg = (struct argnod*)stkfreeze(stkp,1); lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
lp->arg->argflag = (c?c:ARG_RAW); lp->arg->argflag = (c?c:ARG_RAW);
} }
else if(mode==ST_NONE) else if(mode==ST_NONE)
lp->arg = sh_endword(shp,-1); lp->arg = endword(-1);
else else
lp->arg = sh_endword(shp,0); lp->arg = endword(0);
state = lp->arg->argval; state = lp->arg->argval;
lp->comp_assign = assignment; lp->comp_assign = assignment;
if(assignment) if(assignment)
@ -1332,7 +1323,7 @@ breakloop:
{ {
char *cp = strchr(state, '='); char *cp = strchr(state, '=');
if(cp && strncmp(++cp, "$((", 3) == 0) if(cp && strncmp(++cp, "$((", 3) == 0)
errormsg(SH_DICT, ERROR_warn(0), e_lexarithwarn, shp->inlineno, errormsg(SH_DICT, ERROR_warn(0), e_lexarithwarn, sh.inlineno,
state, cp - state, state, cp + 3); state, cp - state, state, cp + 3);
} }
} }
@ -1351,7 +1342,7 @@ breakloop:
strchr(test_opchars,state[1])) strchr(test_opchars,state[1]))
{ {
if(lp->lexd.warn && state[1]=='a') if(lp->lexd.warn && state[1]=='a')
errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete2,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete2,sh.inlineno);
lp->digits = state[1]; lp->digits = state[1];
lp->token = TESTUNOP; lp->token = TESTUNOP;
} }
@ -1381,7 +1372,7 @@ breakloop:
{ {
case TEST_SEQ: case TEST_SEQ:
if(lp->lexd.warn && state[1]==0) if(lp->lexd.warn && state[1]==0)
errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete3,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete3,sh.inlineno);
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
if(lp->lex.testop2) if(lp->lex.testop2)
@ -1418,7 +1409,7 @@ breakloop:
break; break;
} }
errormsg(SH_DICT, ERROR_warn(0), e_lexobsolete4, errormsg(SH_DICT, ERROR_warn(0), e_lexobsolete4,
shp->inlineno, state, alt); sh.inlineno, state, alt);
} }
if(c&TEST_STRCMP) if(c&TEST_STRCMP)
lp->lex.incase = 1; lp->lex.incase = 1;
@ -1442,7 +1433,7 @@ breakloop:
if(n==1 && (c=='{' || c=='}' || c=='!')) if(n==1 && (c=='{' || c=='}' || c=='!'))
{ {
if(lp->lexd.warn && c=='{' && lp->lex.incase==2) if(lp->lexd.warn && c=='{' && lp->lex.incase==2)
errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete6,shp->inlineno); errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete6,sh.inlineno);
if(lp->lex.incase==1 && c==RBRACE) if(lp->lex.incase==1 && c==RBRACE)
lp->lex.incase = 0; lp->lex.incase = 0;
return(lp->token=c); return(lp->token=c);
@ -1494,7 +1485,7 @@ breakloop:
/* check for aliases */ /* check for aliases */
Namval_t* np; Namval_t* np;
if(!lp->lex.incase && !assignment && fcpeek(0)!=LPAREN && if(!lp->lex.incase && !assignment && fcpeek(0)!=LPAREN &&
(np=nv_search(state,shp->alias_tree,HASH_SCOPE)) (np=nv_search(state,sh.alias_tree,HASH_SCOPE))
&& !nv_isattr(np,NV_NOEXPAND) && !nv_isattr(np,NV_NOEXPAND)
&& (lp->aliasok!=2 || nv_isattr(np,BLT_DCL)) && (lp->aliasok!=2 || nv_isattr(np,BLT_DCL))
&& (!sh_isstate(SH_NOALIAS) || nv_isattr(np,NV_NOFREE)) && (!sh_isstate(SH_NOALIAS) || nv_isattr(np,NV_NOFREE))
@ -1520,14 +1511,14 @@ breakloop:
static int comsub(register Lex_t *lp, int endtok) static int comsub(register Lex_t *lp, int endtok)
{ {
register int n,c,count=1; register int n,c,count=1;
register int line=lp->sh->inlineno; register int line=sh.inlineno;
struct ionod *inheredoc = lp->heredoc; struct ionod *inheredoc = lp->heredoc;
char *first,*cp=fcseek(0),word[5]; char *first,*cp=fcseek(0),word[5];
int off, messages=0, assignok=lp->assignok, csub; int off, messages=0, assignok=lp->assignok, csub;
struct _shlex_pvt_lexstate_ save; struct _shlex_pvt_lexstate_ save;
save = lp->lex; save = lp->lex;
csub = lp->comsub; csub = lp->comsub;
sh_lexopen(lp,lp->sh,1); sh_lexopen(lp,1);
lp->lexd.dolparen++; lp->lexd.dolparen++;
lp->lex.incase=0; lp->lex.incase=0;
pushlevel(lp,0,0); pushlevel(lp,0,0);
@ -1659,7 +1650,7 @@ done:
if(lp->heredoc && !inheredoc) if(lp->heredoc && !inheredoc)
{ {
/* here-document isn't fully contained in command substitution */ /* here-document isn't fully contained in command substitution */
errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,lp->sh->inlineno,lp->heredoc->ioname); errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,sh.inlineno,lp->heredoc->ioname);
UNREACHABLE(); UNREACHABLE();
} }
return(messages); return(messages);
@ -1674,23 +1665,22 @@ static void nested_here(register Lex_t *lp)
register struct ionod *iop; register struct ionod *iop;
register int n=0,offset; register int n=0,offset;
struct argnod *arg = lp->arg; struct argnod *arg = lp->arg;
Stk_t *stkp = lp->sh->stk;
char *base; char *base;
if(offset=stktell(stkp)) if(offset=stktell(sh.stk))
base = stkfreeze(stkp,0); base = stkfreeze(sh.stk,0);
if(lp->lexd.docend) if(lp->lexd.docend)
n = fcseek(0)-lp->lexd.docend; n = fcseek(0)-lp->lexd.docend;
iop = sh_newof(0,struct ionod,1,lp->lexd.docextra+n+ARGVAL); iop = sh_newof(0,struct ionod,1,lp->lexd.docextra+n+ARGVAL);
iop->iolst = lp->heredoc; iop->iolst = lp->heredoc;
stkseek(stkp,ARGVAL); stkseek(sh.stk,ARGVAL);
if(lp->lexd.docextra) if(lp->lexd.docextra)
{ {
sfseek(lp->sh->strbuf,(Sfoff_t)0, SEEK_SET); sfseek(sh.strbuf,(Sfoff_t)0, SEEK_SET);
sfmove(lp->sh->strbuf,stkp,lp->lexd.docextra,-1); sfmove(sh.strbuf,sh.stk,lp->lexd.docextra,-1);
sfseek(lp->sh->strbuf,(Sfoff_t)0, SEEK_SET); sfseek(sh.strbuf,(Sfoff_t)0, SEEK_SET);
} }
sfwrite(stkp,lp->lexd.docend,n); sfwrite(sh.stk,lp->lexd.docend,n);
lp->arg = sh_endword(lp->sh,0); lp->arg = endword(0);
iop->ioname = (char*)(iop+1); iop->ioname = (char*)(iop+1);
strcpy(iop->ioname,lp->arg->argval); strcpy(iop->ioname,lp->arg->argval);
iop->iofile = (IODOC|IORAW); iop->iofile = (IODOC|IORAW);
@ -1700,9 +1690,9 @@ static void nested_here(register Lex_t *lp)
lp->arg = arg; lp->arg = arg;
lp->lexd.docword = 0; lp->lexd.docword = 0;
if(offset) if(offset)
stkset(stkp,base,offset); stkset(sh.stk,base,offset);
else else
stkseek(stkp,0); stkseek(sh.stk,0);
} }
/* /*
@ -1728,7 +1718,7 @@ void sh_lexskip(Lex_t *lp,int close, register int copy, int state)
if(!(cp=lp->lexd.first)) if(!(cp=lp->lexd.first))
cp = fcfirst(); cp = fcfirst();
if((copy = fcseek(0)-cp) > 0) if((copy = fcseek(0)-cp) > 0)
sfwrite(lp->sh->stk,cp,copy); sfwrite(sh.stk,cp,copy);
} }
else else
lp->lexd.nocopy--; lp->lexd.nocopy--;
@ -1769,13 +1759,13 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
register const char *state; register const char *state;
register int c,n; register int c,n;
register char *bufp,*cp; register char *bufp,*cp;
register Sfio_t *sp=lp->sh->heredocs, *funlog; register Sfio_t *sp=sh.heredocs, *funlog;
int stripcol=0,stripflg, nsave, special=0; int stripcol=0,stripflg, nsave, special=0;
if(funlog=lp->sh->funlog) if(funlog=sh.funlog)
{ {
if(fcfill()>0) if(fcfill()>0)
fcseek(-LEN); fcseek(-LEN);
lp->sh->funlog = 0; sh.funlog = 0;
} }
if(iop->iolst) if(iop->iolst)
here_copy(lp,iop->iolst); here_copy(lp,iop->iolst);
@ -1881,7 +1871,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
switch(n) switch(n)
{ {
case S_NL: case S_NL:
lp->sh->inlineno++; sh.inlineno++;
if((stripcol && c==' ') || (stripflg && c=='\t')) if((stripcol && c==' ') || (stripflg && c=='\t'))
{ {
if(!lp->lexd.dolparen) if(!lp->lexd.dolparen)
@ -1942,7 +1932,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
} }
#endif /* SHOPT_CRNL */ #endif /* SHOPT_CRNL */
if(c==NL) if(c==NL)
lp->sh->inlineno++; sh.inlineno++;
if(iop->iodelim[n]==0 && (c==NL||c==RPAREN)) if(iop->iodelim[n]==0 && (c==NL||c==RPAREN))
{ {
if(!lp->lexd.dolparen && (n=cp-bufp)) if(!lp->lexd.dolparen && (n=cp-bufp))
@ -1950,7 +1940,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
if((n=sfwrite(sp,bufp,n))>0) if((n=sfwrite(sp,bufp,n))>0)
iop->iosize += n; iop->iosize += n;
} }
lp->sh->inlineno--; sh.inlineno--;
if(c==RPAREN) if(c==RPAREN)
fcseek(-LEN); fcseek(-LEN);
goto done; goto done;
@ -1995,7 +1985,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
if(c==NL) if(c==NL)
{ {
/* new-line joining */ /* new-line joining */
lp->sh->inlineno++; sh.inlineno++;
if(!lp->lexd.dolparen && (n=(fcseek(0)-bufp)-n)>=0) if(!lp->lexd.dolparen && (n=(fcseek(0)-bufp)-n)>=0)
{ {
if(n && (n=sfwrite(sp,bufp,n))>0) if(n && (n=sfwrite(sp,bufp,n))>0)
@ -2016,7 +2006,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
n=0; n=0;
} }
done: done:
lp->sh->funlog = funlog; sh.funlog = funlog;
if(lp->lexd.dolparen) if(lp->lexd.dolparen)
free((void*)iop); free((void*)iop);
else if(!special) else if(!special)
@ -2088,7 +2078,6 @@ static char *fmttoken(Lex_t *lp, register int sym)
noreturn void sh_syntax(Lex_t *lp) noreturn void sh_syntax(Lex_t *lp)
{ {
register Shell_t *shp = lp->sh;
register const char *cp = sh_translate(e_unexpected); register const char *cp = sh_translate(e_unexpected);
register char *tokstr; register char *tokstr;
register int tok = lp->token; register int tok = lp->token;
@ -2099,9 +2088,9 @@ noreturn void sh_syntax(Lex_t *lp)
cp = sh_translate(e_unmatched); cp = sh_translate(e_unmatched);
} }
else else
lp->lastline = shp->inlineno; lp->lastline = sh.inlineno;
tokstr = fmttoken(lp,tok); tokstr = fmttoken(lp,tok);
if((sp=fcfile()) || (shp->infd>=0 && (sp=shp->sftable[shp->infd]))) if((sp=fcfile()) || (sh.infd>=0 && (sp=sh.sftable[sh.infd])))
{ {
/* clear out any pending input */ /* clear out any pending input */
register Sfio_t *top; register Sfio_t *top;
@ -2112,10 +2101,10 @@ noreturn void sh_syntax(Lex_t *lp)
} }
else else
fcclose(); fcclose();
shp->inlineno = lp->inlineno; sh.inlineno = lp->inlineno;
shp->st.firstline = lp->firstline; sh.st.firstline = lp->firstline;
/* reset lexer state */ /* reset lexer state */
sh_lexopen(lp, &sh, 0); sh_lexopen(lp, 0);
if(!sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_PROFILE)) if(!sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_PROFILE))
errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1,lp->lastline,tokstr,cp); errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1,lp->lastline,tokstr,cp);
else else
@ -2123,15 +2112,15 @@ noreturn void sh_syntax(Lex_t *lp)
UNREACHABLE(); UNREACHABLE();
} }
static char *stack_shift(Stk_t *stkp, register char *sp,char *dp) static char *stack_shift(register char *sp,char *dp)
{ {
register char *ep; register char *ep;
register int offset = stktell(stkp); register int offset = stktell(sh.stk);
register int left = offset-(sp-stkptr(stkp,0)); register int left = offset-(sp-stkptr(sh.stk,0));
register int shift = (dp+1-sp); register int shift = (dp+1-sp);
offset += shift; offset += shift;
stkseek(stkp,offset); stkseek(sh.stk,offset);
sp = stkptr(stkp,offset); sp = stkptr(sh.stk,offset);
ep = sp - shift; ep = sp - shift;
while(left--) while(left--)
*--sp = *--ep; *--sp = *--ep;
@ -2146,7 +2135,7 @@ static char *stack_shift(Stk_t *stkp, register char *sp,char *dp)
* The result is left on the stak * The result is left on the stak
* If mode==2, the each $"" string is printed on standard output * If mode==2, the each $"" string is printed on standard output
*/ */
struct argnod *sh_endword(Shell_t *shp,int mode) static struct argnod *endword(int mode)
{ {
register const char *state = sh_lexstates[ST_NESTED]; register const char *state = sh_lexstates[ST_NESTED];
register int n; register int n;
@ -2155,9 +2144,8 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
struct argnod* argp=0; struct argnod* argp=0;
char *ep=0, *xp=0; char *ep=0, *xp=0;
int bracket=0; int bracket=0;
Stk_t *stkp=shp->stk; sfputc(sh.stk,0);
sfputc(stkp,0); sp = stkptr(sh.stk,ARGVAL);
sp = stkptr(stkp,ARGVAL);
if(mbwide()) if(mbwide())
{ {
do do
@ -2196,10 +2184,10 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
switch(n) switch(n)
{ {
case S_EOF: case S_EOF:
stkseek(stkp,dp-stkptr(stkp,0)); stkseek(sh.stk,dp-stkptr(sh.stk,0));
if(mode<=0) if(mode<=0)
{ {
argp = (struct argnod*)stkfreeze(stkp,0); argp = (struct argnod*)stkfreeze(sh.stk,0);
argp->argflag = ARG_RAW|ARG_QUOTED; argp->argflag = ARG_RAW|ARG_QUOTED;
} }
return(argp); return(argp);
@ -2243,7 +2231,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
dp = ep+n; dp = ep+n;
if(sp-dp <= 1) if(sp-dp <= 1)
{ {
sp = stack_shift(stkp,sp,dp); sp = stack_shift(sp,dp);
dp = sp-1; dp = sp-1;
ep = dp-n; ep = dp-n;
} }
@ -2292,7 +2280,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
{ {
if(dp>=sp) if(dp>=sp)
{ {
sp = stack_shift(stkp,sp,dp+1); sp = stack_shift(sp,dp+1);
dp = sp-2; dp = sp-2;
} }
*dp++ = '\\'; *dp++ = '\\';
@ -2328,7 +2316,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
dp[-1] = '\\'; dp[-1] = '\\';
if(dp>=sp) if(dp>=sp)
{ {
sp = stack_shift(stkp,sp,dp); sp = stack_shift(sp,dp);
dp = sp-1; dp = sp-1;
} }
*dp++ = ']'; *dp++ = ']';
@ -2344,7 +2332,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
dp[-1] = '\\'; dp[-1] = '\\';
if(dp>=sp) if(dp>=sp)
{ {
sp = stack_shift(stkp,sp,dp); sp = stack_shift(sp,dp);
dp = sp-1; dp = sp-1;
} }
*dp++ = '['; *dp++ = '[';
@ -2455,7 +2443,7 @@ static void setupalias(Lex_t *lp, const char *string,Namval_t *np)
{ {
unsigned long r; unsigned long r;
r=kiaentity(lp,nv_name(np),-1,'p',0,0,lp->current,'a',0,""); r=kiaentity(lp,nv_name(np),-1,'p',0,0,lp->current,'a',0,"");
sfprintf(lp->kiatmp,"p;%..64d;p;%..64d;%d;%d;e;\n",lp->current,r,lp->sh->inlineno,lp->sh->inlineno); sfprintf(lp->kiatmp,"p;%..64d;p;%..64d;%d;%d;e;\n",lp->current,r,sh.inlineno,sh.inlineno);
} }
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
if((ap->nextc=fcget())==0) if((ap->nextc=fcget())==0)

View file

@ -58,7 +58,6 @@
static int _c_; static int _c_;
typedef struct _mac_ typedef struct _mac_
{ {
Shell_t *shp; /* pointer to shell interpreter */
Sfio_t *sp; /* stream pointer for here-document */ Sfio_t *sp; /* stream pointer for here-document */
struct argnod **arghead; /* address of head of argument list */ struct argnod **arghead; /* address of head of argument list */
char *ifsp; /* pointer to IFS value */ char *ifsp; /* pointer to IFS value */
@ -102,9 +101,9 @@ static void copyto(Mac_t*, int, int);
static void comsubst(Mac_t*, Shnode_t*, int); static void comsubst(Mac_t*, Shnode_t*, int);
static int varsub(Mac_t*); static int varsub(Mac_t*);
static void mac_copy(Mac_t*,const char*, int); static void mac_copy(Mac_t*,const char*, int);
static void tilde_expand2(Shell_t*,int); static void tilde_expand2(int);
static char *sh_tilde(Shell_t*,const char*); static char *sh_tilde(const char*);
static char *special(Shell_t *,int); static char *special(int);
static void endfield(Mac_t*,int); static void endfield(Mac_t*,int);
static char *mac_getstring(char*); static char *mac_getstring(char*);
static int charlen(const char*,int); static int charlen(const char*,int);
@ -114,33 +113,30 @@ static int charlen(const char*,int);
# define lastchar(string,endstring) (endstring) # define lastchar(string,endstring) (endstring)
#endif /* SHOPT_MULTIBYTE */ #endif /* SHOPT_MULTIBYTE */
void *sh_macopen(Shell_t *shp) void *sh_macopen(void)
{ {
void *addr = sh_newof(0,Mac_t,1,0); return(sh_newof(0,Mac_t,1,0));
Mac_t *mp = (Mac_t*)addr;
mp->shp = shp;
return(addr);
} }
/* /*
* perform only parameter substitution and catch failures * perform only parameter substitution and catch failures
* (also save lexer state to allow use while in here-docs) * (also save lexer state to allow use while in here-docs)
*/ */
char *sh_mactry(Shell_t *shp,register char *string) char *sh_mactry(register char *string)
{ {
if(string) if(string)
{ {
int jmp_val; int jmp_val;
int savexit = shp->savexit; int savexit = sh.savexit;
struct checkpt buff; struct checkpt buff;
Lex_t *lexp = (Lex_t*)sh.lex_context, savelex = *lexp; Lex_t *lexp = (Lex_t*)sh.lex_context, savelex = *lexp;
sh_pushcontext(shp,&buff,SH_JMPSUB); sh_pushcontext(&sh,&buff,SH_JMPSUB);
jmp_val = sigsetjmp(buff.buff,0); jmp_val = sigsetjmp(buff.buff,0);
if(jmp_val == 0) if(jmp_val == 0)
string = sh_mactrim(shp,string,0); string = sh_mactrim(string,0);
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
*lexp = savelex; *lexp = savelex;
shp->savexit = savexit; sh.savexit = savexit;
return(string); return(string);
} }
return(""); return("");
@ -153,15 +149,15 @@ char *sh_mactry(Shell_t *shp,register char *string)
* yields a single pathname. * yields a single pathname.
* If <mode> negative, then expansion rules for assignment are applied. * If <mode> negative, then expansion rules for assignment are applied.
*/ */
char *sh_mactrim(Shell_t *shp, char *str, register int mode) char *sh_mactrim(char *str, register int mode)
{ {
register Mac_t *mp = (Mac_t*)shp->mac_context; register Mac_t *mp = (Mac_t*)sh.mac_context;
Stk_t *stkp = shp->stk; Stk_t *stkp = sh.stk;
Mac_t savemac; Mac_t savemac;
savemac = *mp; savemac = *mp;
stkseek(stkp,0); stkseek(stkp,0);
mp->arith = (mode==3); mp->arith = (mode==3);
shp->argaddr = 0; sh.argaddr = 0;
mp->pattern = (mode==1||mode==2); mp->pattern = (mode==1||mode==2);
mp->patfound = 0; mp->patfound = 0;
mp->assign = 0; mp->assign = 0;
@ -169,7 +165,7 @@ char *sh_mactrim(Shell_t *shp, char *str, register int mode)
mp->assign = -mode; mp->assign = -mode;
mp->quoted = mp->lit = mp->split = mp->quote = 0; mp->quoted = mp->lit = mp->split = mp->quote = 0;
mp->sp = 0; mp->sp = 0;
if(mp->ifsp=nv_getval(sh_scoped(shp,IFSNOD))) if(mp->ifsp=nv_getval(sh_scoped(IFSNOD)))
mp->ifs = *mp->ifsp; mp->ifs = *mp->ifsp;
else else
mp->ifs = ' '; mp->ifs = ' ';
@ -181,7 +177,7 @@ char *sh_mactrim(Shell_t *shp, char *str, register int mode)
{ {
/* expand only if unique */ /* expand only if unique */
struct argnod *arglist=0; struct argnod *arglist=0;
if((mode=path_expand(shp,str,&arglist))==1) if((mode=path_expand(str,&arglist))==1)
str = arglist->argval; str = arglist->argval;
else if(mode>1) else if(mode>1)
{ {
@ -197,24 +193,24 @@ char *sh_mactrim(Shell_t *shp, char *str, register int mode)
/* /*
* Perform all the expansions on the argument <argp> * Perform all the expansions on the argument <argp>
*/ */
int sh_macexpand(Shell_t* shp, register struct argnod *argp, struct argnod **arghead,int flag) int sh_macexpand(register struct argnod *argp, struct argnod **arghead,int flag)
{ {
register int flags = argp->argflag; register int flags = argp->argflag;
register char *str = argp->argval; register char *str = argp->argval;
register Mac_t *mp = (Mac_t*)shp->mac_context; register Mac_t *mp = (Mac_t*)sh.mac_context;
char **saveargaddr = shp->argaddr; char **saveargaddr = sh.argaddr;
Mac_t savemac; Mac_t savemac;
Stk_t *stkp = shp->stk; Stk_t *stkp = sh.stk;
savemac = *mp; savemac = *mp;
mp->sp = 0; mp->sp = 0;
if(mp->ifsp=nv_getval(sh_scoped(shp,IFSNOD))) if(mp->ifsp=nv_getval(sh_scoped(IFSNOD)))
mp->ifs = *mp->ifsp; mp->ifs = *mp->ifsp;
else else
mp->ifs = ' '; mp->ifs = ' ';
if((flag&ARG_OPTIMIZE) && !shp->indebug && !(flags&ARG_MESSAGE)) if((flag&ARG_OPTIMIZE) && !sh.indebug && !(flags&ARG_MESSAGE))
shp->argaddr = (char**)&argp->argchn.ap; sh.argaddr = (char**)&argp->argchn.ap;
else else
shp->argaddr = 0; sh.argaddr = 0;
mp->arghead = arghead; mp->arghead = arghead;
mp->quoted = mp->lit = mp->quote = 0; mp->quoted = mp->lit = mp->quote = 0;
mp->arith = ((flag&ARG_ARITH)!=0); mp->arith = ((flag&ARG_ARITH)!=0);
@ -244,17 +240,17 @@ int sh_macexpand(Shell_t* shp, register struct argnod *argp, struct argnod **arg
if(!arghead) if(!arghead)
{ {
argp->argchn.cp = stkfreeze(stkp,1); argp->argchn.cp = stkfreeze(stkp,1);
if(shp->argaddr) if(sh.argaddr)
argp->argflag |= ARG_MAKE; argp->argflag |= ARG_MAKE;
} }
else else
{ {
endfield(mp,mp->quoted|mp->atmode); endfield(mp,mp->quoted|mp->atmode);
flags = mp->fields; flags = mp->fields;
if(flags==1 && shp->argaddr) if(flags==1 && sh.argaddr)
argp->argchn.ap = *arghead; argp->argchn.ap = *arghead;
} }
shp->argaddr = saveargaddr; sh.argaddr = saveargaddr;
*mp = savemac; *mp = savemac;
return(flags); return(flags);
} }
@ -263,23 +259,23 @@ int sh_macexpand(Shell_t* shp, register struct argnod *argp, struct argnod **arg
* Expand here document which is stored in <infile> or <string> * Expand here document which is stored in <infile> or <string>
* The result is written to <outfile> * The result is written to <outfile>
*/ */
void sh_machere(Shell_t *shp,Sfio_t *infile, Sfio_t *outfile, char *string) void sh_machere(Sfio_t *infile, Sfio_t *outfile, char *string)
{ {
register int c,n; register int c,n;
register const char *state = sh_lexstates[ST_QUOTE]; register const char *state = sh_lexstates[ST_QUOTE];
register char *cp; register char *cp;
register Mac_t *mp = (Mac_t*)shp->mac_context; register Mac_t *mp = (Mac_t*)sh.mac_context;
Lex_t *lp = (Lex_t*)mp->shp->lex_context; Lex_t *lp = (Lex_t*)sh.lex_context;
Fcin_t save; Fcin_t save;
Mac_t savemac; Mac_t savemac;
Stk_t *stkp = shp->stk; Stk_t *stkp = sh.stk;
savemac = *mp; savemac = *mp;
stkseek(stkp,0); stkseek(stkp,0);
shp->argaddr = 0; sh.argaddr = 0;
mp->sp = outfile; mp->sp = outfile;
mp->split = mp->assign = mp->pattern = mp->patfound = mp->lit = mp->arith = 0; mp->split = mp->assign = mp->pattern = mp->patfound = mp->lit = mp->arith = 0;
mp->quote = 1; mp->quote = 1;
mp->ifsp = nv_getval(sh_scoped(shp,IFSNOD)); mp->ifsp = nv_getval(sh_scoped(IFSNOD));
mp->ifs = ' '; mp->ifs = ' ';
fcsave(&save); fcsave(&save);
if(infile) if(infile)
@ -407,7 +403,7 @@ void sh_machere(Shell_t *shp,Sfio_t *infile, Sfio_t *outfile, char *string)
/* /*
* expand argument but do not trim pattern characters * expand argument but do not trim pattern characters
*/ */
char *sh_macpat(Shell_t *shp,register struct argnod *arg, int flags) char *sh_macpat(register struct argnod *arg, int flags)
{ {
register char *sp = arg->argval; register char *sp = arg->argval;
if((arg->argflag&ARG_RAW)) if((arg->argflag&ARG_RAW))
@ -417,7 +413,7 @@ char *sh_macpat(Shell_t *shp,register struct argnod *arg, int flags)
arg->argchn.ap=0; arg->argchn.ap=0;
if(!(sp=arg->argchn.cp)) if(!(sp=arg->argchn.cp))
{ {
sh_macexpand(shp,arg,NIL(struct argnod**),flags|ARG_ARRAYOK); sh_macexpand(arg,NIL(struct argnod**),flags|ARG_ARRAYOK);
sp = arg->argchn.cp; sp = arg->argchn.cp;
if(!(flags&ARG_OPTIMIZE) || !(arg->argflag&ARG_MAKE)) if(!(flags&ARG_OPTIMIZE) || !(arg->argflag&ARG_MAKE))
arg->argchn.cp = 0; arg->argchn.cp = 0;
@ -436,7 +432,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
register int c,n; register int c,n;
register const char *state = sh_lexstates[ST_MACRO]; register const char *state = sh_lexstates[ST_MACRO];
register char *cp,*first; register char *cp,*first;
Lex_t *lp = (Lex_t*)mp->shp->lex_context; Lex_t *lp = (Lex_t*)sh.lex_context;
int tilde = -1; int tilde = -1;
int oldquote = mp->quote; int oldquote = mp->quote;
int ansi_c = 0; int ansi_c = 0;
@ -444,7 +440,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
int ere = 0; int ere = 0;
int brace = 0; int brace = 0;
Sfio_t *sp = mp->sp; Sfio_t *sp = mp->sp;
Stk_t *stkp = mp->shp->stk; Stk_t *stkp = sh.stk;
char *resume = 0; char *resume = 0;
mp->sp = NIL(Sfio_t*); mp->sp = NIL(Sfio_t*);
mp->quote = newquote; mp->quote = newquote;
@ -666,7 +662,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
c += (n!=S_EOF); c += (n!=S_EOF);
first = fcseek(c); first = fcseek(c);
if(tilde>=0) if(tilde>=0)
tilde_expand2(mp->shp,tilde); tilde_expand2(tilde);
goto done; goto done;
case S_QUOTE: case S_QUOTE:
if(mp->lit || mp->arith) if(mp->lit || mp->arith)
@ -815,7 +811,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
if(c) if(c)
sfwrite(stkp,first,c); sfwrite(stkp,first,c);
first = fcseek(c); first = fcseek(c);
tilde_expand2(mp->shp,tilde); tilde_expand2(tilde);
#if _WINIX #if _WINIX
if(Skip) if(Skip)
{ {
@ -895,18 +891,18 @@ static void mac_substitute(Mac_t *mp, register char *cp,char *str,register int s
} }
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
#define MAX_OFFSETS (sizeof(shp->offsets)/sizeof(shp->offsets[0])) #define MAX_OFFSETS (sizeof(sh.offsets)/sizeof(sh.offsets[0]))
#define MAX_ARGN (32*1024) #define MAX_ARGN (32*1024)
/* /*
* compute the arguments $1 ... $n and $# from the current line as needed * compute the arguments $1 ... $n and $# from the current line as needed
* save line offsets in the offsets array. * save line offsets in the offsets array.
*/ */
static char *getdolarg(Shell_t *shp, int n, int *size) static char *getdolarg(int n, int *size)
{ {
register int c=S_DELIM, d=shp->ifstable['\\']; register int c=S_DELIM, d=sh.ifstable['\\'];
register unsigned char *first,*last,*cp = (unsigned char*)shp->cur_line; register unsigned char *first,*last,*cp = (unsigned char*)sh.cur_line;
register int m=shp->offsets[0],delim=0; register int m=sh.offsets[0],delim=0;
if(m==0) if(m==0)
return(0); return(0);
if(m<0) if(m<0)
@ -917,21 +913,21 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
m--; m--;
if(m >= MAX_OFFSETS-1) if(m >= MAX_OFFSETS-1)
m = MAX_OFFSETS-2; m = MAX_OFFSETS-2;
cp += shp->offsets[m+1]; cp += sh.offsets[m+1];
n -= m; n -= m;
shp->ifstable['\\'] = 0; sh.ifstable['\\'] = 0;
shp->ifstable[0] = S_EOF; sh.ifstable[0] = S_EOF;
while(1) while(1)
{ {
if(c==S_DELIM) if(c==S_DELIM)
while(shp->ifstable[*cp++]==S_SPACE); while(sh.ifstable[*cp++]==S_SPACE);
first = --cp; first = --cp;
if(++m < MAX_OFFSETS) if(++m < MAX_OFFSETS)
shp->offsets[m] = (first-(unsigned char*)shp->cur_line); sh.offsets[m] = (first-(unsigned char*)sh.cur_line);
while((c=shp->ifstable[*cp++])==0); while((c=sh.ifstable[*cp++])==0);
last = cp-1; last = cp-1;
if(c==S_SPACE) if(c==S_SPACE)
while((c=shp->ifstable[*cp++])==S_SPACE); while((c=sh.ifstable[*cp++])==S_SPACE);
if(--n==0 || c==S_EOF) if(--n==0 || c==S_EOF)
{ {
if(last==first && c==S_EOF && (!delim || (m>1))) if(last==first && c==S_EOF && (!delim || (m>1)))
@ -943,9 +939,9 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
} }
delim = (c==S_DELIM); delim = (c==S_DELIM);
} }
shp->ifstable['\\'] = d; sh.ifstable['\\'] = d;
if(m > shp->offsets[0]) if(m > sh.offsets[0])
shp->offsets[0] = m; sh.offsets[0] = m;
if(n) if(n)
first = last = 0; first = last = 0;
if(size) if(size)
@ -957,14 +953,14 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
/* /*
* get the prefix after name reference resolution * get the prefix after name reference resolution
*/ */
static char *prefix(Shell_t *shp, char *id) static char *prefix(char *id)
{ {
Namval_t *np; Namval_t *np;
register char *sub=0, *cp = strchr(id,'.'); register char *sub=0, *cp = strchr(id,'.');
if(cp) if(cp)
{ {
*cp = 0; *cp = 0;
np = nv_search(id, shp->var_tree,0); np = nv_search(id, sh.var_tree,0);
*cp = '.'; *cp = '.';
if(isastchar(cp[1])) if(isastchar(cp[1]))
cp[1] = 0; cp[1] = 0;
@ -972,7 +968,7 @@ static char *prefix(Shell_t *shp, char *id)
{ {
int n; int n;
char *sp; char *sp;
shp->argaddr = 0; sh.argaddr = 0;
while(nv_isref(np) && np->nvalue.cp) while(nv_isref(np) && np->nvalue.cp)
{ {
sub = nv_refsub(np); sub = nv_refsub(np);
@ -1003,7 +999,7 @@ static int subcopy(Mac_t *mp, int flag)
{ {
int split = mp->split; int split = mp->split;
int xpattern = mp->pattern; int xpattern = mp->pattern;
int loc = stktell(mp->shp->stk); int loc = stktell(sh.stk);
int xarith = mp->arith; int xarith = mp->arith;
int arrayok = mp->arrayok; int arrayok = mp->arrayok;
mp->split = 0; mp->split = 0;
@ -1025,10 +1021,10 @@ static int subcopy(Mac_t *mp, int flag)
* if name is a discipline function, run the function and put the results * if name is a discipline function, run the function and put the results
* on the stack so that ${x.foo} behaves like ${ x.foo;} * on the stack so that ${x.foo} behaves like ${ x.foo;}
*/ */
int sh_macfun(Shell_t *shp, const char *name, int offset) int sh_macfun(const char *name, int offset)
{ {
Namval_t *np, *nq; Namval_t *np, *nq;
np = nv_bfsearch(name,shp->fun_tree,&nq,(char**)0); np = nv_bfsearch(name,sh.fun_tree,&nq,(char**)0);
if(np) if(np)
{ {
/* treat ${x.foo} as ${x.foo;} */ /* treat ${x.foo} as ${x.foo;} */
@ -1046,11 +1042,11 @@ int sh_macfun(Shell_t *shp, const char *name, int offset)
memset(&t,0,sizeof(t)); memset(&t,0,sizeof(t));
memset(&d,0,sizeof(d)); memset(&d,0,sizeof(d));
t.node.com.comarg = &d.arg; t.node.com.comarg = &d.arg;
t.node.com.comline = shp->inlineno; t.node.com.comline = sh.inlineno;
d.dol.dolnum = 1; d.dol.dolnum = 1;
d.dol.dolval[0] = sh_strdup(name); d.dol.dolval[0] = sh_strdup(name);
stkseek(shp->stk,offset); stkseek(sh.stk,offset);
comsubst((Mac_t*)shp->mac_context,&t.node,2); comsubst((Mac_t*)sh.mac_context,&t.node,2);
free(d.dol.dolval[0]); free(d.dol.dolval[0]);
return(1); return(1);
} }
@ -1091,13 +1087,13 @@ static int varsub(Mac_t *mp)
register char *v,*argp=0; register char *v,*argp=0;
register Namval_t *np = NIL(Namval_t*); register Namval_t *np = NIL(Namval_t*);
register int dolg=0, mode=0; register int dolg=0, mode=0;
Lex_t *lp = (Lex_t*)mp->shp->lex_context; Lex_t *lp = (Lex_t*)sh.lex_context;
Namarr_t *ap=0; Namarr_t *ap=0;
int dolmax=0, vsize= -1, offset= -1, nulflg, replen=0, bysub=0; int dolmax=0, vsize= -1, offset= -1, nulflg, replen=0, bysub=0;
char idbuff[3], *id = idbuff, *pattern=0, *repstr=0, *arrmax=0; char idbuff[3], *id = idbuff, *pattern=0, *repstr=0, *arrmax=0;
char *idx = 0; char *idx = 0;
int var=1,addsub=0,oldpat=mp->pattern,idnum=0,flag=0,d; int var=1,addsub=0,oldpat=mp->pattern,idnum=0,flag=0,d;
Stk_t *stkp = mp->shp->stk; Stk_t *stkp = sh.stk;
retry1: retry1:
idbuff[0] = 0; idbuff[0] = 0;
idbuff[1] = 0; idbuff[1] = 0;
@ -1141,19 +1137,19 @@ retry1:
case S_SPC2: case S_SPC2:
var = 0; var = 0;
*id = c; *id = c;
v = special(mp->shp,c); v = special(c);
if(isastchar(c)) if(isastchar(c))
{ {
mode = c; mode = c;
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
if(mp->shp->cur_line) if(sh.cur_line)
{ {
v = getdolarg(mp->shp,1,(int*)0); v = getdolarg(1,(int*)0);
dolmax = MAX_ARGN; dolmax = MAX_ARGN;
} }
else else
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
dolmax = mp->shp->st.dolc+1; dolmax = sh.st.dolc+1;
mp->atmode = (v && mp->quoted && c=='@'); mp->atmode = (v && mp->quoted && c=='@');
dolg = (v!=0); dolg = (v!=0);
} }
@ -1171,7 +1167,7 @@ retry1:
case S_DIG: case S_DIG:
var = 0; var = 0;
c -= '0'; c -= '0';
mp->shp->argaddr = 0; sh.argaddr = 0;
if(type) if(type)
{ {
register int d; register int d;
@ -1181,18 +1177,18 @@ retry1:
} }
idnum = c; idnum = c;
if(c==0) if(c==0)
v = special(mp->shp,c); v = special(c);
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
else if(mp->shp->cur_line) else if(sh.cur_line)
{ {
mp->shp->used_pos = 1; sh.used_pos = 1;
v = getdolarg(mp->shp,c,&vsize); v = getdolarg(c,&vsize);
} }
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
else if(c <= mp->shp->st.dolc) else if(c <= sh.st.dolc)
{ {
mp->shp->used_pos = 1; sh.used_pos = 1;
v = mp->shp->st.dolv[c]; v = sh.st.dolv[c];
} }
else else
v = 0; v = 0;
@ -1226,7 +1222,7 @@ retry1:
while((d=c,(c=fcmbget(&LEN)),isaname(c))||type && c=='.'); while((d=c,(c=fcmbget(&LEN)),isaname(c))||type && c=='.');
while(c==LBRACT && (type||mp->arrayok)) while(c==LBRACT && (type||mp->arrayok))
{ {
mp->shp->argaddr=0; sh.argaddr=0;
if((c=fcmbget(&LEN),isastchar(c)) && fcpeek(0)==RBRACT && d!='.') if((c=fcmbget(&LEN),isastchar(c)) && fcpeek(0)==RBRACT && d!='.')
{ {
if(type==M_VNAME) if(type==M_VNAME)
@ -1308,31 +1304,31 @@ retry1:
flag &= ~NV_NOADD; flag &= ~NV_NOADD;
} }
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
if(mp->shp->cur_line && *id=='R' && strcmp(id,"REPLY")==0) if(sh.cur_line && *id=='R' && strcmp(id,"REPLY")==0)
{ {
mp->shp->argaddr=0; sh.argaddr=0;
np = REPLYNOD; np = REPLYNOD;
} }
else else
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
{ {
if(mp->shp->argaddr) if(sh.argaddr)
flag &= ~NV_NOADD; flag &= ~NV_NOADD;
/* /*
* Get a node pointer (np) to the parameter, if any. * Get a node pointer (np) to the parameter, if any.
*/ */
np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL); np = nv_open(id,sh.var_tree,flag|NV_NOFAIL);
if(!np) if(!np)
{ {
sfprintf(mp->shp->strbuf,"%s%c",id,0); sfprintf(sh.strbuf,"%s%c",id,0);
id = sfstruse(mp->shp->strbuf); id = sfstruse(sh.strbuf);
} }
} }
if(isastchar(mode)) if(isastchar(mode))
var = 0; var = 0;
if((!np || nv_isnull(np)) && type==M_BRACE && c==RBRACE && !(flag&NV_ARRAY) && strchr(id,'.')) if((!np || nv_isnull(np)) && type==M_BRACE && c==RBRACE && !(flag&NV_ARRAY) && strchr(id,'.'))
{ {
if(sh_macfun(mp->shp,id,offset)) if(sh_macfun(id,offset))
{ {
fcmbget(&LEN); fcmbget(&LEN);
return(1); return(1);
@ -1343,7 +1339,7 @@ retry1:
if(nv_isattr(np,NV_NOFREE)) if(nv_isattr(np,NV_NOFREE))
nv_offattr(np,NV_NOFREE); nv_offattr(np,NV_NOFREE);
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
else if(np!=REPLYNOD || !mp->shp->cur_line) else if(np!=REPLYNOD || !sh.cur_line)
#else #else
else else
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
@ -1368,14 +1364,14 @@ retry1:
dolmax =1; dolmax =1;
if(array_assoc(ap)) if(array_assoc(ap))
arrmax = sh_strdup(v); arrmax = sh_strdup(v);
else if((dolmax = (int)sh_arith(mp->shp,v))<0) else if((dolmax = (int)sh_arith(v))<0)
dolmax += array_maxindex(np); dolmax += array_maxindex(np);
if(type==M_SUBNAME) if(type==M_SUBNAME)
bysub = 1; bysub = 1;
} }
else else
{ {
if((int)sh_arith(mp->shp,v)) if((int)sh_arith(v))
np = 0; np = 0;
} }
} }
@ -1405,14 +1401,14 @@ retry1:
if(cc==0) if(cc==0)
mp->assign = 1; mp->assign = 1;
} }
if((type==M_VNAME||type==M_SUBNAME) && mp->shp->argaddr && strcmp(nv_name(np),id)) if((type==M_VNAME||type==M_SUBNAME) && sh.argaddr && strcmp(nv_name(np),id))
mp->shp->argaddr = 0; sh.argaddr = 0;
c = (type>M_BRACE && isastchar(mode)); c = (type>M_BRACE && isastchar(mode));
/* /*
* Check if the parameter is set or unset. * Check if the parameter is set or unset.
*/ */
#if SHOPT_OPTIMIZE #if SHOPT_OPTIMIZE
if(np && type==M_BRACE && mp->shp->argaddr) if(np && type==M_BRACE && sh.argaddr)
nv_optimize(np); /* needed before calling nv_isnull() */ nv_optimize(np); /* needed before calling nv_isnull() */
#endif /* SHOPT_OPTIMIZE */ #endif /* SHOPT_OPTIMIZE */
if(np && (type==M_BRACE ? (!nv_isnull(np) || np==SH_LEVELNOD) : (type==M_TREE || !c || !ap))) if(np && (type==M_BRACE ? (!nv_isnull(np) || np==SH_LEVELNOD) : (type==M_TREE || !c || !ap)))
@ -1434,15 +1430,15 @@ retry1:
Namval_t *nq = nv_type(np); Namval_t *nq = nv_type(np);
type = M_BRACE; type = M_BRACE;
if(nq) if(nq)
nv_typename(nq,mp->shp->strbuf); nv_typename(nq,sh.strbuf);
else else
nv_attribute(np,mp->shp->strbuf,"typeset",1); nv_attribute(np,sh.strbuf,"typeset",1);
v = sfstruse(mp->shp->strbuf); v = sfstruse(sh.strbuf);
} }
#endif /* SHOPT_TYPEDEF */ #endif /* SHOPT_TYPEDEF */
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
else if(mp->shp->cur_line && np==REPLYNOD) else if(sh.cur_line && np==REPLYNOD)
v = mp->shp->cur_line; v = sh.cur_line;
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
else if(type==M_TREE) else if(type==M_TREE)
v = nv_getvtree(np,(Namfun_t*)0); v = nv_getvtree(np,(Namfun_t*)0);
@ -1485,7 +1481,7 @@ retry1:
if(ap) if(ap)
{ {
#if SHOPT_OPTIMIZE #if SHOPT_OPTIMIZE
if(mp->shp->argaddr) if(sh.argaddr)
nv_optimize(np); nv_optimize(np);
#endif #endif
if(isastchar(mode) && array_elem(ap)> !c) if(isastchar(mode) && array_elem(ap)> !c)
@ -1513,8 +1509,8 @@ retry1:
mac_error(np); mac_error(np);
if(type==M_NAMESCAN || type==M_NAMECOUNT) if(type==M_NAMESCAN || type==M_NAMECOUNT)
{ {
mp->shp->last_root = mp->shp->var_tree; sh.last_root = sh.var_tree;
id = idx = prefix(mp->shp,id); id = idx = prefix(id);
stkseek(stkp,offset); stkseek(stkp,offset);
if(type==M_NAMECOUNT) if(type==M_NAMECOUNT)
{ {
@ -1528,7 +1524,7 @@ retry1:
dolg = -1; dolg = -1;
nextname(mp,id,0); nextname(mp,id,0);
/* Check if the prefix (id) itself exists. If so, start with that. */ /* Check if the prefix (id) itself exists. If so, start with that. */
if(nv_open(id,mp->shp->var_tree,NV_NOREF|NV_NOADD|NV_VARNAME|NV_NOFAIL)) if(nv_open(id,sh.var_tree,NV_NOREF|NV_NOADD|NV_VARNAME|NV_NOFAIL))
v = id; v = id;
else else
v = nextname(mp,id,dolmax); v = nextname(mp,id,dolmax);
@ -1556,14 +1552,14 @@ retry1:
else if(dolg>0) else if(dolg>0)
{ {
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
if(mp->shp->cur_line) if(sh.cur_line)
{ {
getdolarg(mp->shp,MAX_ARGN,(int*)0); getdolarg(MAX_ARGN,(int*)0);
c = mp->shp->offsets[0]; c = sh.offsets[0];
} }
else else
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
c = mp->shp->st.dolc; c = sh.st.dolc;
} }
else if(dolg<0) else if(dolg<0)
c = array_elem(ap); c = array_elem(ap);
@ -1673,17 +1669,17 @@ retry1:
if(type<0 && (type+= dolmax)<0) if(type<0 && (type+= dolmax)<0)
type = 0; type = 0;
if(type==0) if(type==0)
v = special(mp->shp,dolg=0); v = special(dolg=0);
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
else if(mp->shp->cur_line) else if(sh.cur_line)
{ {
v = getdolarg(mp->shp,dolg=type,&vsize); v = getdolarg(dolg=type,&vsize);
if(!v) if(!v)
dolmax = type; dolmax = type;
} }
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
else if(type < dolmax) else if(type < dolmax)
v = mp->shp->st.dolv[dolg=type]; v = sh.st.dolv[dolg=type];
else else
v = 0; v = 0;
} }
@ -1846,7 +1842,7 @@ retry2:
else else
nmatch=strgrpmatch(v,pattern,match,elementsof(match)/2,flag); nmatch=strgrpmatch(v,pattern,match,elementsof(match)/2,flag);
if(nmatch && replen>0) if(nmatch && replen>0)
sh_setmatch(mp->shp,v,vsize,nmatch,match,index++); sh_setmatch(v,vsize,nmatch,match,index++);
if(nmatch) if(nmatch)
{ {
vlast = v; vlast = v;
@ -1878,16 +1874,16 @@ retry2:
break; break;
} }
if(replen==0) if(replen==0)
sh_setmatch(mp->shp,vlast,vsize_last,nmatch,match,index++); sh_setmatch(vlast,vsize_last,nmatch,match,index++);
} }
if(vsize) if(vsize)
mac_copy(mp,v,vsize>0?vsize:strlen(v)); mac_copy(mp,v,vsize>0?vsize:strlen(v));
if(addsub) if(addsub)
{ {
mp->shp->instance++; sh.instance++;
sfprintf(mp->shp->strbuf,"[%s]",nv_getsub(np)); sfprintf(sh.strbuf,"[%s]",nv_getsub(np));
mp->shp->instance--; sh.instance--;
v = sfstruse(mp->shp->strbuf); v = sfstruse(sh.strbuf);
mac_copy(mp, v, strlen(v)); mac_copy(mp, v, strlen(v));
} }
if(dolg==0 && dolmax==0) if(dolg==0 && dolmax==0)
@ -1916,11 +1912,11 @@ retry2:
if(++dolg >= dolmax) if(++dolg >= dolmax)
break; break;
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
if(mp->shp->cur_line) if(sh.cur_line)
{ {
if(dolmax==MAX_ARGN && isastchar(mode)) if(dolmax==MAX_ARGN && isastchar(mode))
break; break;
if(!(v=getdolarg(mp->shp,dolg,&vsize))) if(!(v=getdolarg(dolg,&vsize)))
{ {
dolmax = dolg; dolmax = dolg;
break; break;
@ -1928,7 +1924,7 @@ retry2:
} }
else else
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
v = mp->shp->st.dolv[dolg]; v = sh.st.dolv[dolg];
} }
else if(!np) else if(!np)
{ {
@ -2013,7 +2009,7 @@ retry2:
{ {
if(np) if(np)
{ {
if(mp->shp->subshell) if(sh.subshell)
np = sh_assignok(np,1); np = sh_assignok(np,1);
nv_putval(np,argp,0); nv_putval(np,argp,0);
v = nv_getval(np); v = nv_getval(np);
@ -2031,8 +2027,8 @@ retry2:
{ {
if(nv_isarray(np)) if(nv_isarray(np))
{ {
sfprintf(mp->shp->strbuf,"%s[%s]\0",nv_name(np),nv_getsub(np)); sfprintf(sh.strbuf,"%s[%s]\0",nv_name(np),nv_getsub(np));
id = sfstruse(mp->shp->strbuf); id = sfstruse(sh.strbuf);
} }
else else
id = nv_name(np); id = nv_name(np);
@ -2075,9 +2071,9 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
register int c; register int c;
register char *str; register char *str;
Sfio_t *sp; Sfio_t *sp;
Stk_t *stkp = mp->shp->stk; Stk_t *stkp = sh.stk;
Fcin_t save; Fcin_t save;
struct slnod *saveslp = mp->shp->st.staklist; struct slnod *saveslp = sh.st.staklist;
struct _mac_ savemac; struct _mac_ savemac;
int savtop = stktell(stkp); int savtop = stktell(stkp);
char lastc=0, *savptr = stkfreeze(stkp,0); char lastc=0, *savptr = stkfreeze(stkp,0);
@ -2087,36 +2083,36 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
int newlines,bufsize,nextnewlines; int newlines,bufsize,nextnewlines;
Sfoff_t foff; Sfoff_t foff;
Namval_t *np; Namval_t *np;
mp->shp->argaddr = 0; sh.argaddr = 0;
savemac = *mp; savemac = *mp;
mp->shp->st.staklist=0; sh.st.staklist=0;
if(type) if(type)
{ {
sp = 0; sp = 0;
fcseek(-1); fcseek(-1);
if(!t) if(!t)
t = sh_dolparen((Lex_t*)mp->shp->lex_context); t = sh_dolparen((Lex_t*)sh.lex_context);
if(t && t->tre.tretyp==TARITH) if(t && t->tre.tretyp==TARITH)
{ {
fcsave(&save); fcsave(&save);
if(t->ar.arcomp) if(t->ar.arcomp)
num = arith_exec(t->ar.arcomp); num = arith_exec(t->ar.arcomp);
else if((t->ar.arexpr->argflag&ARG_RAW)) else if((t->ar.arexpr->argflag&ARG_RAW))
num = sh_arith(mp->shp,t->ar.arexpr->argval); num = sh_arith(t->ar.arexpr->argval);
else else
num = sh_arith(mp->shp,sh_mactrim(mp->shp,t->ar.arexpr->argval,3)); num = sh_arith(sh_mactrim(t->ar.arexpr->argval,3));
out_offset: out_offset:
stkset(stkp,savptr,savtop); stkset(stkp,savptr,savtop);
*mp = savemac; *mp = savemac;
if((Sflong_t)num!=num) if((Sflong_t)num!=num)
sfprintf(mp->shp->strbuf,"%.*Lg",LDBL_DIG,num); sfprintf(sh.strbuf,"%.*Lg",LDBL_DIG,num);
else if(num) else if(num)
sfprintf(mp->shp->strbuf,"%lld",(Sflong_t)num); sfprintf(sh.strbuf,"%lld",(Sflong_t)num);
else else
sfprintf(mp->shp->strbuf,"%Lg",num); sfprintf(sh.strbuf,"%Lg",num);
str = sfstruse(mp->shp->strbuf); str = sfstruse(sh.strbuf);
mac_copy(mp,str,strlen(str)); mac_copy(mp,str,strlen(str));
mp->shp->st.staklist = saveslp; sh.st.staklist = saveslp;
fcrestore(&save); fcrestore(&save);
return; return;
} }
@ -2143,10 +2139,10 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
if(mp->sp) if(mp->sp)
sfsync(mp->sp); /* flush before executing command */ sfsync(mp->sp); /* flush before executing command */
sp = sfnew(NIL(Sfio_t*),str,c,-1,SF_STRING|SF_READ); sp = sfnew(NIL(Sfio_t*),str,c,-1,SF_STRING|SF_READ);
c = mp->shp->inlineno; c = sh.inlineno;
mp->shp->inlineno = error_info.line+mp->shp->st.firstline; sh.inlineno = error_info.line+sh.st.firstline;
t = (Shnode_t*)sh_parse(mp->shp, sp,SH_EOF|SH_NL); t = (Shnode_t*)sh_parse(sp,SH_EOF|SH_NL);
mp->shp->inlineno = c; sh.inlineno = c;
type = 1; type = 1;
} }
if(t) if(t)
@ -2160,23 +2156,23 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
int r=0; int r=0;
struct checkpt buff; struct checkpt buff;
struct ionod *ip=0; struct ionod *ip=0;
sh_pushcontext(mp->shp,&buff,SH_JMPIO); sh_pushcontext(&sh,&buff,SH_JMPIO);
if((ip=t->tre.treio) && if((ip=t->tre.treio) &&
((ip->iofile&IOLSEEK) || !(ip->iofile&IOUFD)) && ((ip->iofile&IOLSEEK) || !(ip->iofile&IOUFD)) &&
(r=sigsetjmp(buff.buff,0))==0) (r=sigsetjmp(buff.buff,0))==0)
fd = sh_redirect(mp->shp,ip,3); fd = sh_redirect(ip,3);
else else
fd = sh_chkopen(e_devnull); fd = sh_chkopen(e_devnull);
sh_popcontext(mp->shp,&buff); sh_popcontext(&sh,&buff);
if(r==0 && ip && (ip->iofile&IOLSEEK)) if(r==0 && ip && (ip->iofile&IOLSEEK))
{ {
if(sp=mp->shp->sftable[fd]) if(sp=sh.sftable[fd])
num = sftell(sp); num = sftell(sp);
else else
num = lseek(fd, (off_t)0, SEEK_CUR); num = lseek(fd, (off_t)0, SEEK_CUR);
goto out_offset; goto out_offset;
} }
if(!(sp=mp->shp->sftable[fd])) if(!(sp=sh.sftable[fd]))
{ {
char *cp = (char*)sh_malloc(IOBSIZE+1); char *cp = (char*)sh_malloc(IOBSIZE+1);
sp = sfnew(NIL(Sfio_t*),cp,IOBSIZE,fd,SF_READ|SF_MALLOC); sp = sfnew(NIL(Sfio_t*),cp,IOBSIZE,fd,SF_READ|SF_MALLOC);
@ -2187,20 +2183,20 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
{ {
if(type==2 && sh.subshell && !sh.subshare) if(type==2 && sh.subshell && !sh.subshare)
sh_subfork(); /* subshares within virtual subshells are broken, so fork first */ sh_subfork(); /* subshares within virtual subshells are broken, so fork first */
sp = sh_subshell(mp->shp,t,sh_isstate(SH_ERREXIT),type); sp = sh_subshell(t,sh_isstate(SH_ERREXIT),type);
} }
fcrestore(&save); fcrestore(&save);
} }
else else
sp = sfopen(NIL(Sfio_t*),"","sr"); sp = sfopen(NIL(Sfio_t*),"","sr");
sh_freeup(mp->shp); sh_freeup();
mp->shp->st.staklist = saveslp; sh.st.staklist = saveslp;
if(was_history) if(was_history)
sh_onstate(SH_HISTORY); sh_onstate(SH_HISTORY);
if(was_verbose) if(was_verbose)
sh_onstate(SH_VERBOSE); sh_onstate(SH_VERBOSE);
*mp = savemac; *mp = savemac;
np = sh_scoped(mp->shp,IFSNOD); np = sh_scoped(IFSNOD);
nv_putval(np,mp->ifsp,NV_RDONLY); nv_putval(np,mp->ifsp,NV_RDONLY);
mp->ifsp = nv_getval(np); mp->ifsp = nv_getval(np);
stkset(stkp,savptr,savtop); stkset(stkp,savptr,savtop);
@ -2255,7 +2251,7 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
{ {
if(mp->sp) if(mp->sp)
sfnputc(mp->sp,'\n',newlines); sfnputc(mp->sp,'\n',newlines);
else if(!mp->quote && mp->split && mp->shp->ifstable['\n']) else if(!mp->quote && mp->split && sh.ifstable['\n'])
endfield(mp,0); endfield(mp,0);
else else
sfnputc(stkp,'\n',newlines); sfnputc(stkp,'\n',newlines);
@ -2281,7 +2277,7 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
} }
if(was_interactive) if(was_interactive)
sh_onstate(SH_INTERACTIVE); sh_onstate(SH_INTERACTIVE);
if(--newlines>0 && mp->shp->ifstable['\n']==S_DELIM) if(--newlines>0 && sh.ifstable['\n']==S_DELIM)
{ {
if(mp->sp) if(mp->sp)
sfnputc(mp->sp,'\n',newlines); sfnputc(mp->sp,'\n',newlines);
@ -2308,7 +2304,7 @@ static void mac_copy(register Mac_t *mp,register const char *str, register int s
register char *state; register char *state;
register const char *cp=str; register const char *cp=str;
register int c,n,nopat,len; register int c,n,nopat,len;
Stk_t *stkp=mp->shp->stk; Stk_t *stkp=sh.stk;
int oldpat = mp->pattern; int oldpat = mp->pattern;
nopat = (mp->quote||(mp->assign==1)||mp->arith); nopat = (mp->quote||(mp->assign==1)||mp->arith);
if(mp->sp) if(mp->sp)
@ -2375,7 +2371,7 @@ static void mac_copy(register Mac_t *mp,register const char *str, register int s
else if(!mp->quote && mp->split && (mp->ifs||mp->pattern)) else if(!mp->quote && mp->split && (mp->ifs||mp->pattern))
{ {
/* split words at ifs characters */ /* split words at ifs characters */
state = mp->shp->ifstable; state = sh.ifstable;
if(mp->pattern) if(mp->pattern)
{ {
char *sp = "&|()"; char *sp = "&|()";
@ -2476,8 +2472,8 @@ static void mac_copy(register Mac_t *mp,register const char *str, register int s
if(state[c]==S_PAT) if(state[c]==S_PAT)
state[c] = 0; state[c] = 0;
} }
if(mp->shp->ifstable[ESCAPE]==S_ESC) if(sh.ifstable[ESCAPE]==S_ESC)
mp->shp->ifstable[ESCAPE] = 0; sh.ifstable[ESCAPE] = 0;
} }
} }
else else
@ -2493,7 +2489,7 @@ static void endfield(register Mac_t *mp,int split)
{ {
register struct argnod *argp; register struct argnod *argp;
register int count=0; register int count=0;
Stk_t *stkp = mp->shp->stk; Stk_t *stkp = sh.stk;
if(stktell(stkp) > ARGVAL || split) if(stktell(stkp) > ARGVAL || split)
{ {
argp = (struct argnod*)stkfreeze(stkp,1); argp = (struct argnod*)stkfreeze(stkp,1);
@ -2502,13 +2498,13 @@ static void endfield(register Mac_t *mp,int split)
mp->atmode = 0; mp->atmode = 0;
if(mp->patfound) if(mp->patfound)
{ {
mp->shp->argaddr = 0; sh.argaddr = 0;
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
if(sh_isoption(SH_BRACEEXPAND)) if(sh_isoption(SH_BRACEEXPAND))
count = path_generate(mp->shp,argp,mp->arghead); count = path_generate(argp,mp->arghead);
else else
#endif /* SHOPT_BRACEPAT */ #endif /* SHOPT_BRACEPAT */
count = path_expand(mp->shp,argp->argval,mp->arghead); count = path_expand(argp->argval,mp->arghead);
if(count) if(count)
mp->fields += count; mp->fields += count;
else if(split) /* pattern is null string */ else if(split) /* pattern is null string */
@ -2623,7 +2619,7 @@ static int charlen(const char *string,int len)
/* /*
* <offset> is byte offset for beginning of tilde string * <offset> is byte offset for beginning of tilde string
*/ */
static void tilde_expand2(Shell_t *shp, register int offset) static void tilde_expand2(register int offset)
{ {
char *cp = NIL(char*); /* character pointer for tilde expansion result */ char *cp = NIL(char*); /* character pointer for tilde expansion result */
char *stakp = stakptr(0); /* current stack object (&stakp[offset] is tilde string) */ char *stakp = stakptr(0); /* current stack object (&stakp[offset] is tilde string) */
@ -2649,7 +2645,7 @@ static void tilde_expand2(Shell_t *shp, register int offset)
*/ */
stakputc(0); stakputc(0);
if(!cp) if(!cp)
cp = sh_tilde(shp,&stakp[offset]); cp = sh_tilde(&stakp[offset]);
if(cp) if(cp)
{ {
stakseek(offset); stakseek(offset);
@ -2669,7 +2665,7 @@ static void tilde_expand2(Shell_t *shp, register int offset)
* If string doesn't start with ~ or ~... not found then 0 returned. * If string doesn't start with ~ or ~... not found then 0 returned.
*/ */
static char *sh_tilde(Shell_t *shp,register const char *string) static char *sh_tilde(register const char *string)
{ {
register char *cp; register char *cp;
register int c; register int c;
@ -2682,7 +2678,7 @@ static char *sh_tilde(Shell_t *shp,register const char *string)
if((c = *string)==0) if((c = *string)==0)
{ {
static char *username; static char *username;
if(cp = nv_getval(sh_scoped(shp, HOME))) if(cp = nv_getval(sh_scoped(HOME)))
return(cp); return(cp);
/* Fallback for unset HOME: get username and treat ~ like ~username */ /* Fallback for unset HOME: get username and treat ~ like ~username */
if(!username && !((pw = getpwuid(getuid())) && (username = sh_strdup(pw->pw_name)))) if(!username && !((pw = getpwuid(getuid())) && (username = sh_strdup(pw->pw_name))))
@ -2692,9 +2688,9 @@ static char *sh_tilde(Shell_t *shp,register const char *string)
if((c=='-' || c=='+') && string[1]==0) if((c=='-' || c=='+') && string[1]==0)
{ {
if(c=='+') if(c=='+')
cp = nv_getval(sh_scoped(shp,PWDNOD)); cp = nv_getval(sh_scoped(PWDNOD));
else else
cp = nv_getval(sh_scoped(shp,OLDPWDNOD)); cp = nv_getval(sh_scoped(OLDPWDNOD));
return(cp); return(cp);
} }
#if _WINIX #if _WINIX
@ -2734,14 +2730,14 @@ skip:
if(!logins_tree) if(!logins_tree)
{ {
logins_tree = dtopen(&_Nvdisc,Dtbag); logins_tree = dtopen(&_Nvdisc,Dtbag);
dtuserdata(logins_tree,shp,1); dtuserdata(logins_tree,&sh,1);
} }
if(np=nv_search(string,logins_tree,NV_ADD)) if(np=nv_search(string,logins_tree,NV_ADD))
{ {
save = shp->subshell; save = sh.subshell;
shp->subshell = 0; sh.subshell = 0;
nv_putval(np, pw->pw_dir,0); nv_putval(np, pw->pw_dir,0);
shp->subshell = save; sh.subshell = save;
} }
return(pw->pw_dir); return(pw->pw_dir);
} }
@ -2749,41 +2745,41 @@ skip:
/* /*
* return values for special macros * return values for special macros
*/ */
static char *special(Shell_t *shp,register int c) static char *special(register int c)
{ {
if(c!='$') if(c!='$')
shp->argaddr = 0; sh.argaddr = 0;
switch(c) switch(c)
{ {
case '@': case '@':
case '*': case '*':
return(shp->st.dolc>0?shp->st.dolv[1]:NIL(char*)); return(sh.st.dolc>0?sh.st.dolv[1]:NIL(char*));
case '#': case '#':
#if SHOPT_FILESCAN #if SHOPT_FILESCAN
if(shp->cur_line) if(sh.cur_line)
{ {
getdolarg(shp,MAX_ARGN,(int*)0); getdolarg(MAX_ARGN,(int*)0);
return(ltos(shp->offsets[0])); return(ltos(sh.offsets[0]));
} }
#endif /* SHOPT_FILESCAN */ #endif /* SHOPT_FILESCAN */
return(ltos(shp->st.dolc)); return(ltos(sh.st.dolc));
case '!': case '!':
if(shp->bckpid) if(sh.bckpid)
return(ltos(shp->bckpid)); return(ltos(sh.bckpid));
break; break;
case '$': case '$':
if(nv_isnull(SH_DOLLARNOD)) if(nv_isnull(SH_DOLLARNOD))
return(ltos(shp->gd->pid)); return(ltos(sh.pid));
return(nv_getval(SH_DOLLARNOD)); return(nv_getval(SH_DOLLARNOD));
case '-': case '-':
return(sh_argdolminus(shp->arg_context)); return(sh_argdolminus(sh.arg_context));
case '?': case '?':
return(ltos(shp->savexit)); return(ltos(sh.savexit));
case 0: case 0:
if(sh_isstate(SH_PROFILE) || shp->fn_depth==0 || !shp->st.cmdname) if(sh_isstate(SH_PROFILE) || sh.fn_depth==0 || !sh.st.cmdname)
return(shp->shname); return(sh.shname);
else else
return(shp->st.cmdname); return(sh.st.cmdname);
} }
/* Handle 'set -u'/'set -o nounset' for special parameters */ /* Handle 'set -u'/'set -o nounset' for special parameters */
if(sh_isoption(SH_NOUNSET)) if(sh_isoption(SH_NOUNSET))

View file

@ -51,8 +51,8 @@
#endif /* _hdr_nc */ #endif /* _hdr_nc */
/* These routines are referenced by this module */ /* These routines are referenced by this module */
static void exfile(Shell_t*, Sfio_t*,int); static void exfile(Sfio_t*,int);
static void chkmail(Shell_t *shp, char*); static void chkmail(char*);
#if !defined(_NEXT_SOURCE) && !defined(__sun) #if !defined(_NEXT_SOURCE) && !defined(__sun)
static void fixargs(char**,int); static void fixargs(char**,int);
# undef fixargs_disabled # undef fixargs_disabled
@ -81,33 +81,27 @@ static char beenhere = 0;
} }
#endif /* _lib_sigvec */ #endif /* _lib_sigvec */
#ifdef PATH_BFPATH
#define PATHCOMP NIL(Pathcomp_t*)
#else
#define PATHCOMP ""
#endif
/* /*
* search for file and exfile() it if it exists * search for file and exfile() it if it exists
* 1 returned if file found, 0 otherwise * 1 returned if file found, 0 otherwise
*/ */
int sh_source(Shell_t *shp, Sfio_t *iop, const char *file) static int sh_source(Sfio_t *iop, const char *file)
{ {
char* oid; char* oid;
char* nid; char* nid;
int fd; int fd;
if (!file || !*file || (fd = path_open(shp,file, PATHCOMP)) < 0) if (!file || !*file || (fd = path_open(file, NIL(Pathcomp_t*))) < 0)
{ {
REGRESS(source, "sh_source", ("%s:ENOENT", file)); REGRESS(source, "sh_source", ("%s:ENOENT", file));
return 0; return 0;
} }
oid = error_info.id; oid = error_info.id;
nid = error_info.id = sh_strdup(file); nid = error_info.id = sh_strdup(file);
shp->st.filename = path_fullname(shp,stakptr(PATH_OFFSET)); sh.st.filename = path_fullname(stakptr(PATH_OFFSET));
REGRESS(source, "sh_source", ("%s", file)); REGRESS(source, "sh_source", ("%s", file));
exfile(shp, iop, fd); exfile(iop, fd);
error_info.id = oid; error_info.id = oid;
free(nid); free(nid);
return 1; return 1;
@ -124,7 +118,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
register char *name; register char *name;
register int fdin; register int fdin;
register Sfio_t *iop; register Sfio_t *iop;
register Shell_t *shp;
struct stat statb; struct stat statb;
int i, rshflag; /* set for restricted shell */ int i, rshflag; /* set for restricted shell */
char *command; char *command;
@ -138,20 +131,20 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
_NutConf(_NC_SET_SUFFIXED_SEARCHING, 1); _NutConf(_NC_SET_SUFFIXED_SEARCHING, 1);
#endif /* _hdr_nc */ #endif /* _hdr_nc */
fixargs(av,0); fixargs(av,0);
shp = sh_init(ac,av,userinit); sh_init(ac,av,userinit);
time(&mailtime); time(&mailtime);
if(rshflag=sh_isoption(SH_RESTRICTED)) if(rshflag=sh_isoption(SH_RESTRICTED))
sh_offoption(SH_RESTRICTED); sh_offoption(SH_RESTRICTED);
if(sigsetjmp(*((sigjmp_buf*)shp->jmpbuffer),0)) if(sigsetjmp(*((sigjmp_buf*)sh.jmpbuffer),0))
{ {
/* begin script execution here */ /* begin script execution here */
sh_reinit((char**)0); sh_reinit((char**)0);
} }
shp->fn_depth = shp->dot_depth = 0; sh.fn_depth = sh.dot_depth = 0;
command = error_info.id; command = error_info.id;
if(nv_isnull(PS4NOD)) if(nv_isnull(PS4NOD))
nv_putval(PS4NOD,e_traceprompt,NV_RDONLY); nv_putval(PS4NOD,e_traceprompt,NV_RDONLY);
path_pwd(shp,1); path_pwd();
iop = (Sfio_t*)0; iop = (Sfio_t*)0;
if(sh_isoption(SH_POSIX)) if(sh_isoption(SH_POSIX))
sh_onoption(SH_LETOCTAL); sh_onoption(SH_LETOCTAL);
@ -163,10 +156,10 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
{ {
beenhere++; beenhere++;
sh_onstate(SH_PROFILE); sh_onstate(SH_PROFILE);
shp->sigflag[SIGTSTP] |= SH_SIGIGNORE; sh.sigflag[SIGTSTP] |= SH_SIGIGNORE;
if(shp->gd->ppid==1) if(sh.ppid==1)
shp->login_sh++; sh.login_sh++;
if(shp->login_sh >= 2) if(sh.login_sh >= 2)
sh_onoption(SH_LOGIN_SHELL); sh_onoption(SH_LOGIN_SHELL);
/* decide whether shell is interactive */ /* decide whether shell is interactive */
if(!sh_isoption(SH_INTERACTIVE) && !sh_isoption(SH_TFLAG) && !sh_isoption(SH_CFLAG) && if(!sh_isoption(SH_INTERACTIVE) && !sh_isoption(SH_TFLAG) && !sh_isoption(SH_CFLAG) &&
@ -179,9 +172,9 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
if(!sh_isoption(SH_POSIX)) if(!sh_isoption(SH_POSIX))
{ {
/* preset aliases for interactive non-POSIX ksh */ /* preset aliases for interactive non-POSIX ksh */
dtclose(shp->alias_tree); dtclose(sh.alias_tree);
shp->alias_tree = sh_inittree(shp,shtab_aliases); sh.alias_tree = sh_inittree(shtab_aliases);
dtuserdata(shp->alias_tree,shp,1); dtuserdata(sh.alias_tree,&sh,1);
} }
} }
#if SHOPT_REMOTE #if SHOPT_REMOTE
@ -192,8 +185,8 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
if(!sh_isoption(SH_RC) && !fstat(0, &statb) && REMOTE(statb.st_mode)) if(!sh_isoption(SH_RC) && !fstat(0, &statb) && REMOTE(statb.st_mode))
sh_onoption(SH_RC); sh_onoption(SH_RC);
#endif #endif
for(i=0; i<elementsof(shp->offoptions.v); i++) for(i=0; i<elementsof(sh.offoptions.v); i++)
shp->options.v[i] &= ~shp->offoptions.v[i]; sh.options.v[i] &= ~sh.offoptions.v[i];
if(sh_isoption(SH_INTERACTIVE)) if(sh_isoption(SH_INTERACTIVE))
{ {
#ifdef SIGXCPU #ifdef SIGXCPU
@ -204,53 +197,53 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
#endif /* SIGXFSZ */ #endif /* SIGXFSZ */
sh_onoption(SH_MONITOR); sh_onoption(SH_MONITOR);
} }
job_init(shp,sh_isoption(SH_LOGIN_SHELL)); job_init(sh_isoption(SH_LOGIN_SHELL));
if(sh_isoption(SH_LOGIN_SHELL)) if(sh_isoption(SH_LOGIN_SHELL))
{ {
/* system profile */ /* system profile */
sh_source(shp, iop, e_sysprofile); sh_source(iop, e_sysprofile);
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED)) if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED))
{ {
char **files = shp->gd->login_files; char **files = sh.login_files;
while ((name = *files++) && !sh_source(shp, iop, sh_mactry(shp,name))); while ((name = *files++) && !sh_source(iop, sh_mactry(name)));
} }
} }
/* make sure PWD is set up correctly */ /* make sure PWD is set up correctly */
path_pwd(shp,1); path_pwd();
if(!sh_isoption(SH_NOEXEC)) if(!sh_isoption(SH_NOEXEC))
{ {
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC)) if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED) && sh_isoption(SH_RC))
{ {
if(name = sh_mactry(shp,nv_getval(ENVNOD))) if(name = sh_mactry(nv_getval(ENVNOD)))
name = *name ? sh_strdup(name) : (char*)0; name = *name ? sh_strdup(name) : (char*)0;
#if SHOPT_SYSRC #if SHOPT_SYSRC
if(!strmatch(name, "?(.)/./*")) if(!strmatch(name, "?(.)/./*"))
sh_source(shp, iop, e_sysrc); sh_source(iop, e_sysrc);
#endif #endif
if(name) if(name)
{ {
sh_source(shp, iop, name); sh_source(iop, name);
free(name); free(name);
} }
} }
else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED)) else if(sh_isoption(SH_INTERACTIVE) && sh_isoption(SH_PRIVILEGED))
sh_source(shp, iop, e_suidprofile); sh_source(iop, e_suidprofile);
} }
shp->st.cmdname = error_info.id = command; sh.st.cmdname = error_info.id = command;
shp->sigflag[SIGTSTP] &= ~(SH_SIGIGNORE); sh.sigflag[SIGTSTP] &= ~(SH_SIGIGNORE);
sh_offstate(SH_PROFILE); sh_offstate(SH_PROFILE);
if(rshflag) if(rshflag)
sh_onoption(SH_RESTRICTED); sh_onoption(SH_RESTRICTED);
/* open input file if specified */ /* open input file if specified */
if(shp->comdiv) if(sh.comdiv)
{ {
shell_c: shell_c:
iop = sfnew(NIL(Sfio_t*),shp->comdiv,strlen(shp->comdiv),0,SF_STRING|SF_READ); iop = sfnew(NIL(Sfio_t*),sh.comdiv,strlen(sh.comdiv),0,SF_STRING|SF_READ);
} }
else else
{ {
name = error_info.id; name = error_info.id;
error_info.id = shp->shname; error_info.id = sh.shname;
if(sh_isoption(SH_SFLAG)) if(sh_isoption(SH_SFLAG))
fdin = 0; fdin = 0;
else else
@ -274,16 +267,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
* try to undo effect of Solaris 2.5+ * try to undo effect of Solaris 2.5+
* change for argv for setuid scripts * change for argv for setuid scripts
*/ */
if(shp->st.repl_index > 0) if(sh.st.repl_index > 0)
av[shp->st.repl_index] = shp->st.repl_arg; av[sh.st.repl_index] = sh.st.repl_arg;
if(((type = sh_type(cp = av[0])) & SH_TYPE_SH) && (name = nv_getval(L_ARGNOD)) && (!((type = sh_type(cp = name)) & SH_TYPE_SH))) if(((type = sh_type(cp = av[0])) & SH_TYPE_SH) && (name = nv_getval(L_ARGNOD)) && (!((type = sh_type(cp = name)) & SH_TYPE_SH)))
{ {
av[0] = (type & SH_TYPE_LOGIN) ? cp : path_basename(cp); av[0] = (type & SH_TYPE_LOGIN) ? cp : path_basename(cp);
/* exec to change $0 for ps */ /* exec to change $0 for ps */
execv(pathshell(),av); execv(pathshell(),av);
/* exec fails */ /* exec fails */
shp->st.dolv[0] = av[0]; sh.st.dolv[0] = av[0];
fixargs(shp->st.dolv,1); fixargs(sh.st.dolv,1);
} }
#endif #endif
name = av[0]; name = av[0];
@ -300,20 +293,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
fdin = -1; fdin = -1;
} }
else else
shp->st.filename = path_fullname(shp,name); sh.st.filename = path_fullname(name);
sp = 0; sp = 0;
if(fdin < 0 && !strchr(name,'/')) if(fdin < 0 && !strchr(name,'/'))
{ {
#ifdef PATH_BFPATH if(path_absolute(name,NIL(Pathcomp_t*),0))
if(path_absolute(shp,name,NIL(Pathcomp_t*),0))
sp = stakptr(PATH_OFFSET); sp = stakptr(PATH_OFFSET);
#else
sp = path_absolute(shp,name,NIL(char*));
#endif
if(sp) if(sp)
{ {
if((fdin=sh_open(sp,O_RDONLY,0))>=0) if((fdin=sh_open(sp,O_RDONLY,0))>=0)
shp->st.filename = path_fullname(shp,sp); sh.st.filename = path_fullname(sp);
} }
} }
if(fdin<0) if(fdin<0)
@ -328,16 +317,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
} }
/* try sh -c 'name "$@"' */ /* try sh -c 'name "$@"' */
sh_onoption(SH_CFLAG); sh_onoption(SH_CFLAG);
shp->comdiv = (char*)sh_malloc(strlen(name)+7); sh.comdiv = (char*)sh_malloc(strlen(name)+7);
name = strcopy(shp->comdiv,name); name = strcopy(sh.comdiv,name);
if(shp->st.dolc) if(sh.st.dolc)
strcopy(name," \"$@\""); strcopy(name," \"$@\"");
goto shell_c; goto shell_c;
} }
if(fdin==0) if(fdin==0)
fdin = sh_iomovefd(fdin); fdin = sh_iomovefd(fdin);
} }
shp->readscript = shp->shname; sh.readscript = sh.shname;
} }
error_info.id = name; error_info.id = name;
#if SHOPT_ACCT #if SHOPT_ACCT
@ -354,14 +343,14 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
else else
{ {
/* beenhere > 0: We're in a forked child, about to execute a script without a hashbang path. */ /* beenhere > 0: We're in a forked child, about to execute a script without a hashbang path. */
fdin = shp->infd; fdin = sh.infd;
fixargs(shp->st.dolv,1); fixargs(sh.st.dolv,1);
} }
if(sh_isoption(SH_INTERACTIVE)) if(sh_isoption(SH_INTERACTIVE))
sh_onstate(SH_INTERACTIVE); sh_onstate(SH_INTERACTIVE);
nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY); nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY);
exfile(shp,iop,fdin); exfile(iop,fdin);
sh_done(shp,0); sh_done(0);
} }
/* /*
@ -369,16 +358,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
* fdin is the input file descriptor * fdin is the input file descriptor
*/ */
static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno) static void exfile(register Sfio_t *iop,register int fno)
{ {
time_t curtime; time_t curtime;
Shnode_t *t; Shnode_t *t;
int maxtry=IOMAXTRY, tdone=0, execflags; int maxtry=IOMAXTRY, tdone=0, execflags;
int states,jmpval; int states,jmpval;
struct checkpt buff; struct checkpt buff;
sh_pushcontext(shp,&buff,SH_JMPERREXIT); sh_pushcontext(&sh,&buff,SH_JMPERREXIT);
/* open input stream */ /* open input stream */
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE); nv_putval(SH_PATHNAMENOD, sh.st.filename, NV_NOFREE);
if(!iop) if(!iop)
{ {
if(fno > 0) if(fno > 0)
@ -386,26 +375,26 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
int r; int r;
if(fno < 10 && ((r=sh_fcntl(fno,F_DUPFD,10))>=10)) if(fno < 10 && ((r=sh_fcntl(fno,F_DUPFD,10))>=10))
{ {
shp->fdstatus[r] = shp->fdstatus[fno]; sh.fdstatus[r] = sh.fdstatus[fno];
sh_close(fno); sh_close(fno);
fno = r; fno = r;
} }
fcntl(fno,F_SETFD,FD_CLOEXEC); fcntl(fno,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fno] |= IOCLEX; sh.fdstatus[fno] |= IOCLEX;
iop = sh_iostream((void*)shp,fno); iop = sh_iostream(fno);
} }
else else
iop = sfstdin; iop = sfstdin;
} }
else else
fno = -1; fno = -1;
shp->infd = fno; sh.infd = fno;
if(sh_isstate(SH_INTERACTIVE)) if(sh_isstate(SH_INTERACTIVE))
{ {
if(nv_isnull(PS1NOD)) if(nv_isnull(PS1NOD))
nv_putval(PS1NOD,(shp->gd->euserid?e_stdprompt:e_supprompt),NV_RDONLY); nv_putval(PS1NOD,(sh.euserid?e_stdprompt:e_supprompt),NV_RDONLY);
sh_sigdone(); sh_sigdone();
if(sh_histinit((void*)shp)) if(sh_histinit())
sh_onoption(SH_HISTORY); sh_onoption(SH_HISTORY);
} }
else else
@ -425,17 +414,17 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
if(jmpval) if(jmpval)
{ {
Sfio_t *top; Sfio_t *top;
sh_iorestore((void*)shp,0,jmpval); sh_iorestore(0,jmpval);
hist_flush(shp->gd->hist_ptr); hist_flush(sh.hist_ptr);
sfsync(shp->outpool); sfsync(sh.outpool);
shp->st.execbrk = shp->st.breakcnt = 0; sh.st.execbrk = sh.st.breakcnt = 0;
/* check for return from profile or env file */ /* check for return from profile or env file */
if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT)) if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
{ {
sh_setstate(states); sh_setstate(states);
goto done; goto done;
} }
if(!sh_isoption(SH_INTERACTIVE) || sh_isstate(SH_FORKED) || (jmpval > SH_JMPERREXIT && job_close(shp) >=0)) if(!sh_isoption(SH_INTERACTIVE) || sh_isstate(SH_FORKED) || (jmpval > SH_JMPERREXIT && job_close() >=0))
{ {
sh_offstate(SH_INTERACTIVE); sh_offstate(SH_INTERACTIVE);
sh_offstate(SH_MONITOR); sh_offstate(SH_MONITOR);
@ -452,30 +441,30 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
} }
/* make sure that we own the terminal */ /* make sure that we own the terminal */
#ifdef SIGTSTP #ifdef SIGTSTP
tcsetpgrp(job.fd,shp->gd->pid); tcsetpgrp(job.fd,sh.pid);
#endif /* SIGTSTP */ #endif /* SIGTSTP */
} }
/* error return here */ /* error return here */
sfclrerr(iop); sfclrerr(iop);
sh_setstate(states); sh_setstate(states);
shp->st.optindex = 1; sh.st.optindex = 1;
opt_info.offset = 0; opt_info.offset = 0;
shp->st.loopcnt = 0; sh.st.loopcnt = 0;
shp->trapnote = 0; sh.trapnote = 0;
shp->intrap = 0; sh.intrap = 0;
error_info.line = 1; error_info.line = 1;
shp->inlineno = 1; sh.inlineno = 1;
shp->binscript = 0; sh.binscript = 0;
shp->exittrap = 0; sh.exittrap = 0;
shp->errtrap = 0; sh.errtrap = 0;
shp->end_fn = 0; sh.end_fn = 0;
if(sfeof(iop)) if(sfeof(iop))
goto eof_or_error; goto eof_or_error;
/* command loop */ /* command loop */
while(1) while(1)
{ {
shp->nextprompt = 1; sh.nextprompt = 1;
sh_freeup(shp); sh_freeup();
stakset(NIL(char*),0); stakset(NIL(char*),0);
sh_offstate(SH_STOPOK); sh_offstate(SH_STOPOK);
sh_offstate(SH_ERREXIT); sh_offstate(SH_ERREXIT);
@ -511,26 +500,26 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
time(&curtime); time(&curtime);
if ((curtime - mailtime) >= sh_mailchk) if ((curtime - mailtime) >= sh_mailchk)
{ {
chkmail(shp,mail); chkmail(mail);
mailtime = curtime; mailtime = curtime;
} }
} }
if(shp->gd->hist_ptr) if(sh.hist_ptr)
hist_eof(shp->gd->hist_ptr); hist_eof(sh.hist_ptr);
/* sets timeout for command entry */ /* sets timeout for command entry */
shp->timeout = shp->st.tmout; sh.timeout = sh.st.tmout;
#if SHOPT_TIMEOUT #if SHOPT_TIMEOUT
if(shp->timeout <= 0 || shp->timeout > SHOPT_TIMEOUT) if(sh.timeout <= 0 || sh.timeout > SHOPT_TIMEOUT)
shp->timeout = SHOPT_TIMEOUT; sh.timeout = SHOPT_TIMEOUT;
#endif /* SHOPT_TIMEOUT */ #endif /* SHOPT_TIMEOUT */
shp->inlineno = 1; sh.inlineno = 1;
error_info.line = 1; error_info.line = 1;
shp->trapnote = 0; sh.trapnote = 0;
if(buff.mode == SH_JMPEXIT) if(buff.mode == SH_JMPEXIT)
{ {
buff.mode = SH_JMPERREXIT; buff.mode = SH_JMPERREXIT;
#ifdef DEBUG #ifdef DEBUG
errormsg(SH_DICT,ERROR_warn(0),"%d: mode changed to JMP_EXIT",shgd->current_pid); errormsg(SH_DICT,ERROR_warn(0),"%d: mode changed to JMP_EXIT",sh.current_pid);
#endif #endif
} }
} }
@ -545,13 +534,13 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
if(!sferr) if(!sferr)
{ {
if(--maxtry>0 && sh_isoption(SH_IGNOREEOF) if(--maxtry>0 && sh_isoption(SH_IGNOREEOF)
&& !sferror(sfstderr) && (shp->fdstatus[fno]&IOTTY)) && !sferror(sfstderr) && (sh.fdstatus[fno]&IOTTY))
{ {
sfclrerr(iop); sfclrerr(iop);
errormsg(SH_DICT,0,e_logout); errormsg(SH_DICT,0,e_logout);
continue; continue;
} }
else if(job_close(shp)<0) else if(job_close()<0)
continue; continue;
} }
else if(sferr==SH_EXITSIG) else if(sferr==SH_EXITSIG)
@ -569,38 +558,38 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
} }
goto done; goto done;
} }
shp->exitval = sh.savexit; sh.exitval = sh.savexit;
maxtry = IOMAXTRY; maxtry = IOMAXTRY;
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr) if(sh_isstate(SH_INTERACTIVE) && sh.hist_ptr)
{ {
job_wait((pid_t)0); job_wait((pid_t)0);
hist_eof(shp->gd->hist_ptr); hist_eof(sh.hist_ptr);
sfsync(sfstderr); sfsync(sfstderr);
} }
if(sh_isoption(SH_HISTORY)) if(sh_isoption(SH_HISTORY))
sh_onstate(SH_HISTORY); sh_onstate(SH_HISTORY);
job.waitall = job.curpgid = 0; job.waitall = job.curpgid = 0;
error_info.flags |= ERROR_INTERACTIVE; error_info.flags |= ERROR_INTERACTIVE;
t = (Shnode_t*)sh_parse(shp,iop,0); t = (Shnode_t*)sh_parse(iop,0);
if(!sh_isstate(SH_INTERACTIVE) && !sh_isoption(SH_CFLAG)) if(!sh_isstate(SH_INTERACTIVE) && !sh_isoption(SH_CFLAG))
error_info.flags &= ~ERROR_INTERACTIVE; error_info.flags &= ~ERROR_INTERACTIVE;
shp->readscript = 0; sh.readscript = 0;
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr) if(sh_isstate(SH_INTERACTIVE) && sh.hist_ptr)
hist_flush(shp->gd->hist_ptr); hist_flush(sh.hist_ptr);
sh_offstate(SH_HISTORY); sh_offstate(SH_HISTORY);
if(t) if(t)
{ {
execflags = sh_state(SH_ERREXIT)|sh_state(SH_INTERACTIVE); execflags = sh_state(SH_ERREXIT)|sh_state(SH_INTERACTIVE);
/* The last command may not have to fork */ /* The last command may not have to fork */
if(!sh_isstate(SH_PROFILE) && !sh_isstate(SH_INTERACTIVE) && if(!sh_isstate(SH_PROFILE) && !sh_isstate(SH_INTERACTIVE) &&
(fno<0 || !(shp->fdstatus[fno]&(IOTTY|IONOSEEK))) (fno<0 || !(sh.fdstatus[fno]&(IOTTY|IONOSEEK)))
&& !sfreserve(iop,0,0)) && !sfreserve(iop,0,0))
{ {
execflags |= sh_state(SH_NOFORK); execflags |= sh_state(SH_NOFORK);
} }
shp->st.execbrk = 0; sh.st.execbrk = 0;
sh_exec(t,execflags); sh_exec(t,execflags);
if(shp->forked) if(sh.forked)
{ {
sh_offstate(SH_INTERACTIVE); sh_offstate(SH_INTERACTIVE);
goto done; goto done;
@ -611,27 +600,27 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
} }
} }
done: done:
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
if(sh_isstate(SH_INTERACTIVE)) if(sh_isstate(SH_INTERACTIVE))
{ {
if(isatty(0) && !sh_isoption(SH_CFLAG)) if(isatty(0) && !sh_isoption(SH_CFLAG))
sfputc(sfstderr,'\n'); sfputc(sfstderr,'\n');
job_close(shp); job_close();
} }
if(jmpval == SH_JMPSCRIPT) if(jmpval == SH_JMPSCRIPT)
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
else if(jmpval == SH_JMPEXIT) else if(jmpval == SH_JMPEXIT)
sh_done(shp,0); sh_done(0);
if(fno>0) if(fno>0)
sh_close(fno); sh_close(fno);
if(shp->st.filename) if(sh.st.filename)
free((void*)shp->st.filename); free((void*)sh.st.filename);
shp->st.filename = 0; sh.st.filename = 0;
} }
/* prints out messages if files in list have been modified since last call */ /* prints out messages if files in list have been modified since last call */
static void chkmail(Shell_t *shp, char *files) static void chkmail(char *files)
{ {
register char *cp,*sp,*qp; register char *cp,*sp,*qp;
register char save; register char save;
@ -665,7 +654,7 @@ static void chkmail(Shell_t *shp, char *files)
if(!arglist && S_ISDIR(statb.st_mode)) if(!arglist && S_ISDIR(statb.st_mode))
{ {
/* generate list of directory entries */ /* generate list of directory entries */
path_complete(shp,cp,"/*",&arglist); path_complete(cp,"/*",&arglist);
} }
else else
{ {
@ -680,10 +669,10 @@ static void chkmail(Shell_t *shp, char *files)
|| statb.st_size > lastmail.st_size)) || statb.st_size > lastmail.st_size))
{ {
/* save and restore $_ */ /* save and restore $_ */
char *save = shp->lastarg; char *save = sh.lastarg;
shp->lastarg = cp; sh.lastarg = cp;
errormsg(SH_DICT,0,sh_mactry(shp,qp?qp+1:(char*)e_mailmsg)); errormsg(SH_DICT,0,sh_mactry(qp?qp+1:(char*)e_mailmsg));
shp->lastarg = save; sh.lastarg = save;
} }
lastmail = statb; lastmail = statb;
break; break;

File diff suppressed because it is too large Load diff

View file

@ -78,7 +78,6 @@ Sfdouble_t nv_getn(Namval_t *np, register Namfun_t *nfp)
{ {
register Namfun_t *fp; register Namfun_t *fp;
register Sfdouble_t d=0; register Sfdouble_t d=0;
Shell_t *shp = sh_getinterp();
char *str; char *str;
if((fp = nfp) != NIL(Namfun_t*) && !nv_local) if((fp = nfp) != NIL(Namfun_t*) && !nv_local)
fp = nfp = nfp->next; fp = nfp = nfp->next;
@ -106,7 +105,7 @@ Sfdouble_t nv_getn(Namval_t *np, register Namfun_t *nfp)
else else
str = nv_getv(np,fp?fp:nfp); str = nv_getv(np,fp?fp:nfp);
if(str && *str) if(str && *str)
d = sh_arith(shp,str); d = sh_arith(str);
} }
return(d); return(d);
} }
@ -291,7 +290,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
int bflag; int bflag;
/* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */ /* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */
savelex = *lexp; savelex = *lexp;
sh_lexopen(lexp, &sh, 0); /* needs full init (0), not what it calls reinit (1) */ sh_lexopen(lexp, 0); /* needs full init (0), not what it calls reinit (1) */
block(bp,type); block(bp,type);
if(bflag = (type==APPEND && !isblocked(bp,LOOKUPS))) if(bflag = (type==APPEND && !isblocked(bp,LOOKUPS)))
block(bp,LOOKUPS); block(bp,LOOKUPS);
@ -301,7 +300,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
sh_fun(nq,np,(char**)0); sh_fun(nq,np,(char**)0);
sh_popcontext(&sh, &checkpoint); sh_popcontext(&sh, &checkpoint);
if(sh.topfd != checkpoint.topfd) if(sh.topfd != checkpoint.topfd)
sh_iorestore(&sh, checkpoint.topfd, jmpval); sh_iorestore(checkpoint.topfd, jmpval);
unblock(bp,type); unblock(bp,type);
if(bflag) if(bflag)
unblock(bp,LOOKUPS); unblock(bp,LOOKUPS);
@ -397,7 +396,7 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
Lex_t *lexp = (Lex_t*)sh.lex_context, savelex; Lex_t *lexp = (Lex_t*)sh.lex_context, savelex;
/* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */ /* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */
savelex = *lexp; savelex = *lexp;
sh_lexopen(lexp, &sh, 0); /* needs full init (0), not what it calls reinit (1) */ sh_lexopen(lexp, 0); /* needs full init (0), not what it calls reinit (1) */
node = *SH_VALNOD; node = *SH_VALNOD;
if(!nv_isnull(SH_VALNOD)) if(!nv_isnull(SH_VALNOD))
{ {
@ -416,7 +415,7 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
sh_fun(nq,np,(char**)0); sh_fun(nq,np,(char**)0);
sh_popcontext(&sh, &checkpoint); sh_popcontext(&sh, &checkpoint);
if(sh.topfd != checkpoint.topfd) if(sh.topfd != checkpoint.topfd)
sh_iorestore(&sh, checkpoint.topfd, jmpval); sh_iorestore(checkpoint.topfd, jmpval);
unblock(bp,type); unblock(bp,type);
if(!vp->disc[type]) if(!vp->disc[type])
chktfree(np,vp); chktfree(np,vp);
@ -1114,7 +1113,6 @@ Namval_t *nv_search(const char *name, Dt_t *root, int mode)
*/ */
Namval_t *nv_bfsearch(const char *name, Dt_t *root, Namval_t **var, char **last) Namval_t *nv_bfsearch(const char *name, Dt_t *root, Namval_t **var, char **last)
{ {
Shell_t *shp = sh_getinterp();
int c,offset = staktell(); int c,offset = staktell();
register char *sp, *cp=0; register char *sp, *cp=0;
Namval_t *np, *nq; Namval_t *np, *nq;
@ -1172,12 +1170,12 @@ Namval_t *nv_bfsearch(const char *name, Dt_t *root, Namval_t **var, char **last)
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(nv_istable(nq)) if(nv_istable(nq))
{ {
Namval_t *nsp = shp->namespace; Namval_t *nsp = sh.namespace;
if(last==0) if(last==0)
return(nv_search(name,root,0)); return(nv_search(name,root,0));
shp->namespace = 0; sh.namespace = 0;
stakputs(nv_name(nq)); stakputs(nv_name(nq));
shp->namespace = nsp; sh.namespace = nsp;
stakputs(dname-1); stakputs(dname-1);
stakputc(0); stakputc(0);
np = nv_search(stakptr(offset),root,0); np = nv_search(stakptr(offset),root,0);
@ -1300,7 +1298,6 @@ struct table
{ {
Namfun_t fun; Namfun_t fun;
Namval_t *parent; Namval_t *parent;
Shell_t *shp;
Dt_t *dict; Dt_t *dict;
}; };
@ -1316,7 +1313,7 @@ static Namval_t *next_table(register Namval_t* np, Dt_t *root,Namfun_t *fp)
static Namval_t *create_table(Namval_t *np,const char *name,int flags,Namfun_t *fp) static Namval_t *create_table(Namval_t *np,const char *name,int flags,Namfun_t *fp)
{ {
struct table *tp = (struct table *)fp; struct table *tp = (struct table *)fp;
tp->shp->last_table = np; sh.last_table = np;
return(nv_create(name, tp->dict, flags, fp)); return(nv_create(name, tp->dict, flags, fp));
} }
@ -1339,9 +1336,12 @@ static Namfun_t *clone_table(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp
return(&ntp->fun); return(&ntp->fun);
} }
/*
* The first two fields must correspond with those in 'struct adata' in name.c and 'struct tdata' in typeset.c
* (those fields are used via a type conversion in scanfilter() in name.c)
*/
struct adata struct adata
{ {
Shell_t *sh;
Namval_t *tp; Namval_t *tp;
char *mapname; char *mapname;
char **argnam; char **argnam;
@ -1351,8 +1351,7 @@ struct adata
static void delete_fun(Namval_t *np, void *data) static void delete_fun(Namval_t *np, void *data)
{ {
Shell_t *shp = ((struct adata*)data)->sh; nv_delete(np,sh.fun_tree,NV_NOFREE);
nv_delete(np,shp->fun_tree,NV_NOFREE);
} }
static void put_table(register Namval_t* np, const char* val, int flags, Namfun_t* fp) static void put_table(register Namval_t* np, const char* val, int flags, Namfun_t* fp)
@ -1370,8 +1369,7 @@ static void put_table(register Namval_t* np, const char* val, int flags, Namfun_
return; return;
memset(&data,0,sizeof(data)); memset(&data,0,sizeof(data));
data.mapname = nv_name(np); data.mapname = nv_name(np);
data.sh = ((struct table*)fp)->shp; nv_scan(sh.fun_tree,delete_fun,(void*)&data,NV_FUNCTION,NV_FUNCTION|NV_NOSCOPE);
nv_scan(data.sh->fun_tree,delete_fun,(void*)&data,NV_FUNCTION,NV_FUNCTION|NV_NOSCOPE);
dtview(root,0); dtview(root,0);
for(mp=(Namval_t*)dtfirst(root);mp;mp=nq) for(mp=(Namval_t*)dtfirst(root);mp;mp=nq)
{ {
@ -1439,14 +1437,13 @@ Namval_t *nv_parent(Namval_t *np)
Dt_t *nv_dict(Namval_t* np) Dt_t *nv_dict(Namval_t* np)
{ {
Shell_t *shp=sh_getinterp();
struct table *tp = (struct table*)nv_hasdisc(np,&table_disc); struct table *tp = (struct table*)nv_hasdisc(np,&table_disc);
if(tp) if(tp)
return(tp->dict); return(tp->dict);
np = shp->last_table; np = sh.last_table;
if(np && (tp = (struct table*)nv_hasdisc(np,&table_disc))) if(np && (tp = (struct table*)nv_hasdisc(np,&table_disc)))
return(tp->dict); return(tp->dict);
return(shp->var_tree); return(sh.var_tree);
} }
int nv_istable(Namval_t *np) int nv_istable(Namval_t *np)
@ -1476,7 +1473,6 @@ Namval_t *nv_mount(Namval_t *np, const char *name, Dt_t *dict)
nv_offattr(mp,NV_TABLE); nv_offattr(mp,NV_TABLE);
if(!nv_isnull(mp)) if(!nv_isnull(mp))
_nv_unset(mp,NV_RDONLY); _nv_unset(mp,NV_RDONLY);
tp->shp = sh_getinterp();
tp->dict = dict; tp->dict = dict;
tp->parent = pp; tp->parent = pp;
tp->fun.disc = &table_disc; tp->fun.disc = &table_disc;
@ -1503,7 +1499,7 @@ const Namdisc_t *nv_discfun(int which)
int nv_hasget(Namval_t *np) int nv_hasget(Namval_t *np)
{ {
register Namfun_t *fp; register Namfun_t *fp;
if(np==sh_scoped(&sh,IFSNOD)) if(np==sh_scoped(IFSNOD))
return(0); /* avoid BUG_IFSISSET: always return false for IFS */ return(0); /* avoid BUG_IFSISSET: always return false for IFS */
for(fp=np->nvfun; fp; fp=fp->next) for(fp=np->nvfun; fp; fp=fp->next)
{ {
@ -1515,13 +1511,12 @@ int nv_hasget(Namval_t *np)
} }
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
Namval_t *sh_fsearch(Shell_t *shp, const char *fname, int add) Namval_t *sh_fsearch(const char *fname, int add)
{ {
Stk_t *stkp = shp->stk; int offset = stktell(sh.stk);
int offset = stktell(stkp); sfputr(sh.stk,nv_name(sh.namespace),'.');
sfputr(stkp,nv_name(shp->namespace),'.'); sfputr(sh.stk,fname,0);
sfputr(stkp,fname,0); fname = stkptr(sh.stk,offset);
fname = stkptr(stkp,offset);
return(nv_search(fname,sh_subfuntree(add&NV_ADD),add)); return(nv_search(fname,sh_subfuntree(add&NV_ADD),add));
} }
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */

View file

@ -538,7 +538,6 @@ void nv_attribute(register Namval_t *np,Sfio_t *out,char *prefix,int noname)
struct Walk struct Walk
{ {
Shell_t *shp;
Sfio_t *out; Sfio_t *out;
Dt_t *root; Dt_t *root;
int noscope; int noscope;
@ -666,18 +665,18 @@ void nv_outnode(Namval_t *np, Sfio_t* out, int indent, int special)
static void outval(char *name, const char *vname, struct Walk *wp) static void outval(char *name, const char *vname, struct Walk *wp)
{ {
register Namval_t *np, *nq=0, *last_table=wp->shp->last_table; register Namval_t *np, *nq=0, *last_table=sh.last_table;
register Namfun_t *fp; register Namfun_t *fp;
int isarray=0, special=0,mode=0; int isarray=0, special=0,mode=0;
if(*name!='.' || vname[strlen(vname)-1]==']') if(*name!='.' || vname[strlen(vname)-1]==']')
mode = NV_ARRAY; mode = NV_ARRAY;
if(!(np=nv_open(vname,wp->root,mode|NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_NOFAIL|wp->noscope))) if(!(np=nv_open(vname,wp->root,mode|NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_NOFAIL|wp->noscope)))
{ {
wp->shp->last_table = last_table; sh.last_table = last_table;
return; return;
} }
if(!wp->out) if(!wp->out)
wp->shp->last_table = last_table; sh.last_table = last_table;
fp = nv_hasdisc(np,&treedisc); fp = nv_hasdisc(np,&treedisc);
if(*name=='.') if(*name=='.')
{ {
@ -952,18 +951,16 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
Namarr_t *arp = nv_arrayptr(np); Namarr_t *arp = nv_arrayptr(np);
Dt_t *save_tree = sh.var_tree; Dt_t *save_tree = sh.var_tree;
Namval_t *mp=0; Namval_t *mp=0;
Shell_t *shp = sh_getinterp();
char *xpname = xp?stakcopy(nv_name(xp)):0; char *xpname = xp?stakcopy(nv_name(xp)):0;
walk.shp = shp;
if(xp) if(xp)
{ {
shp->last_root = shp->prev_root; sh.last_root = sh.prev_root;
shp->last_table = shp->prev_table; sh.last_table = sh.prev_table;
} }
if(shp->last_table) if(sh.last_table)
shp->last_root = nv_dict(shp->last_table); sh.last_root = nv_dict(sh.last_table);
if(shp->last_root) if(sh.last_root)
shp->var_tree = shp->last_root; sh.var_tree = sh.last_root;
stakputs(nv_name(np)); stakputs(nv_name(np));
if(arp && !(arp->nelem&ARRAY_SCAN) && (subscript = nv_getsub(np))) if(arp && !(arp->nelem&ARRAY_SCAN) && (subscript = nv_getsub(np)))
{ {
@ -977,9 +974,9 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
mp = np; mp = np;
name = stakfreeze(1); name = stakfreeze(1);
len = strlen(name); len = strlen(name);
shp->last_root = 0; sh.last_root = 0;
dir = nv_diropen(mp,name); dir = nv_diropen(mp,name);
walk.root = shp->last_root?shp->last_root:shp->var_tree; walk.root = sh.last_root?sh.last_root:sh.var_tree;
if(subscript) if(subscript)
name[strlen(name)-1] = 0; name[strlen(name)-1] = 0;
while(cp = nv_dirnext(dir)) while(cp = nv_dirnext(dir))
@ -988,7 +985,7 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
continue; continue;
if(xp) if(xp)
{ {
Dt_t *dp = shp->var_tree; Dt_t *dp = sh.var_tree;
Namval_t *nq, *mq; Namval_t *nq, *mq;
if(strlen(cp)<=len) if(strlen(cp)<=len)
continue; continue;
@ -999,9 +996,9 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
stakputs(xpname); stakputs(xpname);
stakputs(cp+len); stakputs(cp+len);
stakputc(0); stakputc(0);
shp->var_tree = save_tree; sh.var_tree = save_tree;
mq = nv_open(stakptr(0),shp->prev_root,NV_VARNAME|NV_NOASSIGN|NV_NOFAIL); mq = nv_open(stakptr(0),sh.prev_root,NV_VARNAME|NV_NOASSIGN|NV_NOFAIL);
shp->var_tree = dp; sh.var_tree = dp;
if(nq && mq) if(nq && mq)
{ {
nv_clone(nq,mq,flags|NV_RAW); nv_clone(nq,mq,flags|NV_RAW);
@ -1021,7 +1018,7 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
nv_dirclose(dir); nv_dirclose(dir);
if(xp) if(xp)
{ {
shp->var_tree = save_tree; sh.var_tree = save_tree;
return((char*)0); return((char*)0);
} }
argv = (char**)stakalloc((n+1)*sizeof(char*)); argv = (char**)stakalloc((n+1)*sizeof(char*));
@ -1045,7 +1042,7 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
walk.flags = flags; walk.flags = flags;
genvalue(argv,name,0,&walk); genvalue(argv,name,0,&walk);
stakset(savptr,savtop); stakset(savptr,savtop);
shp->var_tree = save_tree; sh.var_tree = save_tree;
if(!outfile) if(!outfile)
return((char*)0); return((char*)0);
sfputc(out,0); sfputc(out,0);
@ -1095,16 +1092,15 @@ static void put_tree(register Namval_t *np, const char *val, int flags,Namfun_t
return; return;
if(!nv_isattr(np,(NV_INTEGER|NV_BINARY))) if(!nv_isattr(np,(NV_INTEGER|NV_BINARY)))
{ {
Shell_t *shp = sh_getinterp(); Namval_t *last_table = sh.last_table;
Namval_t *last_table = shp->last_table; Dt_t *last_root = sh.last_root;
Dt_t *last_root = shp->last_root; Namval_t *mp = val?nv_open(val,sh.var_tree,NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_ARRAY|NV_NOFAIL):0;
Namval_t *mp = val?nv_open(val,shp->var_tree,NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_ARRAY|NV_NOFAIL):0;
if(mp && nv_isvtree(mp)) if(mp && nv_isvtree(mp))
{ {
shp->prev_table = shp->last_table; sh.prev_table = sh.last_table;
shp->prev_root = shp->last_root; sh.prev_root = sh.last_root;
shp->last_table = last_table; sh.last_table = last_table;
shp->last_root = last_root; sh.last_root = last_root;
if(!(flags&NV_APPEND)) if(!(flags&NV_APPEND))
walk_tree(np,(Namval_t*)0,(flags&NV_NOSCOPE)|1); walk_tree(np,(Namval_t*)0,(flags&NV_NOSCOPE)|1);
nv_clone(mp,np,NV_COMVAR); nv_clone(mp,np,NV_COMVAR);

View file

@ -79,7 +79,6 @@ typedef struct Namchld
struct Namtype struct Namtype
{ {
Namfun_t fun; Namfun_t fun;
Shell_t *sh;
Namval_t *np; Namval_t *np;
Namval_t *parent; Namval_t *parent;
Namval_t *bp; Namval_t *bp;
@ -779,7 +778,6 @@ void nv_addtype(Namval_t *np, const char *optstr, Optdisc_t *op, size_t optsz)
{ {
Namdecl_t *cp = sh_newof((Namdecl_t*)0,Namdecl_t,1,optsz); Namdecl_t *cp = sh_newof((Namdecl_t*)0,Namdecl_t,1,optsz);
Optdisc_t *dp = (Optdisc_t*)(cp+1); Optdisc_t *dp = (Optdisc_t*)(cp+1);
Shell_t *shp = sh_getinterp();
Namval_t *mp,*bp; Namval_t *mp,*bp;
char *name; char *name;
if(optstr) if(optstr)
@ -789,25 +787,25 @@ void nv_addtype(Namval_t *np, const char *optstr, Optdisc_t *op, size_t optsz)
memcpy((void*)dp,(void*)op, optsz); memcpy((void*)dp,(void*)op, optsz);
cp->optinfof = (void*)dp; cp->optinfof = (void*)dp;
cp->tp = np; cp->tp = np;
mp = nv_search("typeset",shp->bltin_tree,0); mp = nv_search("typeset",sh.bltin_tree,0);
if(name=strrchr(np->nvname,'.')) if(name=strrchr(np->nvname,'.'))
name++; name++;
else else
name = np->nvname; name = np->nvname;
#if SHOPT_NAMESPACE #if SHOPT_NAMESPACE
if(bp=(Namval_t*)shp->namespace) if(bp=(Namval_t*)sh.namespace)
{ {
Namtype_t *tp = (Namtype_t*)nv_hasdisc(np, &type_disc); Namtype_t *tp = (Namtype_t*)nv_hasdisc(np, &type_disc);
if(tp) if(tp)
tp->nsp = bp; tp->nsp = bp;
if(!shp->strbuf2) if(!sh.strbuf2)
shp->strbuf2 = sfstropen(); sh.strbuf2 = sfstropen();
sfprintf(shp->strbuf2,".%s.%s%c\n",nv_name(bp)+1,name,0); sfprintf(sh.strbuf2,".%s.%s%c\n",nv_name(bp)+1,name,0);
name = sfstruse(shp->strbuf2); name = sfstruse(sh.strbuf2);
} }
#endif /* SHOPT_NAMESPACE */ #endif /* SHOPT_NAMESPACE */
if((bp=nv_search(name,shp->fun_tree,NV_NOSCOPE)) && !bp->nvalue.ip) if((bp=nv_search(name,sh.fun_tree,NV_NOSCOPE)) && !bp->nvalue.ip)
nv_delete(bp,shp->fun_tree,0); nv_delete(bp,sh.fun_tree,0);
bp = sh_addbuiltin(name, (Shbltin_f)mp->nvalue.bfp, (void*)cp); bp = sh_addbuiltin(name, (Shbltin_f)mp->nvalue.bfp, (void*)cp);
nv_onattr(bp,nv_isattr(mp,NV_PUBLIC)); nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
nv_onattr(np, NV_RDONLY); nv_onattr(np, NV_RDONLY);
@ -1294,9 +1292,8 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
int rdonly = nv_isattr(np,NV_RDONLY); int rdonly = nv_isattr(np,NV_RDONLY);
char *val=0; char *val=0;
Namarr_t *ap=0; Namarr_t *ap=0;
Shell_t *shp = sh_getinterp();
int nelem = 0; int nelem = 0;
unsigned int subshell = shp->subshell; unsigned int subshell = sh.subshell;
#if SHOPT_TYPEDEF #if SHOPT_TYPEDEF
Namval_t *tq; Namval_t *tq;
if(nv_type(np)==tp) if(nv_type(np)==tp)
@ -1326,7 +1323,7 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
if(subshell) if(subshell)
{ {
sh_assignok(np,1); sh_assignok(np,1);
shp->subshell = 0; sh.subshell = 0;
} }
nv_putsub(np,"0",ARRAY_FILL); nv_putsub(np,"0",ARRAY_FILL);
ap = nv_arrayptr(np); ap = nv_arrayptr(np);
@ -1369,7 +1366,7 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
nv_putsub(np,"0",0); nv_putsub(np,"0",0);
_nv_unset(np,NV_RDONLY|NV_TYPE); _nv_unset(np,NV_RDONLY|NV_TYPE);
ap->nelem--; ap->nelem--;
shp->subshell = subshell; sh.subshell = subshell;
} }
} }
type_init(np); type_init(np);
@ -1429,14 +1426,14 @@ static void write_indent(Sfio_t *out,char *str,int n,int indent)
} }
} }
int sh_outtype(Shell_t *shp,Sfio_t *out) int sh_outtype(Sfio_t *out)
{ {
Namval_t node,*mp,*tp; Namval_t node,*mp,*tp;
Dt_t *dp; Dt_t *dp;
char *cp,*sp,*xp,nvtype[sizeof(NV_CLASS)]; char *cp,*sp,*xp,nvtype[sizeof(NV_CLASS)];
Sfio_t *iop=0; Sfio_t *iop=0;
int n=0,indent = 0; int n=0,indent = 0;
if(cp=shp->prefix) if(cp=sh.prefix)
{ {
indent=1; indent=1;
while(*cp) while(*cp)
@ -1444,10 +1441,10 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
if(*cp++ =='.') if(*cp++ =='.')
indent++; indent++;
} }
n = cp-shp->prefix+1; n = cp-sh.prefix+1;
} }
strcpy(nvtype,NV_CLASS); strcpy(nvtype,NV_CLASS);
if(!(mp = nv_open(nvtype, shp->var_base,NV_NOADD|NV_VARNAME))) if(!(mp = nv_open(nvtype, sh.var_base,NV_NOADD|NV_VARNAME)))
return(0); return(0);
memcpy(&node,L_ARGNOD,sizeof(node)); memcpy(&node,L_ARGNOD,sizeof(node));
L_ARGNOD->nvfun = 0; L_ARGNOD->nvfun = 0;
@ -1459,7 +1456,7 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
/* skip over enums */ /* skip over enums */
if(tp->nvfun && !nv_isvtree(tp)) if(tp->nvfun && !nv_isvtree(tp))
continue; continue;
if(!nv_search(tp->nvname,shp->bltin_tree,0)) if(!nv_search(tp->nvname,sh.bltin_tree,0))
continue; continue;
sfprintf(out,"typeset -T %s\n",tp->nvname); sfprintf(out,"typeset -T %s\n",tp->nvname);
} }
@ -1467,13 +1464,13 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
{ {
if(nv_isnull(tp) || !nv_isvtree(tp)) if(nv_isnull(tp) || !nv_isvtree(tp))
continue; continue;
if(indent && (memcmp(tp->nvname,shp->prefix,n-1) || tp->nvname[n-1]!='.' || strchr(tp->nvname+n,'.'))) if(indent && (memcmp(tp->nvname,sh.prefix,n-1) || tp->nvname[n-1]!='.' || strchr(tp->nvname+n,'.')))
continue; continue;
nv_settype(L_ARGNOD,tp,0); nv_settype(L_ARGNOD,tp,0);
if(indent) if(indent)
sfnputc(out,'\t',indent); sfnputc(out,'\t',indent);
sfprintf(out,"typeset -T %s=",tp->nvname+n); sfprintf(out,"typeset -T %s=",tp->nvname+n);
shp->last_table = 0; sh.last_table = 0;
cp = nv_getval(L_ARGNOD); cp = nv_getval(L_ARGNOD);
if(indent) if(indent)
write_indent(out,cp,strlen(cp)-1,indent); write_indent(out,cp,strlen(cp)-1,indent);
@ -1499,11 +1496,11 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
if(mp->nvalue.ip && mp->nvalue.rp->hoffset>=0) if(mp->nvalue.ip && mp->nvalue.rp->hoffset>=0)
{ {
if(nv_isattr(mp,NV_FTMP)) if(nv_isattr(mp,NV_FTMP))
iop = shp->heredocs; iop = sh.heredocs;
else if(xp=mp->nvalue.rp->fname) else if(xp=mp->nvalue.rp->fname)
iop = sfopen(iop,xp,"r"); iop = sfopen(iop,xp,"r");
else if(shp->gd->hist_ptr) else if(sh.hist_ptr)
iop = (shp->gd->hist_ptr)->histfp; iop = sh.hist_ptr->histfp;
if(iop && sfseek(iop,(Sfoff_t)mp->nvalue.rp->hoffset,SEEK_SET)>=0) if(iop && sfseek(iop,(Sfoff_t)mp->nvalue.rp->hoffset,SEEK_SET)>=0)
sfmove(iop,out, nv_size(mp), -1); sfmove(iop,out, nv_size(mp), -1);
else else
@ -1530,8 +1527,8 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
sfnputc(out,'\t',indent); sfnputc(out,'\t',indent);
sfwrite(out,")\n",2); sfwrite(out,")\n",2);
} }
dtdelete(shp->var_base,L_ARGNOD); dtdelete(sh.var_base,L_ARGNOD);
memcpy(L_ARGNOD,&node,sizeof(node)); memcpy(L_ARGNOD,&node,sizeof(node));
dtinsert(shp->var_base,L_ARGNOD); dtinsert(sh.var_base,L_ARGNOD);
return(0); return(0);
} }

View file

@ -138,7 +138,7 @@ static unsigned long writedefs(Lex_t *lexp,struct argnod *arglist, int line, int
n = cp-argp->argval; n = cp-argp->argval;
else else
n = strlen(argp->argval); n = strlen(argp->argval);
eline = lexp->sh->inlineno-(lexp->token==NL); eline = sh.inlineno-(lexp->token==NL);
r=kiaentity(lexp,argp->argval,n,type,line,eline,parent,justify,width,atbuff); r=kiaentity(lexp,argp->argval,n,type,line,eline,parent,justify,width,atbuff);
sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline); sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline);
argp = argp->argnxt.ap; argp = argp->argnxt.ap;
@ -323,7 +323,7 @@ static Shnode_t *getanode(Lex_t *lp, struct argnod *ap)
t->ar.arline = sh_getlineno(lp); t->ar.arline = sh_getlineno(lp);
t->ar.arexpr = ap; t->ar.arexpr = ap;
if(ap->argflag&ARG_RAW) if(ap->argflag&ARG_RAW)
t->ar.arcomp = sh_arithcomp(lp->sh,ap->argval); t->ar.arcomp = sh_arithcomp(ap->argval);
else else
{ {
const char *p, *q; const char *p, *q;
@ -333,7 +333,7 @@ static Shnode_t *getanode(Lex_t *lp, struct argnod *ap)
for(q = p; !isspace(*q) && *q != '\0'; q++) for(q = p; !isspace(*q) && *q != '\0'; q++)
; ;
errormsg(SH_DICT, ERROR_warn(0), e_lexwarnvar, errormsg(SH_DICT, ERROR_warn(0), e_lexwarnvar,
lp->sh->inlineno, ap->argval, q - p, p); sh.inlineno, ap->argval, q - p, p);
} }
t->ar.arcomp = 0; t->ar.arcomp = 0;
} }
@ -366,27 +366,27 @@ static Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r)
* Flag can be the union of SH_EOF|SH_NL * Flag can be the union of SH_EOF|SH_NL
*/ */
void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag) void *sh_parse(Sfio_t *iop, int flag)
{ {
register Shnode_t *t; register Shnode_t *t;
Lex_t *lexp = (Lex_t*)shp->lex_context; Lex_t *lexp = (Lex_t*)sh.lex_context;
Fcin_t sav_input; Fcin_t sav_input;
struct argnod *sav_arg = lexp->arg; struct argnod *sav_arg = lexp->arg;
int sav_prompt = shp->nextprompt; int sav_prompt = sh.nextprompt;
if(shp->binscript && (sffileno(iop)==shp->infd || (flag&SH_FUNEVAL))) if(sh.binscript && (sffileno(iop)==sh.infd || (flag&SH_FUNEVAL)))
return((void*)sh_trestore(shp,iop)); return((void*)sh_trestore(iop));
fcsave(&sav_input); fcsave(&sav_input);
shp->st.staklist = 0; sh.st.staklist = 0;
lexp->noreserv = 0; lexp->noreserv = 0;
lexp->heredoc = 0; lexp->heredoc = 0;
lexp->inlineno = shp->inlineno; lexp->inlineno = sh.inlineno;
lexp->firstline = shp->st.firstline; lexp->firstline = sh.st.firstline;
shp->nextprompt = 1; sh.nextprompt = 1;
loop_level = 0; loop_level = 0;
label_list = label_last = 0; label_list = label_last = 0;
if(sh_isoption(SH_VERBOSE)) if(sh_isoption(SH_VERBOSE))
sh_onstate(SH_VERBOSE); sh_onstate(SH_VERBOSE);
sh_lexopen(lexp,shp,0); sh_lexopen(lexp,0);
if(fcfopen(iop) < 0) if(fcfopen(iop) < 0)
return(NIL(void*)); return(NIL(void*));
if(fcfile()) if(fcfile())
@ -405,16 +405,16 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
errormsg(SH_DICT,ERROR_exit(1),e_lexversion); errormsg(SH_DICT,ERROR_exit(1),e_lexversion);
UNREACHABLE(); UNREACHABLE();
} }
if(sffileno(iop)==shp->infd || (flag&SH_FUNEVAL)) if(sffileno(iop)==sh.infd || (flag&SH_FUNEVAL))
shp->binscript = 1; sh.binscript = 1;
sfgetc(iop); sfgetc(iop);
t = sh_trestore(shp,iop); t = sh_trestore(iop);
if(flag&SH_NL) if(flag&SH_NL)
{ {
Shnode_t *tt; Shnode_t *tt;
while(1) while(1)
{ {
if(!(tt = sh_trestore(shp,iop))) if(!(tt = sh_trestore(iop)))
break; break;
t =makelist(lexp,TLST, t, tt); t =makelist(lexp,TLST, t, tt);
} }
@ -423,9 +423,9 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
} }
} }
flag &= ~SH_FUNEVAL; flag &= ~SH_FUNEVAL;
if((flag&SH_NL) && (shp->inlineno=error_info.line+shp->st.firstline)==0) if((flag&SH_NL) && (sh.inlineno=error_info.line+sh.st.firstline)==0)
shp->inlineno=1; sh.inlineno=1;
shp->nextprompt = 2; sh.nextprompt = 2;
t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL)); t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL));
fcclose(); fcclose();
fcrestore(&sav_input); fcrestore(&sav_input);
@ -437,13 +437,13 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
if(sp) if(sp)
sfclose(sp); sfclose(sp);
} }
shp->nextprompt = sav_prompt; sh.nextprompt = sav_prompt;
if(flag&SH_NL) if(flag&SH_NL)
{ {
shp->st.firstline = lexp->firstline; sh.st.firstline = lexp->firstline;
shp->inlineno = lexp->inlineno; sh.inlineno = lexp->inlineno;
} }
stkseek(shp->stk,0); stkseek(sh.stk,0);
return((void*)t); return((void*)t);
} }
@ -455,9 +455,9 @@ Shnode_t *sh_dolparen(Lex_t* lp)
{ {
register Shnode_t *t=0; register Shnode_t *t=0;
Sfio_t *sp = fcfile(); Sfio_t *sp = fcfile();
int line = lp->sh->inlineno; int line = sh.inlineno;
lp->sh->inlineno = error_info.line+lp->sh->st.firstline; sh.inlineno = error_info.line+sh.st.firstline;
sh_lexopen(lp,lp->sh,1); sh_lexopen(lp,1);
lp->comsub = 1; lp->comsub = 1;
switch(sh_lex(lp)) switch(sh_lex(lp))
{ {
@ -488,7 +488,7 @@ Shnode_t *sh_dolparen(Lex_t* lp)
fcsopen(cp); fcsopen(cp);
sfclose(sp); sfclose(sp);
} }
lp->sh->inlineno = line; sh.inlineno = line;
return(t); return(t);
} }
@ -496,11 +496,11 @@ Shnode_t *sh_dolparen(Lex_t* lp)
* remove temporary files and stacks * remove temporary files and stacks
*/ */
void sh_freeup(Shell_t *shp) void sh_freeup(void)
{ {
if(shp->st.staklist) if(sh.st.staklist)
sh_funstaks(shp->st.staklist,-1); sh_funstaks(sh.st.staklist,-1);
shp->st.staklist = 0; sh.st.staklist = 0;
} }
/* /*
@ -705,7 +705,7 @@ static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
register int offset; register int offset;
register struct argnod *argp; register struct argnod *argp;
register int n; register int n;
Stk_t *stkp = lexp->sh->stk; Stk_t *stkp = sh.stk;
int argflag = lexp->arg->argflag; int argflag = lexp->arg->argflag;
/* save current input */ /* save current input */
Fcin_t sav_input; Fcin_t sav_input;
@ -761,7 +761,7 @@ static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
} }
else else
tw->wh.whinc = 0; tw->wh.whinc = 0;
sh_lexopen(lexp, lexp->sh,1); sh_lexopen(lexp, 1);
if((n=sh_lex(lexp))==NL) if((n=sh_lex(lexp))==NL)
n = skipnl(lexp,0); n = skipnl(lexp,0);
else if(n==';') else if(n==';')
@ -776,7 +776,6 @@ static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
static Shnode_t *funct(Lex_t *lexp) static Shnode_t *funct(Lex_t *lexp)
{ {
Shell_t *shp = lexp->sh;
register Shnode_t *t; register Shnode_t *t;
register int flag; register int flag;
struct slnod *volatile slp=0; struct slnod *volatile slp=0;
@ -791,11 +790,11 @@ static Shnode_t *funct(Lex_t *lexp)
struct argnod *savelabel = label_last; struct argnod *savelabel = label_last;
struct checkpt buff; struct checkpt buff;
int save_optget = opt_get; int save_optget = opt_get;
void *in_mktype = shp->mktype; void *in_mktype = sh.mktype;
shp->mktype = 0; sh.mktype = 0;
opt_get = 0; opt_get = 0;
t = getnode(functnod); t = getnode(functnod);
t->funct.functline = shp->inlineno; t->funct.functline = sh.inlineno;
t->funct.functtyp=TFUN; t->funct.functtyp=TFUN;
t->funct.functargs = 0; t->funct.functargs = 0;
if(!(flag = (lexp->token==FUNCTSYM))) if(!(flag = (lexp->token==FUNCTSYM)))
@ -809,21 +808,21 @@ static Shnode_t *funct(Lex_t *lexp)
fcfopen(iop); fcfopen(iop);
} }
t->funct.functloc = first = fctell(); t->funct.functloc = first = fctell();
if(!shp->st.filename || sffileno(iop)<0) if(!sh.st.filename || sffileno(iop)<0)
{ {
if(fcfill() >= 0) if(fcfill() >= 0)
fcseek(-1); fcseek(-1);
if(sh_isstate(SH_HISTORY) && shp->gd->hist_ptr) if(sh_isstate(SH_HISTORY) && sh.hist_ptr)
t->funct.functloc = sfseek(shp->gd->hist_ptr->histfp,(off_t)0,SEEK_CUR); t->funct.functloc = sfseek(sh.hist_ptr->histfp, (off_t)0, SEEK_CUR);
else else
{ {
/* copy source to temporary file */ /* copy source to temporary file */
t->funct.functloc = 0; t->funct.functloc = 0;
if(lexp->sh->heredocs) if(sh.heredocs)
t->funct.functloc = sfseek(lexp->sh->heredocs,(Sfoff_t)0, SEEK_END); t->funct.functloc = sfseek(sh.heredocs,(Sfoff_t)0, SEEK_END);
else else
lexp->sh->heredocs = sftmp(HERE_MEM); sh.heredocs = sftmp(HERE_MEM);
lexp->sh->funlog = lexp->sh->heredocs; sh.funlog = sh.heredocs;
t->funct.functtyp |= FPIN; t->funct.functtyp |= FPIN;
} }
} }
@ -846,7 +845,7 @@ static Shnode_t *funct(Lex_t *lexp)
t->funct.functargs = ac = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*)); t->funct.functargs = ac = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*));
if(ac->comset || (ac->comtyp&COMSCAN)) if(ac->comset || (ac->comtyp&COMSCAN))
{ {
errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,lexp->sh->inlineno); errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,sh.inlineno);
UNREACHABLE(); UNREACHABLE();
} }
argv0 = argv = ((struct dolnod*)ac->comarg)->dolval+ARG_SPARE; argv0 = argv = ((struct dolnod*)ac->comarg)->dolval+ARG_SPARE;
@ -858,15 +857,15 @@ static Shnode_t *funct(Lex_t *lexp)
} }
if(c) if(c)
{ {
errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,lexp->sh->inlineno); errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,sh.inlineno);
UNREACHABLE(); UNREACHABLE();
} }
nargs = argv-argv0; nargs = argv-argv0;
size += sizeof(struct dolnod)+(nargs+ARG_SPARE)*sizeof(char*); size += sizeof(struct dolnod)+(nargs+ARG_SPARE)*sizeof(char*);
if(shp->shcomp && memcmp(".sh.math.",t->funct.functnam,9)==0) if(sh.shcomp && memcmp(".sh.math.",t->funct.functnam,9)==0)
{ {
Namval_t *np= nv_open(t->funct.functnam,shp->fun_tree,NV_ADD|NV_VARNAME); Namval_t *np= nv_open(t->funct.functnam,sh.fun_tree,NV_ADD|NV_VARNAME);
np->nvalue.rp = new_of(struct Ufunction,shp->funload?sizeof(Dtlink_t):0); np->nvalue.rp = new_of(struct Ufunction,sh.funload?sizeof(Dtlink_t):0);
memset((void*)np->nvalue.rp,0,sizeof(struct Ufunction)); memset((void*)np->nvalue.rp,0,sizeof(struct Ufunction));
np->nvalue.rp->argc = ((struct dolnod*)ac->comarg)->dolnum; np->nvalue.rp->argc = ((struct dolnod*)ac->comarg)->dolnum;
} }
@ -876,7 +875,7 @@ static Shnode_t *funct(Lex_t *lexp)
} }
if((flag && lexp->token!=LBRACE) || lexp->token==EOFSYM) if((flag && lexp->token!=LBRACE) || lexp->token==EOFSYM)
sh_syntax(lexp); sh_syntax(lexp);
sh_pushcontext(shp,&buff,1); sh_pushcontext(&sh,&buff,1);
jmpval = sigsetjmp(buff.buff,0); jmpval = sigsetjmp(buff.buff,0);
if(jmpval == 0) if(jmpval == 0)
{ {
@ -885,8 +884,8 @@ static Shnode_t *funct(Lex_t *lexp)
savstak = stakinstall(savstak, 0); savstak = stakinstall(savstak, 0);
slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod)); slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod));
slp->slchild = 0; slp->slchild = 0;
slp->slnext = shp->st.staklist; slp->slnext = sh.st.staklist;
shp->st.staklist = 0; sh.st.staklist = 0;
t->funct.functstak = (struct slnod*)slp; t->funct.functstak = (struct slnod*)slp;
/* /*
* store the pathname of function definition file on stack * store the pathname of function definition file on stack
@ -897,8 +896,8 @@ static Shnode_t *funct(Lex_t *lexp)
fp->functnam = 0; fp->functnam = 0;
fp->functargs = 0; fp->functargs = 0;
fp->functline = t->funct.functline; fp->functline = t->funct.functline;
if(shp->st.filename) if(sh.st.filename)
fp->functnam = stakcopy(shp->st.filename); fp->functnam = stakcopy(sh.st.filename);
loop_level = 0; loop_level = 0;
label_last = label_list; label_last = label_list;
if(size) if(size)
@ -926,16 +925,16 @@ static Shnode_t *funct(Lex_t *lexp)
} }
t->funct.functtre = item(lexp,SH_NOIO); t->funct.functtre = item(lexp,SH_NOIO);
} }
else if(shp->shcomp) else if(sh.shcomp)
exit(1); exit(1);
sh_popcontext(shp,&buff); sh_popcontext(&sh,&buff);
loop_level = saveloop; loop_level = saveloop;
label_last = savelabel; label_last = savelabel;
/* restore the old stack */ /* restore the old stack */
if(slp) if(slp)
{ {
slp->slptr = stakinstall(savstak,0); slp->slptr = stakinstall(savstak,0);
slp->slchild = shp->st.staklist; slp->slchild = sh.st.staklist;
} }
#if SHOPT_KIA #if SHOPT_KIA
lexp->current = current; lexp->current = current;
@ -944,25 +943,25 @@ static Shnode_t *funct(Lex_t *lexp)
{ {
if(slp && slp->slptr) if(slp && slp->slptr)
{ {
shp->st.staklist = slp->slnext; sh.st.staklist = slp->slnext;
stakdelete(slp->slptr); stakdelete(slp->slptr);
} }
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
} }
shp->st.staklist = (struct slnod*)slp; sh.st.staklist = (struct slnod*)slp;
last = fctell(); last = fctell();
fp->functline = (last-first); fp->functline = (last-first);
fp->functtre = t; fp->functtre = t;
shp->mktype = in_mktype; sh.mktype = in_mktype;
if(lexp->sh->funlog) if(sh.funlog)
{ {
if(fcfill()>0) if(fcfill()>0)
fcseek(-1); fcseek(-1);
lexp->sh->funlog = 0; sh.funlog = 0;
} }
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile) if(lexp->kiafile)
kiaentity(lexp,t->funct.functnam,-1,'p',t->funct.functline,shp->inlineno-1,lexp->current,'p',0,""); kiaentity(lexp,t->funct.functnam,-1,'p',t->funct.functline,sh.inlineno-1,lexp->current,'p',0,"");
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
t->funct.functtyp |= opt_get; t->funct.functtyp |= opt_get;
opt_get = save_optget; opt_get = save_optget;
@ -977,7 +976,7 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
register int n; register int n;
register Shnode_t *t, **tp; register Shnode_t *t, **tp;
register struct comnod *ac; register struct comnod *ac;
Stk_t *stkp = lexp->sh->stk; Stk_t *stkp = sh.stk;
int array=0, index=0; int array=0, index=0;
Namval_t *np; Namval_t *np;
n = strlen(ap->argval)-1; n = strlen(ap->argval)-1;
@ -1059,7 +1058,7 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
else if(type!=NV_ARRAY && else if(type!=NV_ARRAY &&
n!=FUNCTSYM && n!=FUNCTSYM &&
!(lexp->arg->argflag&ARG_ASSIGN) && !(lexp->arg->argflag&ARG_ASSIGN) &&
!((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && !((np=nv_search(lexp->arg->argval,sh.fun_tree,0)) &&
(nv_isattr(np,BLT_DCL) || np==SYSDOT || np==SYSSOURCE))) (nv_isattr(np,BLT_DCL) || np==SYSDOT || np==SYSSOURCE)))
{ {
array=SH_ARRAY; array=SH_ARRAY;
@ -1088,10 +1087,10 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
n = lexp->token; n = lexp->token;
dcl_recursion = 1; dcl_recursion = 1;
dcl_dehacktivate(); dcl_dehacktivate();
p = path_search(lexp->sh,lexp->arg->argval,NIL(Pathcomp_t**),1); p = path_search(lexp->arg->argval,NIL(Pathcomp_t**),1);
dcl_hacktivate(); dcl_hacktivate();
dcl_recursion = save_recursion; dcl_recursion = save_recursion;
if(p && (np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && nv_isattr(np,BLT_DCL)) if(p && (np=nv_search(lexp->arg->argval,sh.fun_tree,0)) && nv_isattr(np,BLT_DCL))
{ {
lexp->token = n; lexp->token = n;
lexp->arg = arg; lexp->arg = arg;
@ -1128,7 +1127,7 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
} }
if((n!=FUNCTSYM) && if((n!=FUNCTSYM) &&
!(lexp->arg->argflag&ARG_ASSIGN) && !(lexp->arg->argflag&ARG_ASSIGN) &&
!((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && !((np=nv_search(lexp->arg->argval,sh.fun_tree,0)) &&
(nv_isattr(np,BLT_DCL) || np==SYSDOT || np==SYSSOURCE))) (nv_isattr(np,BLT_DCL) || np==SYSDOT || np==SYSSOURCE)))
{ {
struct argnod *arg = lexp->arg; struct argnod *arg = lexp->arg;
@ -1206,7 +1205,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
t->sw.swtyp=TSW; t->sw.swtyp=TSW;
t->sw.swio = 0; t->sw.swio = 0;
t->sw.swtyp |= FLINENO; t->sw.swtyp |= FLINENO;
t->sw.swline = lexp->sh->inlineno; t->sw.swline = sh.inlineno;
if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE) if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE)
sh_syntax(lexp); sh_syntax(lexp);
if(!(t->sw.swlst=syncase(lexp,tok==INSYM?ESACSYM:RBRACE)) && lexp->token==EOFSYM) if(!(t->sw.swlst=syncase(lexp,tok==INSYM?ESACSYM:RBRACE)) && lexp->token==EOFSYM)
@ -1248,7 +1247,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
t = getnode(fornod); t = getnode(fornod);
t->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT); t->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT);
t->for_.forlst=0; t->for_.forlst=0;
t->for_.forline = lexp->sh->inlineno; t->for_.forline = sh.inlineno;
if(sh_lex(lexp)) if(sh_lex(lexp))
{ {
if(lexp->token!=EXPRSYM || t->for_.fortyp!=TFOR) if(lexp->token!=EXPRSYM || t->for_.fortyp!=TFOR)
@ -1261,7 +1260,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
t->for_.fortyp |= FLINENO; t->for_.fortyp |= FLINENO;
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile) if(lexp->kiafile)
writedefs(lexp,lexp->arg,lexp->sh->inlineno,'v',NIL(struct argnod*)); writedefs(lexp,lexp->arg,sh.inlineno,'v',NIL(struct argnod*));
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
while((tok=sh_lex(lexp))==NL); while((tok=sh_lex(lexp))==NL);
if(tok==INSYM) if(tok==INSYM)
@ -1272,7 +1271,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
sh_syntax(lexp); sh_syntax(lexp);
/* some Linux scripts assume this */ /* some Linux scripts assume this */
if(sh_isoption(SH_NOEXEC)) if(sh_isoption(SH_NOEXEC))
errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,lexp->sh->inlineno-(lexp->token=='\n')); errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,sh.inlineno-(lexp->token=='\n'));
t->for_.forlst = (struct comnod*)getnode(comnod); t->for_.forlst = (struct comnod*)getnode(comnod);
(t->for_.forlst)->comarg = 0; (t->for_.forlst)->comarg = 0;
(t->for_.forlst)->comset = 0; (t->for_.forlst)->comset = 0;
@ -1340,7 +1339,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
{ {
if(strcmp(argp->argval,lexp->arg->argval)==0) if(strcmp(argp->argval,lexp->arg->argval)==0)
{ {
errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,lexp->sh->inlineno,argp->argval); errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,sh.inlineno,argp->argval);
UNREACHABLE(); UNREACHABLE();
} }
argp = argp->argnxt.ap; argp = argp->argnxt.ap;
@ -1415,7 +1414,7 @@ static struct argnod *process_sub(Lex_t *lexp,int tok)
Shnode_t *t; Shnode_t *t;
int mode = (tok==OPROCSYM); int mode = (tok==OPROCSYM);
t = sh_cmd(lexp,RPAREN,SH_NL); t = sh_cmd(lexp,RPAREN,SH_NL);
argp = (struct argnod*)stkalloc(lexp->sh->stk,sizeof(struct argnod)); argp = (struct argnod*)stkalloc(sh.stk,sizeof(struct argnod));
*argp->argval = 0; *argp->argval = 0;
argp->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t); argp->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t);
argp->argflag = (ARG_EXP|mode); argp->argflag = (ARG_EXP|mode);
@ -1431,7 +1430,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
register struct comnod *t; register struct comnod *t;
register struct argnod *argp; register struct argnod *argp;
register int tok; register int tok;
Stk_t *stkp = lexp->sh->stk; Stk_t *stkp = sh.stk;
struct argnod **argtail; struct argnod **argtail;
struct argnod **settail; struct argnod **settail;
int cmdarg=0; int cmdarg=0;
@ -1501,7 +1500,7 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
&& !(sh_isoption(SH_RESTRICTED) && strchr(argp->argval,'/'))) && !(sh_isoption(SH_RESTRICTED) && strchr(argp->argval,'/')))
{ {
/* check for builtin command (including path-bound builtins executed by full pathname) */ /* check for builtin command (including path-bound builtins executed by full pathname) */
Namval_t *np=nv_bfsearch(argp->argval,lexp->sh->fun_tree, (Namval_t**)&t->comnamq,(char**)0); Namval_t *np=nv_bfsearch(argp->argval,sh.fun_tree, (Namval_t**)&t->comnamq,(char**)0);
if(np && is_abuiltin(np)) if(np && is_abuiltin(np))
{ {
if(cmdarg==0) if(cmdarg==0)
@ -1667,11 +1666,11 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
break; break;
} }
if(sh_isoption(SH_NOEXEC) && tok==0) if(sh_isoption(SH_NOEXEC) && tok==0)
errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,lexp->sh->inlineno-(lexp->token=='\n'),cp); errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,sh.inlineno-(lexp->token=='\n'),cp);
} }
else if(sh_isoption(SH_NOEXEC) && np==SYSSET && ((tok= *argp->argval)=='-'||tok=='+') && else if(sh_isoption(SH_NOEXEC) && np==SYSSET && ((tok= *argp->argval)=='-'||tok=='+') &&
(argp->argval[1]==0||strchr(argp->argval,'k'))) (argp->argval[1]==0||strchr(argp->argval,'k')))
errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,lexp->sh->inlineno-(lexp->token=='\n'),argp->argval); errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,sh.inlineno-(lexp->token=='\n'),argp->argval);
} }
/* expand argument list if possible */ /* expand argument list if possible */
if(argno>0 && !(flag&(SH_ARRAY|NV_APPEND))) if(argno>0 && !(flag&(SH_ARRAY|NV_APPEND)))
@ -1703,7 +1702,7 @@ static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
{ {
register int iof = lexp->digits, token=lexp->token; register int iof = lexp->digits, token=lexp->token;
register struct ionod *iop; register struct ionod *iop;
Stk_t *stkp = lexp->sh->stk; Stk_t *stkp = sh.stk;
char *iovname=0; char *iovname=0;
register int errout=0; register int errout=0;
if(token==IOVNAME) if(token==IOVNAME)
@ -1794,8 +1793,8 @@ static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
} }
else else
{ {
if(!lexp->sh->heredocs) if(!sh.heredocs)
lexp->sh->heredocs = sftmp(HERE_MEM); sh.heredocs = sftmp(HERE_MEM);
iop->iolst=lexp->heredoc; iop->iolst=lexp->heredoc;
lexp->heredoc=iop; lexp->heredoc=iop;
if(lexp->arg->argflag&ARG_QUOTED) if(lexp->arg->argflag&ARG_QUOTED)
@ -1819,7 +1818,7 @@ static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile) if(lexp->kiafile)
{ {
int n = lexp->sh->inlineno-(lexp->token=='\n'); int n = sh.inlineno-(lexp->token=='\n');
if(!(iof&IOMOV)) if(!(iof&IOMOV))
{ {
unsigned long r=kiaentity(lexp,(iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,lexp->script,'f',0,""); unsigned long r=kiaentity(lexp,(iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,lexp->script,'f',0,"");
@ -1970,7 +1969,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
{ {
case '(': case '(':
t = test_expr(lexp,')'); t = test_expr(lexp,')');
t = makelist(lexp,TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(lexp->sh->inlineno)); t = makelist(lexp,TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(sh.inlineno));
break; break;
case '!': case '!':
if(!(t = test_primary(lexp))) if(!(t = test_primary(lexp)))
@ -1983,7 +1982,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile && !strchr("sntzoOG",num)) if(lexp->kiafile && !strchr("sntzoOG",num))
{ {
int line = lexp->sh->inlineno- (lexp->token==NL); int line = sh.inlineno- (lexp->token==NL);
unsigned long r; unsigned long r;
r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->script,'t',0,""); r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->script,'t',0,"");
sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
@ -1991,7 +1990,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
#endif /* SHOPT_KIA */ #endif /* SHOPT_KIA */
t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT), t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT),
(Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg); (Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg);
t->tst.tstline = lexp->sh->inlineno; t->tst.tstline = sh.inlineno;
break; break;
/* binary test operators */ /* binary test operators */
case 0: case 0:
@ -2013,7 +2012,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
{ {
t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT), t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT),
(Shnode_t*)arg,(Shnode_t*)arg); (Shnode_t*)arg,(Shnode_t*)arg);
t->tst.tstline = lexp->sh->inlineno; t->tst.tstline = sh.inlineno;
return(t); return(t);
} }
else else
@ -2021,7 +2020,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT)) if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
{ {
int line = lexp->sh->inlineno- (lexp->token==NL); int line = sh.inlineno- (lexp->token==NL);
unsigned long r; unsigned long r;
r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,""); r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
@ -2039,11 +2038,11 @@ static Shnode_t *test_primary(Lex_t *lexp)
t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT); t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT);
t->lst.lstlef = (Shnode_t*)arg; t->lst.lstlef = (Shnode_t*)arg;
t->lst.lstrit = (Shnode_t*)lexp->arg; t->lst.lstrit = (Shnode_t*)lexp->arg;
t->tst.tstline = lexp->sh->inlineno; t->tst.tstline = sh.inlineno;
#if SHOPT_KIA #if SHOPT_KIA
if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT)) if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
{ {
int line = lexp->sh->inlineno-(lexp->token==NL); int line = sh.inlineno-(lexp->token==NL);
unsigned long r; unsigned long r;
r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,""); r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line); sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
@ -2073,7 +2072,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
*/ */
unsigned long kiaentity(Lex_t *lexp,const char *name,int len,int type,int first,int last,unsigned long parent, int pkind, int width, const char *attr) unsigned long kiaentity(Lex_t *lexp,const char *name,int len,int type,int first,int last,unsigned long parent, int pkind, int width, const char *attr)
{ {
Stk_t *stkp = lexp->sh->stk; Stk_t *stkp = sh.stk;
Namval_t *np; Namval_t *np;
long offset = stktell(stkp); long offset = stktell(stkp);
sfputc(stkp,type); sfputc(stkp,type);
@ -2119,9 +2118,9 @@ int kiaclose(Lex_t *lexp)
register int n; register int n;
if(lexp->kiafile) if(lexp->kiafile)
{ {
unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,lexp->sh->inlineno-1,0,'s',0,""); unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,sh.inlineno-1,0,'s',0,"");
kiaentity(lexp,lexp->scriptname,-1,'p',1,lexp->sh->inlineno-1,r,'s',0,""); kiaentity(lexp,lexp->scriptname,-1,'p',1,sh.inlineno-1,r,'s',0,"");
kiaentity(lexp,lexp->scriptname,-1,'f',1,lexp->sh->inlineno-1,r,'s',0,""); kiaentity(lexp,lexp->scriptname,-1,'f',1,sh.inlineno-1,r,'s',0,"");
nv_scan(lexp->entity_tree,kia_add,(void*)lexp,NV_TAGGED,0); nv_scan(lexp->entity_tree,kia_add,(void*)lexp,NV_TAGGED,0);
off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END); off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
sfseek(lexp->kiatmp,(off_t)0,SEEK_SET); sfseek(lexp->kiatmp,(off_t)0,SEEK_SET);

File diff suppressed because it is too large Load diff

View file

@ -82,7 +82,6 @@ static const char header[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,SHCOMP_HDR_VERSI
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
Sfio_t *in, *out; Sfio_t *in, *out;
Shell_t *shp;
Namval_t *np; Namval_t *np;
Shnode_t *t; Shnode_t *t;
char *cp, *shcomp_id, *script_id; char *cp, *shcomp_id, *script_id;
@ -106,10 +105,10 @@ int main(int argc, char *argv[])
errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg); errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
UNREACHABLE(); UNREACHABLE();
} }
shp = sh_init(argc,argv,(Shinit_f)0); sh_init(argc,argv,(Shinit_f)0);
script_id = error_info.id; /* set by sh_init() */ script_id = error_info.id; /* set by sh_init() */
error_info.id = shcomp_id; error_info.id = shcomp_id;
shp->shcomp = 1; sh.shcomp = 1;
argv += opt_info.index; argv += opt_info.index;
argc -= opt_info.index; argc -= opt_info.index;
if(argc==0 && tty_check(0)) if(argc==0 && tty_check(0))
@ -162,7 +161,7 @@ int main(int argc, char *argv[])
if(!dflag) if(!dflag)
sfwrite(out,header,sizeof(header)); /* write binary shcomp header */ sfwrite(out,header,sizeof(header)); /* write binary shcomp header */
sh_offoption(SH_MULTILINE); sh_offoption(SH_MULTILINE);
shp->inlineno = 1; sh.inlineno = 1;
#if SHOPT_BRACEPAT #if SHOPT_BRACEPAT
sh_onoption(SH_BRACEEXPAND); sh_onoption(SH_BRACEEXPAND);
#endif #endif
@ -170,7 +169,7 @@ int main(int argc, char *argv[])
while(1) while(1)
{ {
stakset((char*)0,0); stakset((char*)0,0);
if(t = (Shnode_t*)sh_parse(shp,in,0)) if(t = (Shnode_t*)sh_parse(in,0))
{ {
if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0) if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
/* Create aliases found in the script to prevent syntax errors */ /* Create aliases found in the script to prevent syntax errors */

View file

@ -63,7 +63,6 @@
struct vars /* vars stacked per invocation */ struct vars /* vars stacked per invocation */
{ {
Shell_t *shp;
const char *expr; /* current expression */ const char *expr; /* current expression */
const char *nextchr; /* next char in current expression */ const char *nextchr; /* next char in current expression */
const char *errchr; /* next char after error */ const char *errchr; /* next char after error */
@ -160,8 +159,6 @@ Sfdouble_t arith_exec(Arith_t *ep)
int lastsub; int lastsub;
Math_f fun; Math_f fun;
struct lval node; struct lval node;
Shell_t *shp = ep->shp;
node.shp = shp;
node.emode = ep->emode; node.emode = ep->emode;
node.expr = ep->expr; node.expr = ep->expr;
node.elen = ep->elen; node.elen = ep->elen;
@ -170,7 +167,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
node.sub = 0; node.sub = 0;
node.ptr = 0; node.ptr = 0;
node.eflag = 0; node.eflag = 0;
if(shp->arithrecursion++ >= MAXLEVEL) if(sh.arithrecursion++ >= MAXLEVEL)
{ {
arith_error(e_recursive,ep->expr,ep->emode); arith_error(e_recursive,ep->expr,ep->emode);
return(0); return(0);
@ -242,7 +239,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
if(node.flag = c) if(node.flag = c)
lastval = 0; lastval = 0;
node.isfloat=0; node.isfloat=0;
node.level = shp->arithrecursion; node.level = sh.arithrecursion;
node.nosub = 0; node.nosub = 0;
num = (*ep->fun)(&ptr,&node,VALUE,num); num = (*ep->fun)(&ptr,&node,VALUE,num);
if(node.emode&ARITH_ASSIGNOP) if(node.emode&ARITH_ASSIGNOP)
@ -427,7 +424,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
c &= ~T_BINARY; c &= ~T_BINARY;
arg[0] = num; arg[0] = num;
arg[1] = 0; arg[1] = 0;
num = sh_mathfun(shp,(void*)fun,1,arg); num = sh_mathfun((void*)fun,1,arg);
break; break;
} }
num = (*((Math_1f_f)fun))(num); num = (*((Math_1f_f)fun))(num);
@ -448,7 +445,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
arg[0] = sp[1]; arg[0] = sp[1];
arg[1] = num; arg[1] = num;
arg[2] = 0; arg[2] = 0;
num = sh_mathfun(shp,(void*)fun,2,arg); num = sh_mathfun((void*)fun,2,arg);
break; break;
} }
if(c&T_NOFLOAT) if(c&T_NOFLOAT)
@ -473,7 +470,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
arg[1] = sp[2]; arg[1] = sp[2];
arg[2] = num; arg[2] = num;
arg[3] = 0; arg[3] = 0;
num = sh_mathfun(shp,(void*)fun,3,arg); num = sh_mathfun((void*)fun,3,arg);
break; break;
} }
num = (*((Math_3f_f)fun))(sp[1],sp[2],num); num = (*((Math_3f_f)fun))(sp[1],sp[2],num);
@ -490,8 +487,8 @@ Sfdouble_t arith_exec(Arith_t *ep)
*sp = num; *sp = num;
*tp = type; *tp = type;
} }
if(shp->arithrecursion>0) if(sh.arithrecursion>0)
shp->arithrecursion--; sh.arithrecursion--;
if(type==0 && !num) if(type==0 && !num)
num = 0; num = 0;
return(num); return(num);
@ -516,7 +513,7 @@ static int gettok(register struct vars *vp)
vp->nextchr--; vp->nextchr--;
break; break;
case A_COMMA: case A_COMMA:
if(vp->shp->decomma && (c=peekchr(vp))>='0' && c<='9') if(sh.decomma && (c=peekchr(vp))>='0' && c<='9')
{ {
op = A_DIG; op = A_DIG;
goto keep; goto keep;
@ -579,7 +576,6 @@ static int expr(register struct vars *vp,register int precedence)
lvalue.value = 0; lvalue.value = 0;
lvalue.nargs = 0; lvalue.nargs = 0;
lvalue.fun = 0; lvalue.fun = 0;
lvalue.shp = vp->shp;
again: again:
op = gettok(vp); op = gettok(vp);
c = 2*MAXPREC+1; c = 2*MAXPREC+1;
@ -897,13 +893,12 @@ again:
return(1); return(1);
} }
Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*fun)(const char**,struct lval*,int,Sfdouble_t),int emode) Arith_t *arith_compile(const char *string,char **last,Sfdouble_t(*fun)(const char**,struct lval*,int,Sfdouble_t),int emode)
{ {
struct vars cur; struct vars cur;
register Arith_t *ep; register Arith_t *ep;
int offset; int offset;
memset((void*)&cur,0,sizeof(cur)); memset((void*)&cur,0,sizeof(cur));
cur.shp = shp;
cur.expr = cur.nextchr = string; cur.expr = cur.nextchr = string;
cur.convert = fun; cur.convert = fun;
cur.emode = emode; cur.emode = emode;
@ -925,7 +920,6 @@ Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*f
stakputc(0); stakputc(0);
offset = staktell(); offset = staktell();
ep = (Arith_t*)stakfreeze(0); ep = (Arith_t*)stakfreeze(0);
ep->shp = shp;
ep->expr = string; ep->expr = string;
ep->elen = strlen(string); ep->elen = strlen(string);
ep->code = (unsigned char*)(ep+1); ep->code = (unsigned char*)(ep+1);
@ -948,10 +942,10 @@ Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*f
* point to the next non-converted character; if typ is MESSAGE then string * point to the next non-converted character; if typ is MESSAGE then string
* points to an error message string * points to an error message string
* *
* NOTE: (*convert)() may call strval() * NOTE: (*convert)() may call arith_strval()
*/ */
Sfdouble_t strval(Shell_t *shp,const char *s,char **end,Sfdouble_t(*conv)(const char**,struct lval*,int,Sfdouble_t),int emode) Sfdouble_t arith_strval(const char *s, char **end, Sfdouble_t(*convert)(const char**,struct lval*,int,Sfdouble_t), int emode)
{ {
Arith_t *ep; Arith_t *ep;
Sfdouble_t d; Sfdouble_t d;
@ -959,7 +953,7 @@ Sfdouble_t strval(Shell_t *shp,const char *s,char **end,Sfdouble_t(*conv)(const
int offset; int offset;
if(offset=staktell()) if(offset=staktell())
sp = stakfreeze(1); sp = stakfreeze(1);
ep = arith_compile(shp,s,end,conv,emode); ep = arith_compile(s,end,convert,emode);
ep->emode = emode; ep->emode = emode;
d = arith_exec(ep); d = arith_exec(ep);
stakset(sp?sp:(char*)ep,offset); stakset(sp?sp:(char*)ep,offset);

View file

@ -40,11 +40,6 @@
# define iswprint(c) (((c)&~0377) || isprint(c)) # define iswprint(c) (((c)&~0377) || isprint(c))
#endif #endif
#ifndef isxdigit
# define isxdigit(c) ((c)>='0'&&(c)<='9'||(c)>='a'&&(c)<='f'||(c)>='A'&&(c)<='F')
#endif
/* /*
* Table lookup routine * Table lookup routine
* <table> is searched for string <sp> and corresponding value is returned * <table> is searched for string <sp> and corresponding value is returned

View file

@ -69,7 +69,6 @@ struct Link
*/ */
static struct subshell static struct subshell
{ {
Shell_t *shp; /* shell interpreter */
struct subshell *prev; /* previous subshell data */ struct subshell *prev; /* previous subshell data */
struct subshell *pipe; /* subshell where output goes to pipe on fork */ struct subshell *pipe; /* subshell where output goes to pipe on fork */
struct Link *svar; /* save shell variable table */ struct Link *svar; /* save shell variable table */
@ -114,18 +113,18 @@ static unsigned int subenv;
/* /*
* This routine will turn the sftmp() file into a real temporary file * This routine will turn the sftmp() file into a real temporary file
*/ */
void sh_subtmpfile(Shell_t *shp) void sh_subtmpfile(void)
{ {
if(sfset(sfstdout,0,0)&SF_STRING) if(sfset(sfstdout,0,0)&SF_STRING)
{ {
register int fd; register int fd;
register struct checkpt *pp = (struct checkpt*)shp->jmplist; register struct checkpt *pp = (struct checkpt*)sh.jmplist;
register struct subshell *sp = subshell_data->pipe; register struct subshell *sp = subshell_data->pipe;
/* save file descriptor 1 if open */ /* save file descriptor 1 if open */
if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0) if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0)
{ {
fcntl(fd,F_SETFD,FD_CLOEXEC); fcntl(fd,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX; sh.fdstatus[fd] = sh.fdstatus[1]|IOCLEX;
close(1); close(1);
} }
else if(errno!=EBADF) else if(errno!=EBADF)
@ -140,19 +139,19 @@ void sh_subtmpfile(Shell_t *shp)
errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,"could not create temp file"); errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,"could not create temp file");
UNREACHABLE(); UNREACHABLE();
} }
shp->fdstatus[fd] = IOREAD|IOWRITE; sh.fdstatus[fd] = IOREAD|IOWRITE;
sfsync(sfstdout); sfsync(sfstdout);
if(fd==1) if(fd==1)
fcntl(1,F_SETFD,0); fcntl(1,F_SETFD,0);
else else
{ {
sfsetfd(sfstdout,1); sfsetfd(sfstdout,1);
shp->fdstatus[1] = shp->fdstatus[fd]; sh.fdstatus[1] = sh.fdstatus[fd];
shp->fdstatus[fd] = IOCLOSE; sh.fdstatus[fd] = IOCLOSE;
} }
sh_iostream(shp,1); sh_iostream(1);
sfset(sfstdout,SF_SHARE|SF_PUBLIC,1); sfset(sfstdout,SF_SHARE|SF_PUBLIC,1);
sfpool(sfstdout,shp->outpool,SF_WRITE); sfpool(sfstdout,sh.outpool,SF_WRITE);
if(pp && pp->olist && pp->olist->strm == sfstdout) if(pp && pp->olist && pp->olist->strm == sfstdout)
pp->olist->strm = 0; pp->olist->strm = 0;
} }
@ -167,27 +166,26 @@ void sh_subtmpfile(Shell_t *shp)
void sh_subfork(void) void sh_subfork(void)
{ {
register struct subshell *sp = subshell_data; register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp; unsigned int curenv = sh.curenv;
unsigned int curenv = shp->curenv; char comsub = sh.comsub;
char comsub = shp->comsub;
pid_t pid; pid_t pid;
char *trap = shp->st.trapcom[0]; char *trap = sh.st.trapcom[0];
if(trap) if(trap)
trap = sh_strdup(trap); trap = sh_strdup(trap);
/* see whether inside $(...) */ /* see whether inside $(...) */
if(sp->pipe) if(sp->pipe)
sh_subtmpfile(shp); sh_subtmpfile();
shp->curenv = 0; sh.curenv = 0;
shp->savesig = -1; sh.savesig = -1;
if(pid = sh_fork(shp,FSHOWME,NIL(int*))) if(pid = sh_fork(FSHOWME,NIL(int*)))
{ {
shp->curenv = curenv; sh.curenv = curenv;
/* this is the parent part of the fork */ /* this is the parent part of the fork */
if(sp->subpid==0) if(sp->subpid==0)
sp->subpid = pid; sp->subpid = pid;
if(trap) if(trap)
free((void*)trap); free((void*)trap);
siglongjmp(*shp->jmplist,SH_JMPSUB); siglongjmp(*sh.jmplist,SH_JMPSUB);
} }
else else
{ {
@ -205,13 +203,13 @@ void sh_subfork(void)
rp->rand_last = -2; rp->rand_last = -2;
} }
subshell_data = 0; subshell_data = 0;
shp->subshell = 0; sh.subshell = 0;
shp->comsub = 0; sh.comsub = 0;
sp->subpid=0; sp->subpid=0;
shp->st.trapcom[0] = (comsub==2 ? NIL(char*) : trap); sh.st.trapcom[0] = (comsub==2 ? NIL(char*) : trap);
shp->savesig = 0; sh.savesig = 0;
/* sh_fork() increases ${.sh.subshell} but we forked an existing virtual subshell, so undo */ /* sh_fork() increases ${.sh.subshell} but we forked an existing virtual subshell, so undo */
shgd->realsubshell--; sh.realsubshell--;
} }
} }
@ -275,8 +273,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
register Namval_t *mp; register Namval_t *mp;
register struct Link *lp; register struct Link *lp;
struct subshell *sp = subshell_data; struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp; Dt_t *dp= sh.var_tree;
Dt_t *dp= shp->var_tree;
Namval_t *mpnext; Namval_t *mpnext;
Namarr_t *ap; Namarr_t *ap;
unsigned int save; unsigned int save;
@ -288,7 +285,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
return(np); return(np);
if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np))) if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
{ {
shp->last_root = ap->table; sh.last_root = ap->table;
sh_assignok(mp,add); sh_assignok(mp,add);
if(!add || array_assoc(ap)) if(!add || array_assoc(ap))
return(np); return(np);
@ -305,7 +302,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
if(!add && nv_isvtree(np)) if(!add && nv_isvtree(np))
{ {
Namval_t fake; Namval_t fake;
Dt_t *walk, *root=shp->var_tree; Dt_t *walk, *root=sh.var_tree;
char *name = nv_name(np); char *name = nv_name(np);
size_t len = strlen(name); size_t len = strlen(name);
fake.nvname = name; fake.nvname = name;
@ -327,13 +324,13 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
mp = (Namval_t*)&lp->dict; mp = (Namval_t*)&lp->dict;
lp->next = subshell_data->svar; lp->next = subshell_data->svar;
subshell_data->svar = lp; subshell_data->svar = lp;
save = shp->subshell; save = sh.subshell;
shp->subshell = 0; sh.subshell = 0;
mp->nvname = np->nvname; mp->nvname = np->nvname;
if(nv_isattr(np,NV_NOFREE)) if(nv_isattr(np,NV_NOFREE))
nv_onattr(mp,NV_IDENT); nv_onattr(mp,NV_IDENT);
nv_clone(np,mp,(add?(nv_isnull(np)?0:NV_NOFREE)|NV_ARRAY:NV_MOVE)); nv_clone(np,mp,(add?(nv_isnull(np)?0:NV_NOFREE)|NV_ARRAY:NV_MOVE));
shp->subshell = save; sh.subshell = save;
return(np); return(np);
} }
@ -388,12 +385,12 @@ static void nv_restore(struct subshell *sp)
if(nv_isattr(mp,NV_EXPORT)) if(nv_isattr(mp,NV_EXPORT))
{ {
char *name = nv_name(mp); char *name = nv_name(mp);
sh_envput(sp->shp->env,mp); sh_envput(sh.env,mp);
if(*name=='_' && strcmp(name,"_AST_FEATURES")==0) if(*name=='_' && strcmp(name,"_AST_FEATURES")==0)
astconf(NiL, NiL, NiL); astconf(NiL, NiL, NiL);
} }
else if(nv_isattr(np,NV_EXPORT)) else if(nv_isattr(np,NV_EXPORT))
env_delete(sp->shp->env,nv_name(mp)); env_delete(sh.env,nv_name(mp));
nv_onattr(mp,flags); nv_onattr(mp,flags);
skip: skip:
for(mp=lp->child; mp; mp=mpnext) for(mp=lp->child; mp; mp=mpnext)
@ -482,12 +479,12 @@ void sh_subjobcheck(pid_t pid)
* output of command <t>. Otherwise, NULL will be returned. * output of command <t>. Otherwise, NULL will be returned.
*/ */
Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) Sfio_t *sh_subshell(Shnode_t *t, volatile int flags, int comsub)
{ {
struct subshell sub_data; struct subshell sub_data;
register struct subshell *sp = &sub_data; register struct subshell *sp = &sub_data;
int jmpval,isig,nsig=0,fatalerror=0,saveerrno=0; int jmpval,isig,nsig=0,fatalerror=0,saveerrno=0;
unsigned int savecurenv = shp->curenv; unsigned int savecurenv = sh.curenv;
int savejobpgid = job.curpgid; int savejobpgid = job.curpgid;
int *saveexitval = job.exitval; int *saveexitval = job.exitval;
char **savsig; char **savsig;
@ -497,58 +494,57 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
struct dolnod *argsav=0; struct dolnod *argsav=0;
int argcnt; int argcnt;
memset((char*)sp, 0, sizeof(*sp)); memset((char*)sp, 0, sizeof(*sp));
sfsync(shp->outpool); sfsync(sh.outpool);
sh_sigcheck(shp); sh_sigcheck();
shp->savesig = -1; sh.savesig = -1;
if(argsav = sh_arguse(shp)) if(argsav = sh_arguse())
argcnt = argsav->dolrefcnt; argcnt = argsav->dolrefcnt;
if(shp->curenv==0) if(sh.curenv==0)
{ {
subshell_data=0; subshell_data=0;
subenv = 0; subenv = 0;
} }
shp->curenv = ++subenv; sh.curenv = ++subenv;
savst = shp->st; savst = sh.st;
sh_pushcontext(&sh,&checkpoint,SH_JMPSUB); sh_pushcontext(&sh,&checkpoint,SH_JMPSUB);
shp->subshell++; /* increase level of virtual subshells */ sh.subshell++; /* increase level of virtual subshells */
shgd->realsubshell++; /* increase ${.sh.subshell} */ sh.realsubshell++; /* increase ${.sh.subshell} */
sp->prev = subshell_data; sp->prev = subshell_data;
sp->shp = shp;
sp->sig = 0; sp->sig = 0;
subshell_data = sp; subshell_data = sp;
sp->options = shp->options; sp->options = sh.options;
sp->jobs = job_subsave(); sp->jobs = job_subsave();
sp->subdup = shp->subdup; sp->subdup = sh.subdup;
shp->subdup = 0; sh.subdup = 0;
/* make sure initialization has occurred */ /* make sure initialization has occurred */
if(!shp->pathlist) if(!sh.pathlist)
{ {
shp->pathinit = 1; sh.pathinit = 1;
path_get(shp,e_dot); path_get(e_dot);
shp->pathinit = 0; sh.pathinit = 0;
} }
if(!shp->pwd) if(!sh.pwd)
path_pwd(shp,0); path_pwd();
sp->bckpid = shp->bckpid; sp->bckpid = sh.bckpid;
if(comsub) if(comsub)
sh_stats(STAT_COMSUB); sh_stats(STAT_COMSUB);
else else
job.curpgid = 0; job.curpgid = 0;
sp->subshare = shp->subshare; sp->subshare = sh.subshare;
sp->comsub = shp->comsub; sp->comsub = sh.comsub;
shp->subshare = comsub==2; sh.subshare = comsub==2;
if(!shp->subshare) if(!sh.subshare)
sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); sp->pathlist = path_dup((Pathcomp_t*)sh.pathlist);
if(comsub) if(comsub)
shp->comsub = comsub; sh.comsub = comsub;
if(!shp->subshare) if(!sh.subshare)
{ {
struct subshell *xp; struct subshell *xp;
#if _lib_fchdir #if _lib_fchdir
sp->pwdfd = -1; sp->pwdfd = -1;
for(xp=sp->prev; xp; xp=xp->prev) for(xp=sp->prev; xp; xp=xp->prev)
{ {
if(xp->pwdfd>0 && xp->pwd && strcmp(xp->pwd,shp->pwd)==0) if(xp->pwdfd>0 && xp->pwd && strcmp(xp->pwd,sh.pwd)==0)
{ {
sp->pwdfd = xp->pwdfd; sp->pwdfd = xp->pwdfd;
break; break;
@ -573,36 +569,36 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
} }
} }
#endif /* _lib_fchdir */ #endif /* _lib_fchdir */
sp->pwd = (shp->pwd?sh_strdup(shp->pwd):0); sp->pwd = (sh.pwd?sh_strdup(sh.pwd):0);
sp->mask = shp->mask; sp->mask = sh.mask;
sh_stats(STAT_SUBSHELL); sh_stats(STAT_SUBSHELL);
/* save trap table */ /* save trap table */
shp->st.otrapcom = 0; sh.st.otrapcom = 0;
shp->st.otrap = savst.trap; sh.st.otrap = savst.trap;
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0]) if((nsig=sh.st.trapmax)>0 || sh.st.trapcom[0])
{ {
savsig = sh_malloc(nsig * sizeof(char*)); savsig = sh_malloc(nsig * sizeof(char*));
/* /*
* the data is, usually, modified in code like: * the data is, usually, modified in code like:
* tmp = buf[i]; buf[i] = sh_strdup(tmp); free(tmp); * tmp = buf[i]; buf[i] = sh_strdup(tmp); free(tmp);
* so shp->st.trapcom needs a "deep copy" to properly save/restore pointers. * so sh.st.trapcom needs a "deep copy" to properly save/restore pointers.
*/ */
for (isig = 0; isig < nsig; ++isig) for (isig = 0; isig < nsig; ++isig)
{ {
if(shp->st.trapcom[isig] == Empty) if(sh.st.trapcom[isig] == Empty)
savsig[isig] = Empty; savsig[isig] = Empty;
else if(shp->st.trapcom[isig]) else if(sh.st.trapcom[isig])
savsig[isig] = sh_strdup(shp->st.trapcom[isig]); savsig[isig] = sh_strdup(sh.st.trapcom[isig]);
else else
savsig[isig] = NIL(char*); savsig[isig] = NIL(char*);
} }
/* this is needed for var=$(trap) */ /* this is needed for var=$(trap) */
shp->st.otrapcom = (char**)savsig; sh.st.otrapcom = (char**)savsig;
} }
sp->cpid = shp->cpid; sp->cpid = sh.cpid;
sp->coutpipe = shp->coutpipe; sp->coutpipe = sh.coutpipe;
sp->cpipe = shp->cpipe[1]; sp->cpipe = sh.cpipe[1];
shp->cpid = 0; sh.cpid = 0;
sh_sigreset(0); sh_sigreset(0);
} }
jmpval = sigsetjmp(checkpoint.buff,0); jmpval = sigsetjmp(checkpoint.buff,0);
@ -611,7 +607,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
if(comsub) if(comsub)
{ {
/* disable job control */ /* disable job control */
shp->spid = 0; sh.spid = 0;
sp->jobcontrol = job.jobcontrol; sp->jobcontrol = job.jobcontrol;
sp->monitor = (sh_isstate(SH_MONITOR)!=0); sp->monitor = (sh_isstate(SH_MONITOR)!=0);
job.jobcontrol=0; job.jobcontrol=0;
@ -619,7 +615,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
sp->pipe = sp; sp->pipe = sp;
/* save sfstdout and status */ /* save sfstdout and status */
sp->saveout = sfswap(sfstdout,NIL(Sfio_t*)); sp->saveout = sfswap(sfstdout,NIL(Sfio_t*));
sp->fdstatus = shp->fdstatus[1]; sp->fdstatus = sh.fdstatus[1];
sp->tmpfd = -1; sp->tmpfd = -1;
sp->pipefd = -1; sp->pipefd = -1;
/* use sftmp() file for standard output */ /* use sftmp() file for standard output */
@ -631,7 +627,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
} }
sfswap(iop,sfstdout); sfswap(iop,sfstdout);
sfset(sfstdout,SF_READ,0); sfset(sfstdout,SF_READ,0);
shp->fdstatus[1] = IOWRITE; sh.fdstatus[1] = IOWRITE;
if(!(sp->nofork = sh_state(SH_NOFORK))) if(!(sp->nofork = sh_state(SH_NOFORK)))
sh_onstate(SH_NOFORK); sh_onstate(SH_NOFORK);
flags |= sh_state(SH_NOFORK); flags |= sh_state(SH_NOFORK);
@ -641,14 +637,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
sp->pipe = sp->prev->pipe; sp->pipe = sp->prev->pipe;
flags &= ~sh_state(SH_NOFORK); flags &= ~sh_state(SH_NOFORK);
} }
if(shp->savesig < 0) if(sh.savesig < 0)
{ {
shp->savesig = 0; sh.savesig = 0;
#if _lib_fchdir #if _lib_fchdir
if(sp->pwdfd < 0 && !shp->subshare) /* if we couldn't get a file descriptor to our PWD ... */ if(sp->pwdfd < 0 && !sh.subshare) /* if we couldn't get a file descriptor to our PWD ... */
sh_subfork(); /* ...we have to fork, as we cannot fchdir back to it. */ sh_subfork(); /* ...we have to fork, as we cannot fchdir back to it. */
#else #else
if(!shp->subshare) if(!sh.subshare)
{ {
if(sp->pwd && access(sp->pwd,X_OK)<0) if(sp->pwd && access(sp->pwd,X_OK)<0)
{ {
@ -673,11 +669,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
sh_exec(t,flags); sh_exec(t,flags);
} }
} }
if(comsub!=2 && jmpval!=SH_JMPSUB && shp->st.trapcom[0] && shp->subshell) if(comsub!=2 && jmpval!=SH_JMPSUB && sh.st.trapcom[0] && sh.subshell)
{ {
/* trap on EXIT not handled by child */ /* trap on EXIT not handled by child */
char *trap=shp->st.trapcom[0]; char *trap=sh.st.trapcom[0];
shp->st.trapcom[0] = 0; /* prevent recursion */ sh.st.trapcom[0] = 0; /* prevent recursion */
sh_trap(trap,0); sh_trap(trap,0);
free(trap); free(trap);
} }
@ -686,12 +682,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
subshell_data = sp->prev; subshell_data = sp->prev;
sh_popcontext(&sh,&checkpoint); sh_popcontext(&sh,&checkpoint);
if(jmpval==SH_JMPSCRIPT) if(jmpval==SH_JMPSCRIPT)
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
shp->exitval &= SH_EXITMASK; sh.exitval &= SH_EXITMASK;
sh_done(shp,0); sh_done(0);
} }
if(!shp->savesig) if(!sh.savesig)
shp->savesig = -1; sh.savesig = -1;
nv_restore(sp); nv_restore(sp);
if(comsub) if(comsub)
{ {
@ -708,19 +704,19 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
if(sp->pipefd>=0) if(sp->pipefd>=0)
{ {
/* sftmp() file has been returned into pipe */ /* sftmp() file has been returned into pipe */
iop = sh_iostream(shp,sp->pipefd); iop = sh_iostream(sp->pipefd);
sfclose(sfstdout); sfclose(sfstdout);
} }
else else
{ {
if(shp->spid) if(sh.spid)
{ {
int e = shp->exitval; int e = sh.exitval;
job_wait(shp->spid); job_wait(sh.spid);
shp->exitval = e; sh.exitval = e;
if(shp->pipepid==shp->spid) if(sh.pipepid==sh.spid)
shp->spid = 0; sh.spid = 0;
shp->pipepid = 0; sh.pipepid = 0;
} }
/* move tmp file to iop and restore sfstdout */ /* move tmp file to iop and restore sfstdout */
iop = sfswap(sfstdout,NIL(Sfio_t*)); iop = sfswap(sfstdout,NIL(Sfio_t*));
@ -732,20 +728,20 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
} }
if(iop && sffileno(iop)==1) if(iop && sffileno(iop)==1)
{ {
int fd = sfsetfd(iop,sh_iosafefd(shp,3)); int fd = sfsetfd(iop,sh_iosafefd(3));
if(fd<0) if(fd<0)
{ {
shp->toomany = 1; sh.toomany = 1;
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT; ((struct checkpt*)sh.jmplist)->mode = SH_JMPERREXIT;
errormsg(SH_DICT,ERROR_system(1),e_toomany); errormsg(SH_DICT,ERROR_system(1),e_toomany);
UNREACHABLE(); UNREACHABLE();
} }
if(fd >= shp->gd->lim.open_max) if(fd >= sh.lim.open_max)
sh_iovalidfd(shp,fd); sh_iovalidfd(fd);
shp->sftable[fd] = iop; sh.sftable[fd] = iop;
fcntl(fd,F_SETFD,FD_CLOEXEC); fcntl(fd,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fd] = (shp->fdstatus[1]|IOCLEX); sh.fdstatus[fd] = (sh.fdstatus[1]|IOCLEX);
shp->fdstatus[1] = IOCLOSE; sh.fdstatus[1] = IOCLOSE;
} }
sfset(iop,SF_READ,1); sfset(iop,SF_READ,1);
} }
@ -766,29 +762,29 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
} }
sh_close(sp->tmpfd); sh_close(sp->tmpfd);
} }
shp->fdstatus[1] = sp->fdstatus; sh.fdstatus[1] = sp->fdstatus;
} }
if(!shp->subshare) if(!sh.subshare)
{ {
path_delete((Pathcomp_t*)shp->pathlist); path_delete((Pathcomp_t*)sh.pathlist);
shp->pathlist = (void*)sp->pathlist; sh.pathlist = (void*)sp->pathlist;
} }
job_subrestore(sp->jobs); job_subrestore(sp->jobs);
shp->curenv = shp->jobenv = savecurenv; sh.curenv = sh.jobenv = savecurenv;
job.curpgid = savejobpgid; job.curpgid = savejobpgid;
job.exitval = saveexitval; job.exitval = saveexitval;
shp->bckpid = sp->bckpid; sh.bckpid = sp->bckpid;
if(!shp->subshare) /* restore environment if saved */ if(!sh.subshare) /* restore environment if saved */
{ {
int n; int n;
struct rand *rp; struct rand *rp;
shp->options = sp->options; sh.options = sp->options;
/* Clean up subshell hash table. */ /* Clean up subshell hash table. */
if(sp->strack) if(sp->strack)
{ {
Namval_t *np, *next_np; Namval_t *np, *next_np;
/* Detach this scope from the unified view. */ /* Detach this scope from the unified view. */
shp->track_tree = dtview(sp->strack,0); sh.track_tree = dtview(sp->strack,0);
/* Free all elements of the subshell hash table. */ /* Free all elements of the subshell hash table. */
for(np = (Namval_t*)dtfirst(sp->strack); np; np = next_np) for(np = (Namval_t*)dtfirst(sp->strack); np; np = next_np)
{ {
@ -803,7 +799,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
{ {
Namval_t *np, *next_np; Namval_t *np, *next_np;
/* Detach this scope from the unified view. */ /* Detach this scope from the unified view. */
shp->fun_tree = dtview(sp->sfun,0); sh.fun_tree = dtview(sp->sfun,0);
/* Free all elements of the subshell function table. */ /* Free all elements of the subshell function table. */
for(np = (Namval_t*)dtfirst(sp->sfun); np; np = next_np) for(np = (Namval_t*)dtfirst(sp->sfun); np; np = next_np)
{ {
@ -815,7 +811,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
continue; continue;
} }
nv_onattr(np,NV_FUNCTION); /* in case invalidated by unall() */ nv_onattr(np,NV_FUNCTION); /* in case invalidated by unall() */
if(np->nvalue.rp->fname && shp->fpathdict && nv_search(np->nvalue.rp->fname,shp->fpathdict,0)) if(np->nvalue.rp->fname && sh.fpathdict && nv_search(np->nvalue.rp->fname,sh.fpathdict,0))
{ {
/* Autoloaded function. It must not be freed. */ /* Autoloaded function. It must not be freed. */
np->nvalue.rp->fdict = 0; np->nvalue.rp->fdict = 0;
@ -829,50 +825,50 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
} }
dtclose(sp->sfun); dtclose(sp->sfun);
} }
n = shp->st.trapmax-savst.trapmax; n = sh.st.trapmax-savst.trapmax;
sh_sigreset(1); sh_sigreset(1);
if(n>0) if(n>0)
memset(&shp->st.trapcom[savst.trapmax],0,n*sizeof(char*)); memset(&sh.st.trapcom[savst.trapmax],0,n*sizeof(char*));
shp->st = savst; sh.st = savst;
shp->st.otrap = 0; sh.st.otrap = 0;
if(nsig) if(nsig)
{ {
for (isig = 0; isig < nsig; ++isig) for (isig = 0; isig < nsig; ++isig)
if (shp->st.trapcom[isig] && shp->st.trapcom[isig]!=Empty) if (sh.st.trapcom[isig] && sh.st.trapcom[isig]!=Empty)
free(shp->st.trapcom[isig]); free(sh.st.trapcom[isig]);
memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*)); memcpy((char*)&sh.st.trapcom[0],savsig,nsig*sizeof(char*));
free((void*)savsig); free((void*)savsig);
} }
shp->options = sp->options; sh.options = sp->options;
/* restore the present working directory */ /* restore the present working directory */
#if _lib_fchdir #if _lib_fchdir
if(sp->pwdfd > 0 && fchdir(sp->pwdfd) < 0) if(sp->pwdfd > 0 && fchdir(sp->pwdfd) < 0)
#else #else
if(sp->pwd && strcmp(sp->pwd,shp->pwd) && chdir(sp->pwd) < 0) if(sp->pwd && strcmp(sp->pwd,sh.pwd) && chdir(sp->pwd) < 0)
#endif /* _lib_fchdir */ #endif /* _lib_fchdir */
{ {
saveerrno = errno; saveerrno = errno;
fatalerror = 2; fatalerror = 2;
} }
else if(sp->pwd && strcmp(sp->pwd,shp->pwd)) else if(sp->pwd && strcmp(sp->pwd,sh.pwd))
path_newdir(shp,shp->pathlist); path_newdir(sh.pathlist);
if(shp->pwd) if(sh.pwd)
free((void*)shp->pwd); free((void*)sh.pwd);
shp->pwd = sp->pwd; sh.pwd = sp->pwd;
#if _lib_fchdir #if _lib_fchdir
if(sp->pwdclose) if(sp->pwdclose)
close(sp->pwdfd); close(sp->pwdfd);
#endif /* _lib_fchdir */ #endif /* _lib_fchdir */
if(sp->mask!=shp->mask) if(sp->mask!=sh.mask)
umask(shp->mask=sp->mask); umask(sh.mask=sp->mask);
if(shp->coutpipe!=sp->coutpipe) if(sh.coutpipe!=sp->coutpipe)
{ {
sh_close(shp->coutpipe); sh_close(sh.coutpipe);
sh_close(shp->cpipe[1]); sh_close(sh.cpipe[1]);
} }
shp->cpid = sp->cpid; sh.cpid = sp->cpid;
shp->cpipe[1] = sp->cpipe; sh.cpipe[1] = sp->cpipe;
shp->coutpipe = sp->coutpipe; sh.coutpipe = sp->coutpipe;
/* restore $RANDOM seed and state */ /* restore $RANDOM seed and state */
rp = (struct rand*)RANDNOD->nvfun; rp = (struct rand*)RANDNOD->nvfun;
if(sp->rand_state) if(sp->rand_state)
@ -884,65 +880,65 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
* Since virtual subshells should be indistinguishable, do the same here. */ * Since virtual subshells should be indistinguishable, do the same here. */
sh.exitval &= SH_EXITMASK; sh.exitval &= SH_EXITMASK;
} }
shp->subshare = sp->subshare; sh.subshare = sp->subshare;
shp->subdup = sp->subdup; sh.subdup = sp->subdup;
sh.subshell--; /* decrease level of virtual subshells */ sh.subshell--; /* decrease level of virtual subshells */
shgd->realsubshell--; /* decrease ${.sh.subshell} */ sh.realsubshell--; /* decrease ${.sh.subshell} */
subshell_data = sp->prev; subshell_data = sp->prev;
sh_popcontext(&sh,&checkpoint); sh_popcontext(&sh,&checkpoint);
if(!argsav || argsav->dolrefcnt==argcnt) if(!argsav || argsav->dolrefcnt==argcnt)
sh_argfree(shp,argsav,0); sh_argfree(argsav,0);
if(sh.topfd != checkpoint.topfd) if(sh.topfd != checkpoint.topfd)
sh_iorestore(&sh,checkpoint.topfd|IOSUBSHELL,jmpval); sh_iorestore(checkpoint.topfd|IOSUBSHELL,jmpval);
if(sp->sig) if(sp->sig)
{ {
if(sp->prev) if(sp->prev)
sp->prev->sig = sp->sig; sp->prev->sig = sp->sig;
else else
{ {
kill(shgd->current_pid,sp->sig); kill(sh.current_pid,sp->sig);
sh_chktrap(shp); sh_chktrap();
} }
} }
sh_sigcheck(shp); sh_sigcheck();
shp->trapnote = 0; sh.trapnote = 0;
nsig = shp->savesig; nsig = sh.savesig;
shp->savesig = 0; sh.savesig = 0;
if(nsig>0) if(nsig>0)
kill(shgd->current_pid,nsig); kill(sh.current_pid,nsig);
if(sp->subpid) if(sp->subpid)
{ {
job_wait(sp->subpid); job_wait(sp->subpid);
if(comsub) if(comsub)
sh_iounpipe(shp); sh_iounpipe();
} }
shp->comsub = sp->comsub; sh.comsub = sp->comsub;
if(comsub && iop && sp->pipefd<0) if(comsub && iop && sp->pipefd<0)
sfseek(iop,(off_t)0,SEEK_SET); sfseek(iop,(off_t)0,SEEK_SET);
if(shp->trapnote) if(sh.trapnote)
sh_chktrap(shp); sh_chktrap();
if(shp->exitval > SH_EXITSIG) if(sh.exitval > SH_EXITSIG)
{ {
int sig = shp->exitval&SH_EXITMASK; int sig = sh.exitval&SH_EXITMASK;
if(sig==SIGINT || sig== SIGQUIT) if(sig==SIGINT || sig== SIGQUIT)
kill(shgd->current_pid,sig); kill(sh.current_pid,sig);
} }
if(fatalerror) if(fatalerror)
{ {
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT; ((struct checkpt*)sh.jmplist)->mode = SH_JMPERREXIT;
switch(fatalerror) switch(fatalerror)
{ {
case 1: case 1:
shp->toomany = 1; sh.toomany = 1;
errno = saveerrno; errno = saveerrno;
errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,e_redirect); errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,e_redirect);
UNREACHABLE(); UNREACHABLE();
case 2: case 2:
/* reinit PWD as it will be wrong */ /* reinit PWD as it will be wrong */
if(shp->pwd) if(sh.pwd)
free((void*)shp->pwd); free((void*)sh.pwd);
shp->pwd = NIL(const char*); sh.pwd = NIL(const char*);
path_pwd(shp,0); path_pwd();
errno = saveerrno; errno = saveerrno;
errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,"Failed to restore PWD upon exiting subshell"); errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,"Failed to restore PWD upon exiting subshell");
UNREACHABLE(); UNREACHABLE();
@ -951,11 +947,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
UNREACHABLE(); UNREACHABLE();
} }
} }
if(shp->ignsig) if(sh.ignsig)
kill(shgd->current_pid,shp->ignsig); kill(sh.current_pid,sh.ignsig);
if(jmpval==SH_JMPSUB && shp->lastsig) if(jmpval==SH_JMPSUB && sh.lastsig)
kill(shgd->current_pid,shp->lastsig); kill(sh.current_pid,sh.lastsig);
if(jmpval && shp->toomany) if(jmpval && sh.toomany)
siglongjmp(*shp->jmplist,jmpval); siglongjmp(*sh.jmplist,jmpval);
return(iop); return(iop);
} }

View file

@ -489,7 +489,7 @@ static void setids(int mode,uid_t owner,gid_t group)
static void maketemp(char *template) static void maketemp(char *template)
{ {
register char *cp = template; register char *cp = template;
register pid_t n = shgd->current_pid; register pid_t n = getpid();
/* skip to end of string */ /* skip to end of string */
while(*++cp); while(*++cp);
/* convert process id to string */ /* convert process id to string */

View file

@ -97,7 +97,7 @@ static void sigalrm(int sig)
if(time_state&SIGALRM_CALL) if(time_state&SIGALRM_CALL)
time_state &= ~SIGALRM_CALL; time_state &= ~SIGALRM_CALL;
else if(alarm(0)) else if(alarm(0))
kill(shgd->current_pid,SIGALRM|SH_TRAP); kill(sh.current_pid,SIGALRM|SH_TRAP);
if(time_state) if(time_state)
{ {
if(time_state&IN_ADDTIMEOUT) if(time_state&IN_ADDTIMEOUT)

View file

@ -32,29 +32,27 @@
#include "io.h" #include "io.h"
#include <ccode.h> #include <ccode.h>
static struct dolnod *r_comlist(Shell_t*); static struct dolnod *r_comlist(void);
static struct argnod *r_arg(Shell_t*); static struct argnod *r_arg(void);
static struct ionod *r_redirect(Shell_t*); static struct ionod *r_redirect(void);
static struct regnod *r_switch(Shell_t*); static struct regnod *r_switch(void);
static Shnode_t *r_tree(Shell_t*); static Shnode_t *r_tree(void);
static char *r_string(Stk_t*); static char *r_string(void);
static void r_comarg(Shell_t*,struct comnod*); static void r_comarg(struct comnod*);
static Sfio_t *infile; static Sfio_t *infile;
#define getnode(s,type) ((Shnode_t*)stkalloc((s),sizeof(struct type))) #define getnode(type) ((Shnode_t*)stkalloc(sh.stk,sizeof(struct type)))
Shnode_t *sh_trestore(Shell_t *shp,Sfio_t *in) Shnode_t *sh_trestore(Sfio_t *in)
{ {
Shnode_t *t;
infile = in; infile = in;
t = r_tree(shp); return(r_tree());
return(t);
} }
/* /*
* read in a shell tree * read in a shell tree
*/ */
static Shnode_t *r_tree(Shell_t *shp) static Shnode_t *r_tree(void)
{ {
long l = sfgetl(infile); long l = sfgetl(infile);
register int type; register int type;
@ -66,107 +64,107 @@ static Shnode_t *r_tree(Shell_t *shp)
{ {
case TTIME: case TTIME:
case TPAR: case TPAR:
t = getnode(shp->stk,parnod); t = getnode(parnod);
t->par.partre = r_tree(shp); t->par.partre = r_tree();
break; break;
case TCOM: case TCOM:
t = getnode(shp->stk,comnod); t = getnode(comnod);
t->tre.tretyp = type; t->tre.tretyp = type;
r_comarg(shp,(struct comnod*)t); r_comarg((struct comnod*)t);
break; break;
case TSETIO: case TSETIO:
case TFORK: case TFORK:
t = getnode(shp->stk,forknod); t = getnode(forknod);
t->fork.forkline = sfgetu(infile); t->fork.forkline = sfgetu(infile);
t->fork.forktre = r_tree(shp); t->fork.forktre = r_tree();
t->fork.forkio = r_redirect(shp); t->fork.forkio = r_redirect();
break; break;
case TIF: case TIF:
t = getnode(shp->stk,ifnod); t = getnode(ifnod);
t->if_.iftre = r_tree(shp); t->if_.iftre = r_tree();
t->if_.thtre = r_tree(shp); t->if_.thtre = r_tree();
t->if_.eltre = r_tree(shp); t->if_.eltre = r_tree();
break; break;
case TWH: case TWH:
t = getnode(shp->stk,whnod); t = getnode(whnod);
t->wh.whinc = (struct arithnod*)r_tree(shp); t->wh.whinc = (struct arithnod*)r_tree();
t->wh.whtre = r_tree(shp); t->wh.whtre = r_tree();
t->wh.dotre = r_tree(shp); t->wh.dotre = r_tree();
break; break;
case TLST: case TLST:
case TAND: case TAND:
case TORF: case TORF:
case TFIL: case TFIL:
t = getnode(shp->stk,lstnod); t = getnode(lstnod);
t->lst.lstlef = r_tree(shp); t->lst.lstlef = r_tree();
t->lst.lstrit = r_tree(shp); t->lst.lstrit = r_tree();
break; break;
case TARITH: case TARITH:
t = getnode(shp->stk,arithnod); t = getnode(arithnod);
t->ar.arline = sfgetu(infile); t->ar.arline = sfgetu(infile);
t->ar.arexpr = r_arg(shp); t->ar.arexpr = r_arg();
t->ar.arcomp = 0; t->ar.arcomp = 0;
if((t->ar.arexpr)->argflag&ARG_RAW) if((t->ar.arexpr)->argflag&ARG_RAW)
t->ar.arcomp = sh_arithcomp(shp,(t->ar.arexpr)->argval); t->ar.arcomp = sh_arithcomp((t->ar.arexpr)->argval);
break; break;
case TFOR: case TFOR:
t = getnode(shp->stk,fornod); t = getnode(fornod);
t->for_.forline = 0; t->for_.forline = 0;
if(type&FLINENO) if(type&FLINENO)
t->for_.forline = sfgetu(infile); t->for_.forline = sfgetu(infile);
t->for_.fortre = r_tree(shp); t->for_.fortre = r_tree();
t->for_.fornam = r_string(shp->stk); t->for_.fornam = r_string();
t->for_.forlst = (struct comnod*)r_tree(shp); t->for_.forlst = (struct comnod*)r_tree();
break; break;
case TSW: case TSW:
t = getnode(shp->stk,swnod); t = getnode(swnod);
t->sw.swline = 0; t->sw.swline = 0;
if(type&FLINENO) if(type&FLINENO)
t->sw.swline = sfgetu(infile); t->sw.swline = sfgetu(infile);
t->sw.swarg = r_arg(shp); t->sw.swarg = r_arg();
if(type&COMSCAN) if(type&COMSCAN)
t->sw.swio = r_redirect(shp); t->sw.swio = r_redirect();
else else
t->sw.swio = 0; t->sw.swio = 0;
t->sw.swlst = r_switch(shp); t->sw.swlst = r_switch();
break; break;
case TFUN: case TFUN:
{ {
Stak_t *savstak; Stak_t *savstak;
struct slnod *slp; struct slnod *slp;
struct functnod *fp; struct functnod *fp;
t = getnode(shp->stk,functnod); t = getnode(functnod);
t->funct.functloc = -1; t->funct.functloc = -1;
t->funct.functline = sfgetu(infile); t->funct.functline = sfgetu(infile);
t->funct.functnam = r_string(shp->stk); t->funct.functnam = r_string();
savstak = stakcreate(STAK_SMALL); savstak = stakcreate(STAK_SMALL);
savstak = stakinstall(savstak, 0); savstak = stakinstall(savstak, 0);
slp = (struct slnod*)stkalloc(shp->stk,sizeof(struct slnod)+sizeof(struct functnod)); slp = (struct slnod*)stkalloc(sh.stk,sizeof(struct slnod)+sizeof(struct functnod));
slp->slchild = 0; slp->slchild = 0;
slp->slnext = shp->st.staklist; slp->slnext = sh.st.staklist;
shp->st.staklist = 0; sh.st.staklist = 0;
fp = (struct functnod*)(slp+1); fp = (struct functnod*)(slp+1);
memset(fp, 0, sizeof(*fp)); memset(fp, 0, sizeof(*fp));
fp->functtyp = TFUN|FAMP; fp->functtyp = TFUN|FAMP;
if(shp->st.filename) if(sh.st.filename)
fp->functnam = stkcopy(shp->stk,shp->st.filename); fp->functnam = stkcopy(sh.stk,sh.st.filename);
t->funct.functtre = r_tree(shp); t->funct.functtre = r_tree();
t->funct.functstak = slp; t->funct.functstak = slp;
t->funct.functargs = (struct comnod*)r_tree(shp); t->funct.functargs = (struct comnod*)r_tree();
slp->slptr = stakinstall(savstak,0); slp->slptr = stakinstall(savstak,0);
slp->slchild = shp->st.staklist; slp->slchild = sh.st.staklist;
break; break;
} }
case TTST: case TTST:
t = getnode(shp->stk,tstnod); t = getnode(tstnod);
t->tst.tstline = sfgetu(infile); t->tst.tstline = sfgetu(infile);
if((type&TPAREN)==TPAREN) if((type&TPAREN)==TPAREN)
t->lst.lstlef = r_tree(shp); t->lst.lstlef = r_tree();
else else
{ {
t->lst.lstlef = (Shnode_t*)r_arg(shp); t->lst.lstlef = (Shnode_t*)r_arg();
if((type&TBINARY)) if((type&TBINARY))
t->lst.lstrit = (Shnode_t*)r_arg(shp); t->lst.lstrit = (Shnode_t*)r_arg();
} }
} }
if(t) if(t)
@ -174,11 +172,11 @@ static Shnode_t *r_tree(Shell_t *shp)
return(t); return(t);
} }
static struct argnod *r_arg(Shell_t *shp) static struct argnod *r_arg(void)
{ {
register struct argnod *ap=0, *apold, *aptop=0; register struct argnod *ap=0, *apold, *aptop=0;
register long l; register long l;
Stk_t *stkp=shp->stk; Stk_t *stkp=sh.stk;
while((l=sfgetu(infile))>0) while((l=sfgetu(infile))>0)
{ {
ap = (struct argnod*)stkseek(stkp,(unsigned)l+ARGVAL); ap = (struct argnod*)stkseek(stkp,(unsigned)l+ARGVAL);
@ -196,12 +194,12 @@ static struct argnod *r_arg(Shell_t *shp)
ap->argflag = sfgetc(infile); ap->argflag = sfgetc(infile);
ap = (struct argnod*)stkfreeze(stkp,0); ap = (struct argnod*)stkfreeze(stkp,0);
if(*ap->argval==0 && (ap->argflag&ARG_EXP)) if(*ap->argval==0 && (ap->argflag&ARG_EXP))
ap->argchn.ap = (struct argnod*)r_tree(shp); ap->argchn.ap = (struct argnod*)r_tree();
else if(*ap->argval==0 && (ap->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED))==0) else if(*ap->argval==0 && (ap->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED))==0)
{ {
struct fornod *fp = (struct fornod*)getnode(shp->stk,fornod); struct fornod *fp = (struct fornod*)getnode(fornod);
fp->fortyp = sfgetu(infile); fp->fortyp = sfgetu(infile);
fp->fortre = r_tree(shp); fp->fortre = r_tree();
fp->fornam = ap->argval+1; fp->fornam = ap->argval+1;
ap->argchn.ap = (struct argnod*)fp; ap->argchn.ap = (struct argnod*)fp;
} }
@ -212,37 +210,37 @@ static struct argnod *r_arg(Shell_t *shp)
return(aptop); return(aptop);
} }
static struct ionod *r_redirect(Shell_t* shp) static struct ionod *r_redirect(void)
{ {
register long l; register long l;
register struct ionod *iop=0, *iopold, *ioptop=0; register struct ionod *iop=0, *iopold, *ioptop=0;
while((l=sfgetl(infile))>=0) while((l=sfgetl(infile))>=0)
{ {
iop = (struct ionod*)getnode(shp->stk,ionod); iop = (struct ionod*)getnode(ionod);
if(!ioptop) if(!ioptop)
ioptop = iop; ioptop = iop;
else else
iopold->ionxt = iop; iopold->ionxt = iop;
iop->iofile = l; iop->iofile = l;
if((l & IOPROCSUB) && !(l & IOLSEEK)) if((l & IOPROCSUB) && !(l & IOLSEEK))
iop->ioname = (char*)r_tree(shp); /* process substitution as file name to redirection */ iop->ioname = (char*)r_tree(); /* process substitution as file name to redirection */
else else
iop->ioname = r_string(shp->stk); /* file name, descriptor, etc. */ iop->ioname = r_string(); /* file name, descriptor, etc. */
if(iop->iodelim = r_string(shp->stk)) if(iop->iodelim = r_string())
{ {
iop->iosize = sfgetl(infile); iop->iosize = sfgetl(infile);
if(shp->heredocs) if(sh.heredocs)
iop->iooffset = sfseek(shp->heredocs,(off_t)0,SEEK_END); iop->iooffset = sfseek(sh.heredocs,(off_t)0,SEEK_END);
else else
{ {
shp->heredocs = sftmp(512); sh.heredocs = sftmp(512);
iop->iooffset = 0; iop->iooffset = 0;
} }
sfmove(infile,shp->heredocs, iop->iosize, -1); sfmove(infile,sh.heredocs, iop->iosize, -1);
} }
iopold = iop; iopold = iop;
if(iop->iofile&IOVNM) if(iop->iofile&IOVNM)
iop->iovname = r_string(shp->stk); iop->iovname = r_string();
else else
iop->iovname = 0; iop->iovname = 0;
iop->iofile &= ~IOVNM; iop->iofile &= ~IOVNM;
@ -252,30 +250,30 @@ static struct ionod *r_redirect(Shell_t* shp)
return(ioptop); return(ioptop);
} }
static void r_comarg(Shell_t *shp,struct comnod *com) static void r_comarg(struct comnod *com)
{ {
char *cmdname=0; char *cmdname=0;
com->comio = r_redirect(shp); com->comio = r_redirect();
com->comset = r_arg(shp); com->comset = r_arg();
com->comstate = 0; com->comstate = 0;
if(com->comtyp&COMSCAN) if(com->comtyp&COMSCAN)
{ {
com->comarg = r_arg(shp); com->comarg = r_arg();
if(com->comarg->argflag==ARG_RAW) if(com->comarg->argflag==ARG_RAW)
cmdname = com->comarg->argval; cmdname = com->comarg->argval;
} }
else if(com->comarg = (struct argnod*)r_comlist(shp)) else if(com->comarg = (struct argnod*)r_comlist())
cmdname = ((struct dolnod*)(com->comarg))->dolval[ARG_SPARE]; cmdname = ((struct dolnod*)(com->comarg))->dolval[ARG_SPARE];
com->comline = sfgetu(infile); com->comline = sfgetu(infile);
com->comnamq = 0; com->comnamq = 0;
if(cmdname) if(cmdname)
{ {
char *cp; char *cp;
com->comnamp = (void*)nv_search(cmdname,shp->fun_tree,0); com->comnamp = (void*)nv_search(cmdname,sh.fun_tree,0);
if(com->comnamp && (cp =strrchr(cmdname+1,'.'))) if(com->comnamp && (cp =strrchr(cmdname+1,'.')))
{ {
*cp = 0; *cp = 0;
com->comnamp = (void*)nv_open(cmdname,shp->var_tree,NV_VARNAME|NV_NOADD|NV_NOARRAY); com->comnamp = (void*)nv_open(cmdname,sh.var_tree,NV_VARNAME|NV_NOADD|NV_NOARRAY);
*cp = '.'; *cp = '.';
} }
} }
@ -283,36 +281,36 @@ static void r_comarg(Shell_t *shp,struct comnod *com)
com->comnamp = 0; com->comnamp = 0;
} }
static struct dolnod *r_comlist(Shell_t *shp) static struct dolnod *r_comlist(void)
{ {
register struct dolnod *dol=0; register struct dolnod *dol=0;
register long l; register long l;
register char **argv; register char **argv;
if((l=sfgetl(infile))>0) if((l=sfgetl(infile))>0)
{ {
dol = (struct dolnod*)stkalloc(shp->stk,sizeof(struct dolnod) + sizeof(char*)*(l+ARG_SPARE)); dol = (struct dolnod*)stkalloc(sh.stk,sizeof(struct dolnod) + sizeof(char*)*(l+ARG_SPARE));
dol->dolnum = l; dol->dolnum = l;
dol->dolbot = ARG_SPARE; dol->dolbot = ARG_SPARE;
argv = dol->dolval+ARG_SPARE; argv = dol->dolval+ARG_SPARE;
while(*argv++ = r_string(shp->stk)); while(*argv++ = r_string());
} }
return(dol); return(dol);
} }
static struct regnod *r_switch(Shell_t *shp) static struct regnod *r_switch(void)
{ {
register long l; register long l;
struct regnod *reg=0,*regold,*regtop=0; struct regnod *reg=0,*regold,*regtop=0;
while((l=sfgetl(infile))>=0) while((l=sfgetl(infile))>=0)
{ {
reg = (struct regnod*)getnode(shp->stk,regnod); reg = (struct regnod*)getnode(regnod);
if(!regtop) if(!regtop)
regtop = reg; regtop = reg;
else else
regold->regnxt = reg; regold->regnxt = reg;
reg->regflag = l; reg->regflag = l;
reg->regptr = r_arg(shp); reg->regptr = r_arg();
reg->regcom = r_tree(shp); reg->regcom = r_tree();
regold = reg; regold = reg;
} }
if(reg) if(reg)
@ -320,14 +318,14 @@ static struct regnod *r_switch(Shell_t *shp)
return(regtop); return(regtop);
} }
static char *r_string(Stk_t *stkp) static char *r_string(void)
{ {
register Sfio_t *in = infile; register Sfio_t *in = infile;
register unsigned long l = sfgetu(in); register unsigned long l = sfgetu(in);
register char *ptr; register char *ptr;
if(l == 0) if(l == 0)
return(NIL(char*)); return(NIL(char*));
ptr = stkalloc(stkp,(unsigned)l); ptr = stkalloc(sh.stk,(unsigned)l);
if(--l > 0) if(--l > 0)
{ {
if(sfread(in,ptr,(size_t)l)!=(size_t)l) if(sfread(in,ptr,(size_t)l)!=(size_t)l)

View file

@ -31,7 +31,7 @@
void *sh_waitnotify(int(*newevent)(int,long,int)) void *sh_waitnotify(int(*newevent)(int,long,int))
{ {
int (*old)(int,long,int); int (*old)(int,long,int);
old = shgd->waitevent; old = sh.waitevent;
shgd->waitevent = newevent; sh.waitevent = newevent;
return((void*)old); return((void*)old);
} }

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,7 @@ unsigned int sh_isoption(int \fIoption\fP);
unsigned int sh_onoption(int \fIoption\fP); unsigned int sh_onoption(int \fIoption\fP);
unsigned int sh_offoption(int \fIoption\fP); unsigned int sh_offoption(int \fIoption\fP);
void *sh_parse(Shell_t *\fIshp\fP, Sfio_t *\fIsp\fP, int \fIflags\fP); void *sh_parse(Sfio_t *\fIsp\fP, int \fIflags\fP);
int sh_trap(const char *\fIstring\fP, int \fImode\fP); int sh_trap(const char *\fIstring\fP, int \fImode\fP);
int sh_run(int \fIargc\fP, char *\fIargv\fP[]); int sh_run(int \fIargc\fP, char *\fIargv\fP[]);
int sh_eval(Sfio_t *\fIsp\fP, int \fImode\fP); int sh_eval(Sfio_t *\fIsp\fP, int \fImode\fP);
@ -116,7 +116,11 @@ initialize this library before any other commands in this library
are invoked. are invoked.
The arguments \fIargc\fP and \fIargv\fP are the number The arguments \fIargc\fP and \fIargv\fP are the number
of arguments and the vector of arguments as supplied by the shell. of arguments and the vector of arguments as supplied by the shell.
It returns a pointer the \f3Shell_t\fP. It returns a pointer to the \f3sh\fP shell state structure
which is of type \f3Shell_t\fP.
Since only one shell interpreter per process is supported,
there is only one instance of \f3sh\fP,
so it does not matter whether it is accessed directly or via a pointer.
.TP .TP
.B 3 .B 3
To build a new version of \f3ksh\fP with extended capabilities, To build a new version of \f3ksh\fP with extended capabilities,
@ -143,16 +147,21 @@ The \f3Shell_t\fP structure contains the following fields:
Dt_t *\fIvar_tree\fP; \fR/* shell variable dictionary */\fP Dt_t *\fIvar_tree\fP; \fR/* shell variable dictionary */\fP
Dt_t *\fIfun_tree\fP; \fR/* shell function dictionary */\fP Dt_t *\fIfun_tree\fP; \fR/* shell function dictionary */\fP
Dt_t *\fIalias_tree\fP; \fR/* shell alias dictionary */\fP Dt_t *\fIalias_tree\fP; \fR/* shell alias dictionary */\fP
Dt_t *\fIbltin_tree\fP; \fR/* shell built-in dictionary */\fP Dt_t *\fIbltin_tree\fP; \fR/* shell built-in command dictionary */\fP
Dt_t *\fItrack_tree\fP; \fR/* shell hash table */\fP Dt_t *\fItrack_tree\fP; \fR/* shell hash table (tracked alias dictionary) */\fP
Shscope_t *\fItopscope\fP; \fR/* pointer to top-level scope */\fP Shscope_t *\fItopscope\fP; \fR/* pointer to top-level scope */\fP
char *\fIinfile_name\fP; \fR/* path name of current input file */\fP
int \fIinlineno\fP; \fR/* line number of current input file */\fP int \fIinlineno\fP; \fR/* line number of current input file */\fP
int \fIexitval\fP; \fR/* most recent exit value */\fP int \fIexitval\fP; \fR/* exit status of the command currently being run */\fP
int \fIsavexit\fP; \fR/* $? == exit status of the last command executed */\fP
.ft R .ft R
.fi .fi
This structure is returned by \f3sh_init()\fP but can also be retrieved As of ksh 93u+m, it is once again officially supported to access this
structure directly as \f3sh\fP. In addition, a pointer to
this structure is returned by \f3sh_init()\fP but can also be retrieved
by a call to \f3sh_getinterp()\fP. by a call to \f3sh_getinterp()\fP.
There are other fields not documented here, but they should be considered
unstable and subject to change between releases; programs using libshell
should not rely on them.
.PP .PP
All built-in commands to the shell are invoked with All built-in commands to the shell are invoked with
three arguments. The first two arguments give the three arguments. The first two arguments give the
@ -291,8 +300,8 @@ If \fImode\fP is non-zero and the history file has
been created, the stream defined by \fIsp\fP been created, the stream defined by \fIsp\fP
will be appended to the history file as a command. will be appended to the history file as a command.
.PP .PP
The \f3sh_parse()\fP function takes a pointer to the The \f3sh_parse()\fP function takes
shell interpreter \fIshp\fP, a pointer to a string or file stream a pointer to a string or file stream
\fIsp\fP, and compilation flags, and returns a pointer \fIsp\fP, and compilation flags, and returns a pointer
to a parse tree of the compiled stream. This pointer can to a parse tree of the compiled stream. This pointer can
be used in subsequent calls to \f3sh_trap()\fP. be used in subsequent calls to \f3sh_trap()\fP.

View file

@ -46,11 +46,7 @@
struct Shbltin_s; struct Shbltin_s;
typedef struct Shbltin_s Shbltin_t; typedef struct Shbltin_s Shbltin_t;
#ifdef _SHTABLE_H /* pre-ksh93u+ -- obsolete */
typedef int (*Shbltin_f)(int, char**, void*);
#else
typedef int (*Shbltin_f)(int, char**, Shbltin_t*); typedef int (*Shbltin_f)(int, char**, Shbltin_t*);
#endif /* _SHTABLE_H */
struct Shbltin_s struct Shbltin_s
{ {