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:
parent
01da863154
commit
b590a9f155
68 changed files with 3674 additions and 3935 deletions
|
@ -31,7 +31,7 @@
|
|||
*
|
||||
* > I never documented the alarm builtin because it is problematic. The
|
||||
* > 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
|
||||
* > it is blocked and it should return and then handle the trap.
|
||||
*/
|
||||
|
@ -54,7 +54,6 @@ struct tevent
|
|||
long milli;
|
||||
int flags;
|
||||
void *timeout;
|
||||
Shell_t *sh;
|
||||
};
|
||||
|
||||
static const char ALARM[] = "alarm";
|
||||
|
@ -127,23 +126,23 @@ static void print_alarms(void *list)
|
|||
static void trap_timeout(void* handle)
|
||||
{
|
||||
register struct tevent *tp = (struct tevent*)handle;
|
||||
tp->sh->trapnote |= SH_SIGALRM;
|
||||
sh.trapnote |= SH_SIGALRM;
|
||||
if(!(tp->flags&R_FLAG))
|
||||
tp->timeout = 0;
|
||||
tp->flags |= L_FLAG;
|
||||
tp->sh->sigflag[SIGALRM] |= SH_SIGALRM;
|
||||
sh.sigflag[SIGALRM] |= SH_SIGALRM;
|
||||
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 *tptop;
|
||||
while(1)
|
||||
{
|
||||
shp->sigflag[SIGALRM] &= ~SH_SIGALRM;
|
||||
tptop= (struct tevent*)shp->st.timetrap;
|
||||
sh.sigflag[SIGALRM] &= ~SH_SIGALRM;
|
||||
tptop= (struct tevent*)sh.st.timetrap;
|
||||
for(tp=tptop;tp;tp=tpnext)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -169,12 +168,11 @@ void sh_timetraps(Shell_t *shp)
|
|||
/*
|
||||
* This trap function catches "alarm" actions only
|
||||
*/
|
||||
static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t
|
||||
*fp)
|
||||
static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t *fp)
|
||||
{
|
||||
register struct tevent *tp = (struct tevent*)fp;
|
||||
if(!event)
|
||||
return(action?"":(char*)ALARM);
|
||||
return(action ? Empty : (char*)ALARM);
|
||||
if(strcmp(event,ALARM)!=0)
|
||||
{
|
||||
/* 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;
|
||||
else
|
||||
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 double d;
|
||||
Shell_t *shp = tp->sh;
|
||||
if(val)
|
||||
{
|
||||
double now;
|
||||
|
@ -216,14 +213,14 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
|
|||
d -= now;
|
||||
tp->milli = 1000*(d+.0005);
|
||||
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)
|
||||
shp->st.timetrap = time_add(tp,shp->st.timetrap);
|
||||
sh.st.timetrap = time_add(tp,sh.st.timetrap);
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
nv_close(tp->action);
|
||||
nv_unset(np);
|
||||
|
@ -245,7 +242,6 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
|
|||
register int n,rflag=0;
|
||||
register Namval_t *np;
|
||||
register struct tevent *tp;
|
||||
register Shell_t *shp = context->shp;
|
||||
while (n = optget(argv, sh_optalarm)) switch (n)
|
||||
{
|
||||
case 'r':
|
||||
|
@ -267,7 +263,7 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
|
|||
}
|
||||
if(argc==0)
|
||||
{
|
||||
print_alarms(shp->st.timetrap);
|
||||
print_alarms(sh.st.timetrap);
|
||||
return(0);
|
||||
}
|
||||
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));
|
||||
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))
|
||||
nv_unset(np);
|
||||
nv_setattr(np, NV_DOUBLE);
|
||||
|
@ -283,7 +279,6 @@ int b_alarm(int argc,char *argv[],Shbltin_t *context)
|
|||
tp->fun.disc = &alarmdisc;
|
||||
tp->flags = rflag;
|
||||
tp->node = np;
|
||||
tp->sh = shp;
|
||||
nv_stack(np,(Namfun_t*)tp);
|
||||
nv_putval(np, argv[1], 0);
|
||||
return(0);
|
||||
|
|
|
@ -54,11 +54,11 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
|
|||
register char *dir;
|
||||
Pathcomp_t *cdpath = 0;
|
||||
register const char *dp;
|
||||
register Shell_t *shp = context->shp;
|
||||
int saverrno=0;
|
||||
int rval,pflag=0,eflag=0,ret=1;
|
||||
char *oldpwd;
|
||||
Namval_t *opwdnod, *pwdnod;
|
||||
NOT_USED(context);
|
||||
while((rval = optget(argv,sh_optcd))) switch(rval)
|
||||
{
|
||||
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));
|
||||
UNREACHABLE();
|
||||
}
|
||||
oldpwd = path_pwd(shp,0);
|
||||
opwdnod = sh_scoped(shp,OLDPWDNOD);
|
||||
pwdnod = sh_scoped(shp,PWDNOD);
|
||||
oldpwd = path_pwd();
|
||||
opwdnod = sh_scoped(OLDPWDNOD);
|
||||
pwdnod = sh_scoped(PWDNOD);
|
||||
if(oldpwd == e_dot && pwdnod->nvalue.cp)
|
||||
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 */
|
||||
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,
|
||||
* 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(!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[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))
|
||||
{
|
||||
shp->cdpathlist = (void*)cdpath;
|
||||
cdpath->shp = shp;
|
||||
}
|
||||
if(cdpath=path_addpath((Pathcomp_t*)0,dp,PATH_CDPATH))
|
||||
sh.cdpathlist = (void*)cdpath;
|
||||
}
|
||||
}
|
||||
if(*dir!='/')
|
||||
{
|
||||
/* check for leading .. */
|
||||
char *cp;
|
||||
sfprintf(shp->strbuf,"%s",dir);
|
||||
cp = sfstruse(shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%s",dir);
|
||||
cp = sfstruse(sh.strbuf);
|
||||
pathcanon(cp, 0);
|
||||
if(cp[0]=='.' && cp[1]=='.' && (cp[2]=='/' || cp[2]==0))
|
||||
{
|
||||
if(!shp->strbuf2)
|
||||
shp->strbuf2 = sfstropen();
|
||||
sfprintf(shp->strbuf2,"%s/%s",oldpwd,cp);
|
||||
dir = sfstruse(shp->strbuf2);
|
||||
if(!sh.strbuf2)
|
||||
sh.strbuf2 = sfstropen();
|
||||
sfprintf(sh.strbuf2,"%s/%s",oldpwd,cp);
|
||||
dir = sfstruse(sh.strbuf2);
|
||||
pathcanon(dir, 0);
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +166,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
|
|||
do
|
||||
{
|
||||
dp = cdpath?cdpath->name:"";
|
||||
cdpath = path_nextcomp(shp,cdpath,dir,0);
|
||||
cdpath = path_nextcomp(cdpath,dir,0);
|
||||
#if _WINIX
|
||||
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))
|
||||
continue;
|
||||
}
|
||||
if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0)
|
||||
if((rval=chdir(path_relative(stakptr(PATH_OFFSET)))) >= 0)
|
||||
goto success;
|
||||
if(errno!=ENOENT && saverrno==0)
|
||||
saverrno=errno;
|
||||
}
|
||||
while(cdpath);
|
||||
if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/')
|
||||
if(rval<0 && *dir=='/' && *(path_relative(stakptr(PATH_OFFSET)))!='/')
|
||||
rval = chdir(dir);
|
||||
/* use absolute chdir() if relative chdir() fails */
|
||||
if(rval<0)
|
||||
|
@ -239,27 +236,27 @@ success:
|
|||
dir[len] = 0;
|
||||
nv_putval(pwdnod,dir,NV_RDONLY);
|
||||
nv_onattr(pwdnod,NV_EXPORT);
|
||||
if(shp->pwd)
|
||||
free((void*)shp->pwd);
|
||||
shp->pwd = sh_strdup(pwdnod->nvalue.cp);
|
||||
if(sh.pwd)
|
||||
free((void*)sh.pwd);
|
||||
sh.pwd = sh_strdup(pwdnod->nvalue.cp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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. */
|
||||
if(shp->pwd)
|
||||
free((void*)shp->pwd);
|
||||
shp->pwd = NIL(const char*);
|
||||
path_pwd(shp,0);
|
||||
if(*shp->pwd != '/')
|
||||
if(sh.pwd)
|
||||
free((void*)sh.pwd);
|
||||
sh.pwd = NIL(const char*);
|
||||
path_pwd();
|
||||
if(*sh.pwd != '/')
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_system(ret),e_direct);
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
nv_scan(sh_subtracktree(1),rehash,(void*)0,NV_TAGGED,NV_TAGGED);
|
||||
path_newdir(shp,shp->pathlist);
|
||||
path_newdir(shp,shp->cdpathlist);
|
||||
path_newdir(sh.pathlist);
|
||||
path_newdir(sh.cdpathlist);
|
||||
if(pflag && eflag)
|
||||
{
|
||||
/* 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 char *cp;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
while((n = optget(argv,sh_optpwd))) switch(n)
|
||||
{
|
||||
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));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(*(cp = path_pwd(shp,0)) != '/')
|
||||
if(*(cp = path_pwd()) != '/')
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_system(1), e_pwd);
|
||||
UNREACHABLE();
|
||||
|
|
|
@ -99,7 +99,7 @@ int b_break(register int n, register char *argv[],Shbltin_t *context)
|
|||
{
|
||||
char *arg;
|
||||
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)
|
||||
{
|
||||
case ':':
|
||||
|
@ -125,13 +125,13 @@ int b_break(register int n, register char *argv[],Shbltin_t *context)
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if(shp->st.loopcnt)
|
||||
if(sh.st.loopcnt)
|
||||
{
|
||||
shp->st.execbrk = shp->st.breakcnt = n;
|
||||
if(shp->st.breakcnt > shp->st.loopcnt)
|
||||
shp->st.breakcnt = shp->st.loopcnt;
|
||||
sh.st.execbrk = sh.st.breakcnt = n;
|
||||
if(sh.st.breakcnt > sh.st.loopcnt)
|
||||
sh.st.breakcnt = sh.st.loopcnt;
|
||||
if(cont)
|
||||
shp->st.breakcnt = -shp->st.breakcnt;
|
||||
sh.st.breakcnt = -sh.st.breakcnt;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -209,7 +209,6 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
|
|||
Namarr_t *ap;
|
||||
char *cp,*sp;
|
||||
struct Enum *ep;
|
||||
Shell_t *shp = context->shp;
|
||||
struct {
|
||||
Optdisc_t opt;
|
||||
Namval_t *np;
|
||||
|
@ -251,7 +250,7 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
|
|||
}
|
||||
n = staktell();
|
||||
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);
|
||||
n = sz;
|
||||
i = 0;
|
||||
|
@ -296,12 +295,12 @@ int b_enum(int argc, char** argv, Shbltin_t *context)
|
|||
#ifdef STANDALONE
|
||||
void lib_init(int flag, void* context)
|
||||
{
|
||||
Shell_t *shp = ((Shbltin_t*)context)->shp;
|
||||
Namval_t *mp,*bp;
|
||||
NOT_USED(context);
|
||||
if(flag)
|
||||
return;
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -35,12 +35,11 @@
|
|||
|
||||
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 = shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
#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
|
||||
if(nv_search(s,shp->fun_tree,0))
|
||||
if(nv_search(s,sh.fun_tree,0))
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
{
|
||||
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,'(');
|
||||
sfputr(stkp,s,')');
|
||||
sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1);
|
||||
sfputr(sp,sh_mactry(stkfreeze(stkp,1)),-1);
|
||||
stkset(stkp,savptr,savtop);
|
||||
}
|
||||
return(1);
|
||||
|
@ -59,19 +58,14 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
register char *options=error_info.context->id;
|
||||
register Namval_t *np;
|
||||
register int flag, mode;
|
||||
register Shell_t *shp = context->shp;
|
||||
char value[2], key[2];
|
||||
int jmpval;
|
||||
volatile int extended, r= -1;
|
||||
struct checkpt buff, *pp;
|
||||
struct {
|
||||
Optdisc_t hdr;
|
||||
Shell_t *sh;
|
||||
} disc;
|
||||
Optdisc_t disc;
|
||||
memset(&disc, 0, sizeof(disc));
|
||||
disc.hdr.version = OPT_VERSION;
|
||||
disc.hdr.infof = infof;
|
||||
disc.sh = shp;
|
||||
disc.version = OPT_VERSION;
|
||||
disc.infof = infof;
|
||||
value[1] = 0;
|
||||
key[1] = 0;
|
||||
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.id = options;
|
||||
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)
|
||||
{
|
||||
argv +=1;
|
||||
|
@ -104,27 +98,27 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
}
|
||||
else
|
||||
{
|
||||
argv = shp->st.dolv;
|
||||
argc = shp->st.dolc;
|
||||
argv = sh.st.dolv;
|
||||
argc = sh.st.dolc;
|
||||
}
|
||||
opt_info.index = shp->st.optindex;
|
||||
opt_info.offset = shp->st.optchar;
|
||||
opt_info.index = sh.st.optindex;
|
||||
opt_info.offset = sh.st.optchar;
|
||||
if(mode= (*options==':'))
|
||||
options++;
|
||||
extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
|
||||
sh_pushcontext(shp,&buff,1);
|
||||
sh_pushcontext(&sh,&buff,1);
|
||||
jmpval = sigsetjmp(buff.buff,0);
|
||||
if(jmpval)
|
||||
{
|
||||
sh_popcontext(shp,&buff);
|
||||
shp->st.opterror = 1;
|
||||
sh_popcontext(&sh,&buff);
|
||||
sh.st.opterror = 1;
|
||||
if(r==0)
|
||||
return(2);
|
||||
pp = (struct checkpt*)shp->jmplist;
|
||||
pp = (struct checkpt*)sh.jmplist;
|
||||
pp->mode = SH_JMPERREXIT;
|
||||
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)
|
||||
{
|
||||
case '?':
|
||||
|
@ -148,7 +142,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
flag = '?';
|
||||
}
|
||||
*(options = value) = flag;
|
||||
shp->st.opterror = 1;
|
||||
sh.st.opterror = 1;
|
||||
if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
|
||||
{
|
||||
opt_info.offset = 0;
|
||||
|
@ -156,7 +150,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
}
|
||||
break;
|
||||
case 0:
|
||||
if(shp->st.opterror)
|
||||
if(sh.st.opterror)
|
||||
{
|
||||
char *com[2];
|
||||
com[0] = "-?";
|
||||
|
@ -183,11 +177,11 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
if(r<0)
|
||||
r = 0;
|
||||
error_info.context->flags &= ~ERROR_SILENT;
|
||||
shp->st.optindex = opt_info.index;
|
||||
shp->st.optchar = opt_info.offset;
|
||||
sh.st.optindex = opt_info.index;
|
||||
sh.st.optchar = opt_info.offset;
|
||||
nv_putval(np, options, 0);
|
||||
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)
|
||||
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] != '+')
|
||||
|
@ -205,7 +199,7 @@ int b_getopts(int argc,char *argv[],Shbltin_t *context)
|
|||
else
|
||||
nv_putval(np, opt_info.arg, NV_RDONLY);
|
||||
nv_close(np);
|
||||
sh_popcontext(shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
opt_info.disc = 0;
|
||||
return(r);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
register History_t *hp;
|
||||
register char *arg;
|
||||
register int flag,fdo;
|
||||
register Shell_t *shp = context->shp;
|
||||
Sfio_t *outfile;
|
||||
char *fname;
|
||||
int range[2], incr, index2, indx= -1;
|
||||
|
@ -56,12 +55,13 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
#endif
|
||||
Histloc_t location;
|
||||
NOT_USED(argc);
|
||||
if(!sh_histinit((void*)shp))
|
||||
NOT_USED(context);
|
||||
if(!sh_histinit())
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_system(1),e_histopen);
|
||||
UNREACHABLE();
|
||||
}
|
||||
hp = shp->gd->hist_ptr;
|
||||
hp = sh.hist_ptr;
|
||||
while((flag = optget(argv,sh_opthist))) switch(flag)
|
||||
{
|
||||
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);
|
||||
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";
|
||||
nflag++;
|
||||
}
|
||||
|
@ -224,9 +224,9 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
sfprintf(outfile,"%d\t",range[flag]);
|
||||
else if(lflag)
|
||||
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)
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
if(range[flag] == range[1-flag])
|
||||
break;
|
||||
range[flag] += incr;
|
||||
|
@ -236,7 +236,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
sfclose(outfile);
|
||||
hist_eof(hp);
|
||||
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;
|
||||
if(*arg!='/')
|
||||
|
@ -272,7 +272,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
char buff[IOBSIZE+1];
|
||||
Sfio_t *iop;
|
||||
/* read in and run the command */
|
||||
if(shp->hist_depth++ > HIST_RECURSE)
|
||||
if(sh.hist_depth++ > HIST_RECURSE)
|
||||
{
|
||||
sh_close(fdo);
|
||||
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);
|
||||
sh_eval(iop,1); /* this will close fdo */
|
||||
shp->hist_depth--;
|
||||
sh.hist_depth--;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ int b_hist(int argc,char *argv[], Shbltin_t *context)
|
|||
sh_offstate(SH_VERBOSE);
|
||||
sh_offstate(SH_HISTORY);
|
||||
}
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ int b_exec(int argc,char *argv[], Shbltin_t *context)
|
|||
int clear = 0;
|
||||
char *arg0 = 0;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
sh.st.ioset = 0;
|
||||
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)
|
||||
argv[0] = arg0;
|
||||
#ifdef JOBS
|
||||
if(job_close(&sh) < 0)
|
||||
if(job_close() < 0)
|
||||
return(1);
|
||||
#endif /* JOBS */
|
||||
/* 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)--;
|
||||
/* force bad exec to terminate shell */
|
||||
pp = (struct checkpt*)sh.jmplist;
|
||||
pp->mode = SH_JMPEXIT;
|
||||
sh_sigreset(2);
|
||||
sh_freeup(&sh);
|
||||
path_exec(&sh,pname,argv,NIL(struct argnod*));
|
||||
sh_freeup();
|
||||
path_exec(pname,argv,NIL(struct argnod*));
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
@ -165,8 +166,8 @@ int b_let(int argc,char *argv[],Shbltin_t *context)
|
|||
{
|
||||
register int r;
|
||||
register char *arg;
|
||||
Shell_t *shp = context->shp;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
while (r = optget(argv,sh_optlet)) switch (r)
|
||||
{
|
||||
case ':':
|
||||
|
@ -183,15 +184,15 @@ int b_let(int argc,char *argv[],Shbltin_t *context)
|
|||
UNREACHABLE();
|
||||
}
|
||||
while(arg= *argv++)
|
||||
r = !sh_arith(shp,arg);
|
||||
r = !sh_arith(arg);
|
||||
return(r);
|
||||
}
|
||||
|
||||
int b_eval(int argc,char *argv[], Shbltin_t *context)
|
||||
{
|
||||
register int r;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
while (r = optget(argv,sh_opteval)) switch (r)
|
||||
{
|
||||
case ':':
|
||||
|
@ -212,7 +213,7 @@ int b_eval(int argc,char *argv[], Shbltin_t *context)
|
|||
sh_offstate(SH_MONITOR);
|
||||
sh_eval(sh_sfeval(argv),0);
|
||||
}
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -224,8 +225,7 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
|
|||
register char *script;
|
||||
register Namval_t *np;
|
||||
register int jmpval;
|
||||
register Shell_t *shp = context->shp;
|
||||
struct sh_scoped savst, *prevscope = shp->st.self;
|
||||
struct sh_scoped savst, *prevscope = sh.st.self;
|
||||
char *filename=0, *buffer=0, *tofree;
|
||||
int fd;
|
||||
struct dolnod *saveargfor;
|
||||
|
@ -233,6 +233,7 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
|
|||
struct checkpt buff;
|
||||
Sfio_t *iop=0;
|
||||
short level;
|
||||
NOT_USED(context);
|
||||
while (n = optget(argv,sh_optdot)) switch (n)
|
||||
{
|
||||
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));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(shp->dot_depth+1 > DOTMAX)
|
||||
if(sh.dot_depth+1 > DOTMAX)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_toodeep,script);
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(!(np=shp->posix_fun))
|
||||
if(!(np=sh.posix_fun))
|
||||
{
|
||||
/* check for KornShell style function first */
|
||||
np = nv_search(script,shp->fun_tree,0);
|
||||
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && shp->bltindata.bnode==SYSDOT))
|
||||
np = nv_search(script,sh.fun_tree,0);
|
||||
if(np && is_afunction(np) && !nv_isattr(np,NV_FPOSIX) && !(sh_isoption(SH_POSIX) && sh.bltindata.bnode==SYSDOT))
|
||||
{
|
||||
if(!np->nvalue.ip)
|
||||
{
|
||||
path_search(shp,script,NIL(Pathcomp_t**),0);
|
||||
path_search(script,NIL(Pathcomp_t**),0);
|
||||
if(np->nvalue.ip)
|
||||
{
|
||||
if(nv_isattr(np,NV_FPOSIX))
|
||||
|
@ -279,40 +280,40 @@ int b_dot_cmd(register int n,char *argv[],Shbltin_t *context)
|
|||
np = 0;
|
||||
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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
filename = path_fullname(shp,stkptr(shp->stk,PATH_OFFSET));
|
||||
filename = path_fullname(stkptr(sh.stk,PATH_OFFSET));
|
||||
}
|
||||
}
|
||||
*prevscope = shp->st;
|
||||
shp->st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
|
||||
shp->st.var_local = shp->st.save_tree = shp->var_tree;
|
||||
*prevscope = sh.st;
|
||||
sh.st.lineno = np?((struct functnod*)nv_funtree(np))->functline:1;
|
||||
sh.st.var_local = sh.st.save_tree = sh.var_tree;
|
||||
if(filename)
|
||||
{
|
||||
shp->st.filename = filename;
|
||||
shp->st.lineno = 1;
|
||||
sh.st.filename = filename;
|
||||
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);
|
||||
shp->st.prevst = prevscope;
|
||||
shp->st.self = &savst;
|
||||
shp->topscope = (Shscope_t*)shp->st.self;
|
||||
prevscope->save_tree = shp->var_tree;
|
||||
tofree = shp->st.filename;
|
||||
sh.st.prevst = prevscope;
|
||||
sh.st.self = &savst;
|
||||
sh.topscope = (Shscope_t*)sh.st.self;
|
||||
prevscope->save_tree = sh.var_tree;
|
||||
tofree = sh.st.filename;
|
||||
if(np)
|
||||
shp->st.filename = np->nvalue.rp->fname;
|
||||
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
|
||||
shp->posix_fun = 0;
|
||||
sh.st.filename = np->nvalue.rp->fname;
|
||||
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
|
||||
sh.posix_fun = 0;
|
||||
if(np || argv[1])
|
||||
argsave = sh_argnew(shp,argv,&saveargfor);
|
||||
sh_pushcontext(shp,&buff,SH_JMPDOT);
|
||||
argsave = sh_argnew(argv,&saveargfor);
|
||||
sh_pushcontext(&sh,&buff,SH_JMPDOT);
|
||||
jmpval = sigsetjmp(buff.buff,0);
|
||||
if(jmpval == 0)
|
||||
{
|
||||
shp->dot_depth++;
|
||||
sh.dot_depth++;
|
||||
if(np)
|
||||
sh_exec((Shnode_t*)(nv_funtree(np)),sh_isstate(SH_ERREXIT));
|
||||
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_popcontext(shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
if(buffer)
|
||||
free(buffer);
|
||||
if(!np)
|
||||
free(tofree);
|
||||
shp->dot_depth--;
|
||||
sh.dot_depth--;
|
||||
if((np || argv[1]) && jmpval!=SH_JMPSCRIPT)
|
||||
sh_argreset(shp,(struct dolnod*)argsave,saveargfor);
|
||||
sh_argreset((struct dolnod*)argsave,saveargfor);
|
||||
else
|
||||
{
|
||||
prevscope->dolc = shp->st.dolc;
|
||||
prevscope->dolv = shp->st.dolv;
|
||||
prevscope->dolc = sh.st.dolc;
|
||||
prevscope->dolv = sh.st.dolv;
|
||||
}
|
||||
if (shp->st.self != &savst)
|
||||
*shp->st.self = shp->st;
|
||||
if (sh.st.self != &savst)
|
||||
*sh.st.self = sh.st;
|
||||
/* only restore the top Shscope_t portion for POSIX functions */
|
||||
memcpy((void*)&shp->st, (void*)prevscope, sizeof(Shscope_t));
|
||||
shp->topscope = (Shscope_t*)prevscope;
|
||||
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
|
||||
memcpy((void*)&sh.st, (void*)prevscope, sizeof(Shscope_t));
|
||||
sh.topscope = (Shscope_t*)prevscope;
|
||||
nv_putval(SH_PATHNAMENOD, sh.st.filename ,NV_NOFREE);
|
||||
if(jmpval && jmpval!=SH_JMPFUN)
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
return(shp->exitval);
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
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)
|
||||
{
|
||||
register char *arg;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(context);
|
||||
while((n = optget(argv,sh_optshift))) switch(n)
|
||||
{
|
||||
case ':':
|
||||
|
@ -388,23 +389,23 @@ int b_shift(register int n, register char *argv[], Shbltin_t *context)
|
|||
UNREACHABLE();
|
||||
}
|
||||
argv += opt_info.index;
|
||||
n = ((arg= *argv)?(int)sh_arith(shp,arg):1);
|
||||
if(n<0 || shp->st.dolc<n)
|
||||
n = ((arg= *argv)?(int)sh_arith(arg):1);
|
||||
if(n < 0 || sh.st.dolc < n)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_number,arg);
|
||||
UNREACHABLE();
|
||||
}
|
||||
else
|
||||
{
|
||||
shp->st.dolv += n;
|
||||
shp->st.dolc -= n;
|
||||
sh.st.dolv += n;
|
||||
sh.st.dolc -= n;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case ':':
|
||||
|
@ -421,7 +422,7 @@ int b_wait(int n,register char *argv[],Shbltin_t *context)
|
|||
}
|
||||
argv += opt_info.index;
|
||||
job_bwait(argv);
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
register int flag = **argv;
|
||||
register Shell_t *shp = context->shp;
|
||||
register const char *optstr = sh_optbg;
|
||||
NOT_USED(context);
|
||||
if(*argv[0]=='f')
|
||||
optstr = sh_optfg;
|
||||
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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
|
||||
int b_jobs(register int n,char *argv[],Shbltin_t *context)
|
||||
{
|
||||
register int flag = 0;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(context);
|
||||
while((n = optget(argv,sh_optjobs))) switch(n)
|
||||
{
|
||||
case 'l':
|
||||
|
@ -505,7 +506,7 @@ int b_jobs(register int n,char *argv[],Shbltin_t *context)
|
|||
UNREACHABLE();
|
||||
}
|
||||
job_wait((pid_t)0);
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -540,7 +541,7 @@ static void print_cpu_times(void)
|
|||
{
|
||||
struct timeval utime, stime;
|
||||
double dtime;
|
||||
int clk_tck = shgd->lim.clk_tck;
|
||||
int clk_tck = sh.lim.clk_tck;
|
||||
struct tms cpu_times;
|
||||
times(&cpu_times);
|
||||
/* Print the time (user & system) consumed by the shell. */
|
||||
|
|
|
@ -380,7 +380,7 @@ static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
|
|||
if (!val)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -62,7 +62,6 @@ struct printf
|
|||
char *lastarg;
|
||||
char cescape;
|
||||
char err;
|
||||
Shell_t *sh;
|
||||
};
|
||||
|
||||
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 const char preformat[] = "";
|
||||
static char *genformat(char*);
|
||||
static int fmtvecho(const char*, struct printf*);
|
||||
static ssize_t fmtbase64(Sfio_t*, char*, int);
|
||||
|
||||
struct print
|
||||
{
|
||||
Shell_t *sh;
|
||||
const char *options;
|
||||
char raw;
|
||||
char echon;
|
||||
|
@ -108,15 +105,15 @@ static int exitval;
|
|||
struct print prdata;
|
||||
prdata.options = sh_optecho+5;
|
||||
prdata.raw = prdata.echon = 0;
|
||||
prdata.sh = context->shp;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
/* This mess is because /bin/echo on BSD is different */
|
||||
if(!prdata.sh->universe)
|
||||
if(!sh.universe)
|
||||
{
|
||||
register char *universe;
|
||||
if(universe=astconf("UNIVERSE",0,0))
|
||||
bsd_univ = (strcmp(universe,"ucb")==0);
|
||||
prdata.sh->universe = 1;
|
||||
sh.universe = 1;
|
||||
}
|
||||
if(!bsd_univ)
|
||||
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;
|
||||
NOT_USED(argc);
|
||||
NOT_USED(context);
|
||||
memset(&prdata,0,sizeof(prdata));
|
||||
prdata.sh = context->shp;
|
||||
prdata.options = sh_optprintf;
|
||||
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 int n, fd = 1;
|
||||
register Shell_t *shp = context->shp;
|
||||
const char *options, *msg = e_file+4;
|
||||
char *format = 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
|
||||
{
|
||||
struct print *pp = (struct print*)context;
|
||||
shp = pp->sh;
|
||||
options = pp->options;
|
||||
if(argc==0)
|
||||
{
|
||||
|
@ -206,7 +201,7 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
|
|||
nflag++;
|
||||
break;
|
||||
case 'p':
|
||||
fd = shp->coutpipe;
|
||||
fd = sh.coutpipe;
|
||||
msg = e_query;
|
||||
break;
|
||||
case 'f':
|
||||
|
@ -214,12 +209,12 @@ int b_print(int argc, char *argv[], Shbltin_t *context)
|
|||
break;
|
||||
case 's':
|
||||
/* print to history file */
|
||||
if(!sh_histinit((void*)shp))
|
||||
if(!sh_histinit())
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_system(1),e_history);
|
||||
UNREACHABLE();
|
||||
}
|
||||
fd = sffileno(shp->gd->hist_ptr->histfp);
|
||||
fd = sffileno(sh.hist_ptr->histfp);
|
||||
sh_onstate(SH_HISTORY);
|
||||
sflag++;
|
||||
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);
|
||||
if(*opt_info.arg)
|
||||
fd = -1;
|
||||
else if(!sh_iovalidfd(shp,fd))
|
||||
else if(!sh_iovalidfd(fd))
|
||||
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;
|
||||
break;
|
||||
case 'v':
|
||||
if(argc < 0)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
errormsg(SH_DICT, ERROR_exit(2), e_create, opt_info.arg);
|
||||
|
@ -300,9 +295,9 @@ skip:
|
|||
argv++;
|
||||
if(vname)
|
||||
{
|
||||
if(!shp->strbuf2)
|
||||
shp->strbuf2 = sfstropen();
|
||||
outfile = shp->strbuf2;
|
||||
if(!sh.strbuf2)
|
||||
sh.strbuf2 = sfstropen();
|
||||
outfile = sh.strbuf2;
|
||||
goto printf_v;
|
||||
}
|
||||
skip2:
|
||||
|
@ -311,8 +306,8 @@ skip2:
|
|||
errno = EBADF;
|
||||
n = 0;
|
||||
}
|
||||
else if(!(n=shp->fdstatus[fd]))
|
||||
n = sh_iocheckfd(shp,fd);
|
||||
else if(!(n=sh.fdstatus[fd]))
|
||||
n = sh_iocheckfd(fd);
|
||||
if(!(n&IOWRITE))
|
||||
{
|
||||
/* don't print error message for stdout for compatibility */
|
||||
|
@ -321,13 +316,13 @@ skip2:
|
|||
errormsg(SH_DICT,ERROR_system(1),msg);
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(!(outfile=shp->sftable[fd]))
|
||||
if(!(outfile=sh.sftable[fd]))
|
||||
{
|
||||
sh_onstate(SH_NOTRACK);
|
||||
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);
|
||||
sfpool(outfile,shp->outpool,SF_WRITE);
|
||||
sfpool(outfile,sh.outpool,SF_WRITE);
|
||||
}
|
||||
/* turn off share to guarantee atomic writes for printf */
|
||||
n = sfset(outfile,SF_SHARE|SF_PUBLIC,0);
|
||||
|
@ -338,7 +333,6 @@ printf_v:
|
|||
Sfio_t *pool;
|
||||
struct printf pdata;
|
||||
memset(&pdata, 0, sizeof(pdata));
|
||||
pdata.sh = shp;
|
||||
pdata.hdr.version = SFIO_VERSION;
|
||||
pdata.hdr.extf = extend;
|
||||
pdata.nextarg = argv;
|
||||
|
@ -346,7 +340,7 @@ printf_v:
|
|||
pool=sfpool(sfstderr,NIL(Sfio_t*),SF_WRITE);
|
||||
do
|
||||
{
|
||||
if(shp->trapnote&SH_SIGSET)
|
||||
if(sh.trapnote&SH_SIGSET)
|
||||
break;
|
||||
pdata.hdr.form = format;
|
||||
sfprintf(outfile,"%!",&pdata);
|
||||
|
@ -377,7 +371,7 @@ printf_v:
|
|||
if (sfsync((Sfio_t*)0) < 0)
|
||||
exitval = 1;
|
||||
}
|
||||
else if(sh_echolist(shp,outfile,rflag,argv) && !nflag)
|
||||
else if(echolist(outfile,rflag,argv) && !nflag)
|
||||
if(sfputc(outfile,'\n') < 0)
|
||||
exitval = 1;
|
||||
}
|
||||
|
@ -385,7 +379,7 @@ printf_v:
|
|||
nv_putval(vname, sfstruse(outfile), 0);
|
||||
else if(sflag)
|
||||
{
|
||||
hist_flush(shp->gd->hist_ptr);
|
||||
hist_flush(sh.hist_ptr);
|
||||
sh_offstate(SH_HISTORY);
|
||||
}
|
||||
else
|
||||
|
@ -404,7 +398,7 @@ printf_v:
|
|||
* 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 int n;
|
||||
|
@ -425,7 +419,7 @@ int sh_echolist(Shell_t *shp,Sfio_t *outfile, int raw, char *argv[])
|
|||
if(*argv)
|
||||
if(sfputc(outfile,' ') < 0)
|
||||
exitval = 1;
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
}
|
||||
return(!pdata.cescape);
|
||||
}
|
||||
|
@ -491,10 +485,9 @@ static char *genformat(char *format)
|
|||
{
|
||||
register char *fp;
|
||||
stakseek(0);
|
||||
stakputs(preformat);
|
||||
stakputs(format);
|
||||
fp = (char*)stakfreeze(1);
|
||||
strformat(fp+sizeof(preformat)-1);
|
||||
strformat(fp);
|
||||
return(fp);
|
||||
}
|
||||
|
||||
|
@ -718,7 +711,6 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
|
|||
int fold = fe->base;
|
||||
union types_t* value = (union types_t*)v;
|
||||
struct printf* pp = (struct printf*)fe;
|
||||
Shell_t *shp = pp->sh;
|
||||
register char* argp = *pp->nextarg;
|
||||
char *w,*s;
|
||||
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;
|
||||
if(argp)
|
||||
{
|
||||
sfprintf(pp->sh->strbuf,"%s.%.*s%c",argp,fe->n_str,fe->t_str,0);
|
||||
argp = sfstruse(pp->sh->strbuf);
|
||||
sfprintf(sh.strbuf,"%s.%.*s%c",argp,fe->n_str,fe->t_str,0);
|
||||
argp = sfstruse(sh.strbuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -804,7 +796,7 @@ static int extend(Sfio_t* sp, void* v, Sffmt_t* fe)
|
|||
case 'n':
|
||||
{
|
||||
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_onattr(np,NV_INTEGER);
|
||||
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;
|
||||
case 'B':
|
||||
if(!shp->strbuf2)
|
||||
shp->strbuf2 = sfstropen();
|
||||
fe->size = fmtbase64(shp->strbuf2,value->s, fe->flags&SFFMT_ALTER);
|
||||
value->s = sfstruse(shp->strbuf2);
|
||||
if(!sh.strbuf2)
|
||||
sh.strbuf2 = sfstropen();
|
||||
fe->size = fmtbase64(sh.strbuf2,value->s, fe->flags&SFFMT_ALTER);
|
||||
value->s = sfstruse(sh.strbuf2);
|
||||
fe->flags |= SFFMT_SHORT;
|
||||
break;
|
||||
case 'H':
|
||||
|
|
|
@ -64,9 +64,8 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
|
|||
Sfdouble_t sec;
|
||||
register char *name;
|
||||
register int r, flags=0, fd=0;
|
||||
register Shell_t *shp = context->shp;
|
||||
ssize_t len=0;
|
||||
long timeout = 1000*shp->st.tmout;
|
||||
long timeout = 1000*sh.st.tmout;
|
||||
int save_prompt, fixargs=context->invariant;
|
||||
struct read_save *rp;
|
||||
static char default_prompt[3] = {ESC,ESC};
|
||||
|
@ -108,7 +107,7 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
|
|||
}
|
||||
break;
|
||||
case 'p':
|
||||
if((fd = shp->cpipe[0])<=0)
|
||||
if((fd = sh.cpipe[0])<=0)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_query);
|
||||
UNREACHABLE();
|
||||
|
@ -131,12 +130,12 @@ int b_read(int argc,char *argv[], Shbltin_t *context)
|
|||
break;
|
||||
case 'u':
|
||||
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 */
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(sh_inuse(shp,fd))
|
||||
if(sh_inuse(fd))
|
||||
fd = -1;
|
||||
break;
|
||||
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));
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(!((r=shp->fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
|
||||
r = sh_iocheckfd(shp,fd);
|
||||
if(!((r=sh.fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
|
||||
r = sh_iocheckfd(fd);
|
||||
if(fd<0 || !(r&IOREAD))
|
||||
{
|
||||
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;
|
||||
}
|
||||
bypass:
|
||||
shp->prompt = default_prompt;
|
||||
if(r && (shp->prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR)))
|
||||
sh.prompt = default_prompt;
|
||||
if(r && (sh.prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR)))
|
||||
{
|
||||
memcpy(shp->prompt,name,r);
|
||||
sfwrite(sfstderr,shp->prompt,r-1);
|
||||
memcpy(sh.prompt,name,r);
|
||||
sfwrite(sfstderr,sh.prompt,r-1);
|
||||
}
|
||||
shp->timeout = 0;
|
||||
save_prompt = shp->nextprompt;
|
||||
shp->nextprompt = 0;
|
||||
r=sh_readline(shp,argv,fd,flags,len,timeout);
|
||||
shp->nextprompt = save_prompt;
|
||||
if(r==0 && (r=(sfeof(shp->sftable[fd])||sferror(shp->sftable[fd]))))
|
||||
sh.timeout = 0;
|
||||
save_prompt = sh.nextprompt;
|
||||
sh.nextprompt = 0;
|
||||
r=sh_readline(argv,fd,flags,len,timeout);
|
||||
sh.nextprompt = save_prompt;
|
||||
if(r==0 && (r=(sfeof(sh.sftable[fd])||sferror(sh.sftable[fd]))))
|
||||
{
|
||||
if(fd == shp->cpipe[0] && errno!=EINTR)
|
||||
sh_pclose(shp->cpipe);
|
||||
if(fd == sh.cpipe[0] && errno!=EINTR)
|
||||
sh_pclose(sh.cpipe);
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
@ -216,7 +215,7 @@ static void timedout(void *handle)
|
|||
* <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 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;
|
||||
char inquote = 0;
|
||||
struct checkpt buff;
|
||||
Edit_t *ep = (struct edit*)shp->gd->ed_context;
|
||||
if(!(iop=shp->sftable[fd]) && !(iop=sh_iostream(shp,fd)))
|
||||
Edit_t *ep = (struct edit*)sh.ed_context;
|
||||
if(!(iop=sh.sftable[fd]) && !(iop=sh_iostream(fd)))
|
||||
return(1);
|
||||
sh_stats(STAT_READS);
|
||||
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;
|
||||
if(flags&C_FLAG)
|
||||
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)))
|
||||
np = mp;
|
||||
if((flags&V_FLAG) && shp->gd->ed_context)
|
||||
((struct edit*)shp->gd->ed_context)->e_default = np;
|
||||
if((flags&V_FLAG) && sh.ed_context)
|
||||
((struct edit*)sh.ed_context)->e_default = np;
|
||||
if(flags&A_FLAG)
|
||||
{
|
||||
Namarr_t *ap;
|
||||
|
@ -286,15 +285,15 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
else
|
||||
{
|
||||
name = 0;
|
||||
if(dtvnext(shp->var_tree) || shp->namespace)
|
||||
np = nv_open(nv_name(REPLYNOD),shp->var_tree,0);
|
||||
if(dtvnext(sh.var_tree) || sh.namespace)
|
||||
np = nv_open(nv_name(REPLYNOD),sh.var_tree,0);
|
||||
else
|
||||
np = REPLYNOD;
|
||||
}
|
||||
keytrap = ep?ep->e_keytrap:0;
|
||||
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);
|
||||
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;
|
||||
/* set up state table based on IFS */
|
||||
ifs = nv_getval(mp=sh_scoped(shp,IFSNOD));
|
||||
if((flags&R_FLAG) && shp->ifstable['\\']==S_ESC)
|
||||
shp->ifstable['\\'] = 0;
|
||||
else if(!(flags&R_FLAG) && shp->ifstable['\\']==0)
|
||||
shp->ifstable['\\'] = S_ESC;
|
||||
ifs = nv_getval(mp=sh_scoped(IFSNOD));
|
||||
if((flags&R_FLAG) && sh.ifstable['\\']==S_ESC)
|
||||
sh.ifstable['\\'] = 0;
|
||||
else if(!(flags&R_FLAG) && sh.ifstable['\\']==0)
|
||||
sh.ifstable['\\'] = S_ESC;
|
||||
if(delim>0)
|
||||
shp->ifstable[delim] = S_NL;
|
||||
sh.ifstable[delim] = S_NL;
|
||||
if(delim!='\n')
|
||||
{
|
||||
shp->ifstable['\n'] = 0;
|
||||
sh.ifstable['\n'] = 0;
|
||||
nv_putval(mp, ifs, NV_RDONLY);
|
||||
}
|
||||
shp->ifstable[0] = S_EOF;
|
||||
sh.ifstable[0] = S_EOF;
|
||||
if((flags&SS_FLAG))
|
||||
{
|
||||
shp->ifstable['"'] = S_QUOTE;
|
||||
shp->ifstable['\r'] = S_ERR;
|
||||
sh.ifstable['"'] = S_QUOTE;
|
||||
sh.ifstable['\r'] = S_ERR;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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;
|
||||
if(fd==0)
|
||||
was_share = (sfset(iop,SF_SHARE,shp->redir0!=2)&SF_SHARE)!=0;
|
||||
if(timeout || (shp->fdstatus[fd]&(IOTTY|IONOSEEK)))
|
||||
was_share = (sfset(iop,SF_SHARE,sh.redir0!=2)&SF_SHARE)!=0;
|
||||
if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
|
||||
{
|
||||
sh_pushcontext(shp,&buff,1);
|
||||
sh_pushcontext(&sh,&buff,1);
|
||||
jmpval = sigsetjmp(buff.buff,0);
|
||||
if(jmpval)
|
||||
goto done;
|
||||
|
@ -504,10 +503,10 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
}
|
||||
if(timeslot)
|
||||
timerdel(timeslot);
|
||||
if((flags&S_FLAG) && !shp->gd->hist_ptr)
|
||||
if((flags&S_FLAG) && !sh.hist_ptr)
|
||||
{
|
||||
sh_histinit((void*)shp);
|
||||
if(!shp->gd->hist_ptr)
|
||||
sh_histinit();
|
||||
if(!sh.hist_ptr)
|
||||
flags &= ~S_FLAG;
|
||||
}
|
||||
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)
|
||||
*(cpmax-1) = delim;
|
||||
if(flags&S_FLAG)
|
||||
sfwrite(shp->gd->hist_ptr->histfp,(char*)cp,c);
|
||||
c = shp->ifstable[*cp++];
|
||||
sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
|
||||
c = sh.ifstable[*cp++];
|
||||
#if !SHOPT_MULTIBYTE
|
||||
if(!name && (flags&R_FLAG)) /* special case single argument */
|
||||
{
|
||||
/* skip over leading blanks */
|
||||
while(c==S_SPACE)
|
||||
c = shp->ifstable[*cp++];
|
||||
c = sh.ifstable[*cp++];
|
||||
/* strip trailing delimiters */
|
||||
if(cpmax[-1] == '\n')
|
||||
cpmax--;
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -551,7 +550,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
}
|
||||
else
|
||||
c = S_NL;
|
||||
shp->nextprompt = 2;
|
||||
sh.nextprompt = 2;
|
||||
rel= staktell();
|
||||
mbinit();
|
||||
/* 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;
|
||||
#endif /* SHOPT_MULTIBYTE */
|
||||
case S_QUOTE:
|
||||
c = shp->ifstable[*cp++];
|
||||
c = sh.ifstable[*cp++];
|
||||
if(inquote && c==S_QUOTE)
|
||||
c = -1;
|
||||
else
|
||||
|
@ -594,12 +593,12 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
if(c==-1)
|
||||
{
|
||||
stakputc('"');
|
||||
c = shp->ifstable[*cp++];
|
||||
c = sh.ifstable[*cp++];
|
||||
}
|
||||
continue;
|
||||
case S_ESC:
|
||||
/* process escape character */
|
||||
if((c = shp->ifstable[*cp++]) == S_NL)
|
||||
if((c = sh.ifstable[*cp++]) == S_NL)
|
||||
was_escape = 1;
|
||||
else
|
||||
c = 0;
|
||||
|
@ -629,7 +628,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
break;
|
||||
}
|
||||
/* eliminate null bytes */
|
||||
c = shp->ifstable[*cp++];
|
||||
c = sh.ifstable[*cp++];
|
||||
if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE))
|
||||
c = 0;
|
||||
continue;
|
||||
|
@ -644,9 +643,9 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
if(cp)
|
||||
{
|
||||
if(flags&S_FLAG)
|
||||
sfwrite(shp->gd->hist_ptr->histfp,(char*)cp,c);
|
||||
sfwrite(sh.hist_ptr->histfp,(char*)cp,c);
|
||||
cpmax = cp + c;
|
||||
c = shp->ifstable[*cp++];
|
||||
c = sh.ifstable[*cp++];
|
||||
val=0;
|
||||
if(!name && (c==S_SPACE || c==S_DELIM || c==S_MBYTE))
|
||||
c = 0;
|
||||
|
@ -658,7 +657,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
|
||||
case S_SPACE:
|
||||
/* skip over blanks */
|
||||
while((c=shp->ifstable[*cp++])==S_SPACE);
|
||||
while((c=sh.ifstable[*cp++])==S_SPACE);
|
||||
if(!val)
|
||||
continue;
|
||||
#if SHOPT_MULTIBYTE
|
||||
|
@ -684,7 +683,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
if(name)
|
||||
{
|
||||
/* skip over trailing blanks */
|
||||
while((c=shp->ifstable[*cp++])==S_SPACE);
|
||||
while((c=sh.ifstable[*cp++])==S_SPACE);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
@ -702,7 +701,7 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
cp += mbsz - 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 */
|
||||
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(shp->ifstable[*cp]==S_QUOTE)
|
||||
if(sh.ifstable[*cp]==S_QUOTE)
|
||||
{
|
||||
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 */
|
||||
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==(unsigned char*)val)
|
||||
vp--;
|
||||
else
|
||||
while(shp->ifstable[*--vp]==S_SPACE);
|
||||
while(sh.ifstable[*--vp]==S_SPACE);
|
||||
}
|
||||
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))
|
||||
{
|
||||
nv_onattr(np,NV_EXPORT);
|
||||
sh_envput(shp->env,np);
|
||||
sh_envput(sh.env,np);
|
||||
}
|
||||
if(name)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -829,18 +828,18 @@ int sh_readline(register Shell_t *shp,char **names, volatile int fd, int flags,s
|
|||
}
|
||||
}
|
||||
done:
|
||||
if(timeout || (shp->fdstatus[fd]&(IOTTY|IONOSEEK)))
|
||||
sh_popcontext(shp,&buff);
|
||||
if(timeout || (sh.fdstatus[fd]&(IOTTY|IONOSEEK)))
|
||||
sh_popcontext(&sh,&buff);
|
||||
if(was_write)
|
||||
sfset(iop,SF_WRITE,1);
|
||||
if(!was_share)
|
||||
sfset(iop,SF_SHARE,0);
|
||||
nv_close(np);
|
||||
if((shp->fdstatus[fd]&IOTTY) && !keytrap)
|
||||
if((sh.fdstatus[fd]&IOTTY) && !keytrap)
|
||||
tty_cooked(fd);
|
||||
if(flags&S_FLAG)
|
||||
hist_flush(shp->gd->hist_ptr);
|
||||
hist_flush(sh.hist_ptr);
|
||||
if(jmpval > 1)
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
return(jmpval);
|
||||
}
|
||||
|
|
|
@ -122,11 +122,11 @@ static const char* regress_options[] =
|
|||
"etc",
|
||||
};
|
||||
|
||||
void sh_regress_init(Shell_t* shp)
|
||||
void sh_regress_init(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
register Shell_t* shp = context->shp;
|
||||
int n;
|
||||
|
||||
for (;;)
|
||||
|
|
|
@ -38,11 +38,11 @@ int b_sleep(register int argc,char *argv[],Shbltin_t *context)
|
|||
{
|
||||
register char *cp;
|
||||
register double d=0;
|
||||
register Shell_t *shp = context->shp;
|
||||
int sflag=0;
|
||||
time_t tloc = 0;
|
||||
char *last;
|
||||
if(!(shp->sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
|
||||
NOT_USED(context);
|
||||
if(!(sh.sigflag[SIGALRM]&(SH_SIGFAULT|SH_SIGOFF)))
|
||||
sh_sigtrap(SIGALRM);
|
||||
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;
|
||||
if(*cp == 'P' || *cp == 'p')
|
||||
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) = ',';
|
||||
if(!strchr(cp,'.'))
|
||||
|
@ -120,16 +120,16 @@ skip:
|
|||
{
|
||||
time_t now;
|
||||
errno = 0;
|
||||
shp->lastsig=0;
|
||||
sh.lastsig=0;
|
||||
sh_delay(d,sflag);
|
||||
if(sflag || tloc==0 || errno!=EINTR || shp->lastsig)
|
||||
if(sflag || tloc==0 || errno!=EINTR || sh.lastsig)
|
||||
break;
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
if(tloc < (now=time(NIL(time_t*))))
|
||||
break;
|
||||
d = (double)(tloc-now);
|
||||
if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
sh_timetraps(shp);
|
||||
if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
sh_timetraps();
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
@ -141,7 +141,6 @@ skip:
|
|||
*/
|
||||
void sh_delay(double t, int sflag)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
int n = (int)t;
|
||||
Tv_t ts, tx;
|
||||
|
||||
|
@ -149,7 +148,7 @@ void sh_delay(double t, int sflag)
|
|||
ts.tv_nsec = 1000000000 * (t - (double)n);
|
||||
while(tvsleep(&ts, &tx) < 0)
|
||||
{
|
||||
if ((shp->trapnote & (SH_SIGSET | SH_SIGTRAP)) || sflag)
|
||||
if ((sh.trapnote & (SH_SIGSET | SH_SIGTRAP)) || sflag)
|
||||
return;
|
||||
ts = tx;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@ static int test_mode(const char*);
|
|||
|
||||
struct test
|
||||
{
|
||||
Shell_t *sh;
|
||||
int ap;
|
||||
int ac;
|
||||
char **av;
|
||||
|
@ -82,7 +81,7 @@ static char *nxtarg(struct test*,int);
|
|||
static int expr(struct test*,int);
|
||||
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;
|
||||
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)
|
||||
match[1] = strlen(str);
|
||||
if(n)
|
||||
sh_setmatch(shp, str, -1, n, match, 0);
|
||||
sh_setmatch(str, -1, n, match, 0);
|
||||
return(n);
|
||||
}
|
||||
|
||||
|
@ -115,7 +114,6 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
|
|||
register int not;
|
||||
int exitval;
|
||||
|
||||
tdata.sh = context->shp;
|
||||
tdata.av = argv;
|
||||
tdata.ap = 1;
|
||||
if(c_eq(cp,'['))
|
||||
|
@ -164,12 +162,12 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
|
|||
break;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
case 3:
|
||||
|
@ -209,7 +207,7 @@ int b_test(int argc, char *argv[],Shbltin_t *context)
|
|||
}
|
||||
break;
|
||||
}
|
||||
exitval = (!test_unop(tdata.sh,cp[1],argv[2]));
|
||||
exitval = (!test_unop(cp[1],argv[2]));
|
||||
goto done;
|
||||
case 2:
|
||||
exitval = (*cp==0);
|
||||
|
@ -346,7 +344,7 @@ static int e3(struct test *tp)
|
|||
UNREACHABLE();
|
||||
}
|
||||
if(strchr(test_opchars,op))
|
||||
return(test_unop(tp->sh,op,cp));
|
||||
return(test_unop(op,cp));
|
||||
}
|
||||
if(!cp)
|
||||
{
|
||||
|
@ -364,10 +362,10 @@ skip:
|
|||
}
|
||||
if(op==TEST_AND || op==TEST_OR)
|
||||
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;
|
||||
int f;
|
||||
|
@ -449,8 +447,8 @@ int test_unop(Shell_t *shp,register int op,register const char *arg)
|
|||
if(op=='s')
|
||||
return(statb.st_size>0);
|
||||
else if(op=='O')
|
||||
return(statb.st_uid==shp->gd->userid);
|
||||
return(statb.st_gid==shp->gd->groupid);
|
||||
return(statb.st_uid==sh.userid);
|
||||
return(statb.st_gid==sh.groupid);
|
||||
case 'a':
|
||||
case 'e':
|
||||
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;
|
||||
Namarr_t *ap;
|
||||
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);
|
||||
isref = nv_isref(np);
|
||||
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
|
||||
* 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;
|
||||
if(op&TEST_ARITH)
|
||||
|
@ -514,8 +512,8 @@ int test_binop(Shell_t *shp,register int op,const char *left,const char *right)
|
|||
left++;
|
||||
while(*right=='0')
|
||||
right++;
|
||||
lnum = sh_arith(shp,left);
|
||||
rnum = sh_arith(shp,right);
|
||||
lnum = sh_arith(left);
|
||||
rnum = sh_arith(right);
|
||||
}
|
||||
switch(op)
|
||||
{
|
||||
|
@ -523,9 +521,9 @@ int test_binop(Shell_t *shp,register int op,const char *left,const char *right)
|
|||
case TEST_OR:
|
||||
return(*left!=0);
|
||||
case TEST_PEQ:
|
||||
return(test_strmatch(shp, left, right));
|
||||
return(test_strmatch(left, right));
|
||||
case TEST_PNE:
|
||||
return(!test_strmatch(shp, left, right));
|
||||
return(!test_strmatch(left, right));
|
||||
case TEST_SGT:
|
||||
return(strcoll(left, right)>0);
|
||||
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:
|
||||
return(strcmp(left, right)!=0);
|
||||
case TEST_REP:
|
||||
sfprintf(stkstd, "~(E)%s", right);
|
||||
return(test_strmatch(shp, left, stkfreeze(stkstd, 1))>0);
|
||||
sfprintf(sh.strbuf, "~(E)%s", right);
|
||||
return(test_strmatch(left, sfstruse(sh.strbuf))>0);
|
||||
case TEST_EF:
|
||||
return(test_inode(left,right));
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
struct stat statb;
|
||||
if(*name==0)
|
||||
return(-1);
|
||||
if(sh_isdevfd(name))
|
||||
return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode));
|
||||
/* 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;
|
||||
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));
|
||||
#ifdef _lib_setreuid
|
||||
/* swap the real uid to effective, check access then restore */
|
||||
/* 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 */
|
||||
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);
|
||||
/* restore ids */
|
||||
if(shp->gd->userid!=shp->gd->euserid)
|
||||
setreuid(shp->gd->userid,shp->gd->euserid);
|
||||
if(shp->gd->groupid!=shp->gd->egroupid)
|
||||
setregid(shp->gd->groupid,shp->gd->egroupid);
|
||||
if(sh.userid!=sh.euserid)
|
||||
setreuid(sh.userid,sh.euserid);
|
||||
if(sh.groupid!=sh.egroupid)
|
||||
setregid(sh.groupid,sh.egroupid);
|
||||
return(mode);
|
||||
}
|
||||
else if(shp->gd->groupid!=shp->gd->egroupid)
|
||||
setregid(shp->gd->groupid,shp->gd->egroupid);
|
||||
else if(sh.groupid!=sh.egroupid)
|
||||
setregid(sh.groupid,sh.egroupid);
|
||||
}
|
||||
#endif /* _lib_setreuid */
|
||||
skip:
|
||||
|
@ -639,16 +636,16 @@ skip:
|
|||
{
|
||||
if(mode == F_OK)
|
||||
return(mode);
|
||||
else if(shp->gd->euserid == 0)
|
||||
else if(sh.euserid == 0)
|
||||
{
|
||||
if(!S_ISREG(statb.st_mode) || mode!=X_OK)
|
||||
return(0);
|
||||
/* root needs execute permission for someone */
|
||||
mode = (S_IXUSR|S_IXGRP|S_IXOTH);
|
||||
}
|
||||
else if(shp->gd->euserid == statb.st_uid)
|
||||
else if(sh.euserid == statb.st_uid)
|
||||
mode <<= 6;
|
||||
else if(shp->gd->egroupid == statb.st_gid)
|
||||
else if(sh.egroupid == statb.st_gid)
|
||||
mode <<= 3;
|
||||
#ifdef _lib_getgroups
|
||||
/* on some systems you can be in several groups */
|
||||
|
|
|
@ -40,14 +40,13 @@
|
|||
|
||||
static const char trapfmt[] = "trap -- %s %s\n";
|
||||
|
||||
static int sig_number(Shell_t*,const char*);
|
||||
static void sig_list(Shell_t*,int);
|
||||
static int sig_number(const char*);
|
||||
static void sig_list(int);
|
||||
|
||||
int b_trap(int argc,char *argv[],Shbltin_t *context)
|
||||
{
|
||||
register char *arg = argv[1];
|
||||
register int sig, clear = 0, dflag = 0, pflag = 0;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(argc);
|
||||
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
|
||||
* 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++;
|
||||
dflag++;
|
||||
|
@ -100,7 +99,7 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
|
|||
}
|
||||
while(arg = *argv++)
|
||||
{
|
||||
sig = sig_number(shp,arg);
|
||||
sig = sig_number(arg);
|
||||
if(sig<0)
|
||||
{
|
||||
errormsg(SH_DICT,2,e_trap,arg);
|
||||
|
@ -109,7 +108,7 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
|
|||
/* internal traps */
|
||||
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;
|
||||
if(sig>SH_DEBUGTRAP)
|
||||
{
|
||||
|
@ -122,37 +121,37 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
|
|||
sfputr(sfstdout,sh_fmtq(arg),'\n');
|
||||
continue;
|
||||
}
|
||||
shp->st.otrap = 0;
|
||||
if(shp->st.trap[sig])
|
||||
free(shp->st.trap[sig]);
|
||||
shp->st.trap[sig] = 0;
|
||||
sh.st.otrap = 0;
|
||||
if(sh.st.trap[sig])
|
||||
free(sh.st.trap[sig]);
|
||||
sh.st.trap[sig] = 0;
|
||||
if(!clear && *action)
|
||||
shp->st.trap[sig] = sh_strdup(action);
|
||||
sh.st.trap[sig] = sh_strdup(action);
|
||||
if(sig == SH_DEBUGTRAP)
|
||||
{
|
||||
if(shp->st.trap[sig])
|
||||
shp->trapnote |= SH_SIGTRAP;
|
||||
if(sh.st.trap[sig])
|
||||
sh.trapnote |= SH_SIGTRAP;
|
||||
else
|
||||
shp->trapnote = 0;
|
||||
sh.trapnote = 0;
|
||||
|
||||
}
|
||||
if(sig == SH_ERRTRAP)
|
||||
{
|
||||
if(clear)
|
||||
shp->errtrap = 0;
|
||||
else if(!shp->fn_depth || shp->end_fn)
|
||||
shp->errtrap = 1;
|
||||
sh.errtrap = 0;
|
||||
else if(!sh.fn_depth || sh.end_fn)
|
||||
sh.errtrap = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(sig>shp->gd->sigmax)
|
||||
if(sig > sh.sigmax)
|
||||
{
|
||||
errormsg(SH_DICT,2,e_trap,arg);
|
||||
return(1);
|
||||
}
|
||||
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])
|
||||
sfputr(sfstdout,arg,'\n');
|
||||
}
|
||||
|
@ -160,26 +159,26 @@ int b_trap(int argc,char *argv[],Shbltin_t *context)
|
|||
{
|
||||
sh_sigclear(sig);
|
||||
if(sig == 0)
|
||||
shp->exittrap = 0;
|
||||
sh.exittrap = 0;
|
||||
if(dflag)
|
||||
signal(sig,SIG_DFL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sig >= shp->st.trapmax)
|
||||
shp->st.trapmax = sig+1;
|
||||
arg = shp->st.trapcom[sig];
|
||||
if(sig >= sh.st.trapmax)
|
||||
sh.st.trapmax = sig+1;
|
||||
arg = sh.st.trapcom[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)
|
||||
free(arg);
|
||||
if(sig == 0 && (!shp->fn_depth || shp->end_fn))
|
||||
shp->exittrap = 1;
|
||||
if(sig == 0 && (!sh.fn_depth || sh.end_fn))
|
||||
sh.exittrap = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* print out current traps */
|
||||
sig_list(shp,-2);
|
||||
sig_list(-2);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -191,7 +190,6 @@ int b_kill(int argc,char *argv[],Shbltin_t *context)
|
|||
{
|
||||
register char *signame;
|
||||
register int sig=SIGTERM, flag=0, n;
|
||||
register Shell_t *shp = context->shp;
|
||||
int usemenu = 0;
|
||||
NOT_USED(argc);
|
||||
#if defined(JOBS) && defined(SIGSTOP)
|
||||
|
@ -206,7 +204,7 @@ int b_kill(int argc,char *argv[],Shbltin_t *context)
|
|||
#endif /* defined(JOBS) && defined(SIGSTOP) */
|
||||
{
|
||||
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;
|
||||
opt_info.index--;
|
||||
errormsg(SH_DICT,2, "%s", opt_info.arg);
|
||||
|
@ -242,35 +240,35 @@ endopts:
|
|||
if(flag&L_FLAG)
|
||||
{
|
||||
if(!(*argv))
|
||||
sig_list(shp,usemenu);
|
||||
sig_list(usemenu);
|
||||
else while(signame = *argv++)
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
sfprintf(sfstdout,"%d\n",sig);
|
||||
}
|
||||
}
|
||||
return(shp->exitval);
|
||||
return(sh.exitval);
|
||||
}
|
||||
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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if(job_walk(sfstdout,job_kill,sig,argv))
|
||||
shp->exitval = 1;
|
||||
return(shp->exitval);
|
||||
sh.exitval = 1;
|
||||
return(sh.exitval);
|
||||
}
|
||||
|
||||
#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");
|
||||
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();
|
||||
}
|
||||
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
|
||||
*/
|
||||
|
||||
static int sig_number(Shell_t *shp,const char *string)
|
||||
static int sig_number(const char *string)
|
||||
{
|
||||
const Shtable_t *tp;
|
||||
register int n,o,sig=0;
|
||||
|
@ -365,29 +363,29 @@ static int sig_number(Shell_t *shp,const char *string)
|
|||
n = tp->sh_number;
|
||||
}
|
||||
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
|
||||
{
|
||||
n &= (1<<SH_SIGBITS)-1;
|
||||
if(n < SH_TRAP)
|
||||
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 */
|
||||
if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+') /* MIN+ */
|
||||
{
|
||||
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- */
|
||||
{
|
||||
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)
|
||||
n = shp->gd->sigruntime[SH_SIGRTMIN] + sig - 1;
|
||||
if(n<shp->gd->sigruntime[SH_SIGRTMIN] || n>shp->gd->sigruntime[SH_SIGRTMAX])
|
||||
n = sh.sigruntime[SH_SIGRTMIN] + sig - 1;
|
||||
if(n < sh.sigruntime[SH_SIGRTMIN] || n > sh.sigruntime[SH_SIGRTMAX])
|
||||
n = -1;
|
||||
}
|
||||
}
|
||||
|
@ -398,29 +396,29 @@ static int sig_number(Shell_t *shp,const char *string)
|
|||
* synthesize signal name for sig in buf
|
||||
* 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;
|
||||
|
||||
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++] = 'T';
|
||||
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++] = 'X';
|
||||
buf[i++] = '-';
|
||||
sig = shp->gd->sigruntime[SH_SIGRTMAX]-sig;
|
||||
sig = sh.sigruntime[SH_SIGRTMAX] - sig;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i++] = 'I';
|
||||
buf[i++] = 'N';
|
||||
buf[i++] = '+';
|
||||
sig = sig-shp->gd->sigruntime[SH_SIGRTMIN];
|
||||
sig = sig - sh.sigruntime[SH_SIGRTMIN];
|
||||
}
|
||||
}
|
||||
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 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 int sig;
|
||||
|
@ -452,7 +450,7 @@ static void sig_list(register Shell_t *shp,register int flag)
|
|||
if(flag<=0)
|
||||
{
|
||||
/* 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;
|
||||
for(sig=SH_DEBUGTRAP; sig>=0; sig--)
|
||||
traps[sig] = 0;
|
||||
|
@ -460,7 +458,7 @@ static void sig_list(register Shell_t *shp,register int flag)
|
|||
for(; *tp->sh_name; tp++)
|
||||
{
|
||||
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;
|
||||
if(sig==flag)
|
||||
{
|
||||
|
@ -473,25 +471,25 @@ static void sig_list(register Shell_t *shp,register int flag)
|
|||
names[sig] = (char*)tp->sh_name;
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* print the traps */
|
||||
register char *trap,**trapcom;
|
||||
sig = shp->st.trapmax;
|
||||
sig = sh.st.trapmax;
|
||||
/* 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)
|
||||
{
|
||||
if(!(trap=trapcom[sig]))
|
||||
continue;
|
||||
if(sig > shp->gd->sigmax || !(sname=(char*)names[sig]))
|
||||
sname = sig_name(shp,sig,name,1);
|
||||
if(sig > sh.sigmax || !(sname=(char*)names[sig]))
|
||||
sname = sig_name(sig,name,1);
|
||||
sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
|
||||
}
|
||||
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;
|
||||
sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
|
||||
}
|
||||
|
@ -499,11 +497,11 @@ static void sig_list(register Shell_t *shp,register int flag)
|
|||
else
|
||||
{
|
||||
/* 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]))
|
||||
{
|
||||
sname = sig_name(shp,sig,name,1);
|
||||
sname = sig_name(sig,name,1);
|
||||
if(flag)
|
||||
sname = stakcopy(sname);
|
||||
}
|
||||
|
@ -515,7 +513,7 @@ static void sig_list(register Shell_t *shp,register int flag)
|
|||
if(flag)
|
||||
{
|
||||
names[sig] = 0;
|
||||
sh_menu(sfstdout,shp->gd->sigmax,(char**)names+1);
|
||||
sh_menu(sfstdout,sh.sigmax,(char**)names+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,12 @@
|
|||
#include "variables.h"
|
||||
#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
|
||||
{
|
||||
Shell_t *sh;
|
||||
Namval_t *tp;
|
||||
const char *wctname;
|
||||
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_all(Sfio_t*, Dt_t*, 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 void pushname(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;
|
||||
NOT_USED(argc);
|
||||
memset((void*)&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
tdata.aflag = '-';
|
||||
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);
|
||||
else
|
||||
flag = (NV_ASSIGN|NV_EXPORT|NV_IDENT);
|
||||
if(!tdata.sh->prefix)
|
||||
tdata.sh->prefix = "";
|
||||
return(setall(argv,flag,tdata.sh->var_tree, &tdata));
|
||||
if(!sh.prefix)
|
||||
sh.prefix = Empty;
|
||||
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;
|
||||
NOT_USED(argc);
|
||||
memset((void*)&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
troot = tdata.sh->alias_tree;
|
||||
troot = sh.alias_tree;
|
||||
if(*argv[0]=='h')
|
||||
flag |= NV_TAGGED;
|
||||
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 */
|
||||
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 */
|
||||
if(xflag && (flag&NV_TAGGED))
|
||||
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;
|
||||
|
||||
memset((void*)&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
troot = tdata.sh->var_tree;
|
||||
troot = sh.var_tree;
|
||||
if(ntp) /* custom declaration command added using enum */
|
||||
{
|
||||
tdata.tp = ntp->tp;
|
||||
|
@ -359,7 +359,7 @@ int b_typeset(int argc,register char *argv[],Shbltin_t *context)
|
|||
break;
|
||||
case 'f':
|
||||
flag &= ~(NV_VARNAME|NV_ASSIGN);
|
||||
troot = tdata.sh->fun_tree;
|
||||
troot = sh.fun_tree;
|
||||
break;
|
||||
case 'i':
|
||||
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");
|
||||
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");
|
||||
error_info.errors++;
|
||||
}
|
||||
if(sflag && troot==tdata.sh->fun_tree)
|
||||
if(sflag && troot==sh.fun_tree)
|
||||
{
|
||||
/* static function */
|
||||
sflag = 0;
|
||||
|
@ -497,39 +497,39 @@ endargs:
|
|||
flag |= NV_DOUBLE;
|
||||
if(sflag)
|
||||
{
|
||||
if(tdata.sh->mktype)
|
||||
if(sh.mktype)
|
||||
flag |= NV_REF|NV_TAGGED;
|
||||
else if(!tdata.sh->typeinit)
|
||||
else if(!sh.typeinit)
|
||||
flag |= NV_STATIC|NV_IDENT;
|
||||
}
|
||||
if(tdata.sh->fn_depth && !tdata.pflag)
|
||||
if(sh.fn_depth && !tdata.pflag)
|
||||
flag |= NV_NOSCOPE;
|
||||
if(tdata.help)
|
||||
tdata.help = sh_strdup(tdata.help);
|
||||
if(flag&NV_TYPE)
|
||||
{
|
||||
Stk_t *stkp = tdata.sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
int off=0,offset = stktell(stkp);
|
||||
if(!tdata.prefix)
|
||||
return(sh_outtype(tdata.sh,sfstdout));
|
||||
return(sh_outtype(sfstdout));
|
||||
sfputr(stkp,NV_CLASS,-1);
|
||||
#if SHOPT_NAMESPACE
|
||||
if(tdata.sh->namespace)
|
||||
if(sh.namespace)
|
||||
{
|
||||
off = stktell(stkp)+1;
|
||||
sfputr(stkp,nv_name(tdata.sh->namespace),'.');
|
||||
sfputr(stkp,nv_name(sh.namespace),'.');
|
||||
}
|
||||
else
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
if(NV_CLASS[sizeof(NV_CLASS)-2]!='.')
|
||||
sfputc(stkp,'.');
|
||||
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(!tdata.tp && off)
|
||||
{
|
||||
*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 */
|
||||
stkseek(stkp,offset);
|
||||
|
@ -550,7 +550,7 @@ endargs:
|
|||
}
|
||||
else if(tdata.aflag==0 && ntp && ntp->tp)
|
||||
tdata.aflag = '-';
|
||||
if(!tdata.sh->mktype)
|
||||
if(!sh.mktype)
|
||||
tdata.help = 0;
|
||||
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))
|
||||
{
|
||||
Dt_t *root = tp->sh->last_root;
|
||||
Namval_t *nsp = tp->sh->namespace;
|
||||
Dt_t *root = sh.last_root;
|
||||
Namval_t *nsp = sh.namespace;
|
||||
char *cp;
|
||||
if(!tp->pflag)
|
||||
return;
|
||||
|
@ -589,20 +589,20 @@ static void print_value(Sfio_t *iop, Namval_t *np, struct tdata *tp)
|
|||
sfprintf(iop,"{\n", name);
|
||||
tp->indent++;
|
||||
/* output types from namespace */
|
||||
tp->sh->namespace = 0;
|
||||
tp->sh->prefix = nv_name(np)+1;
|
||||
sh_outtype(tp->sh,iop);
|
||||
tp->sh->prefix = 0;
|
||||
tp->sh->namespace = np;
|
||||
tp->sh->last_root = root;
|
||||
sh.namespace = 0;
|
||||
sh.prefix = nv_name(np)+1;
|
||||
sh_outtype(iop);
|
||||
sh.prefix = 0;
|
||||
sh.namespace = np;
|
||||
sh.last_root = root;
|
||||
/* output variables from namespace */
|
||||
print_scan(iop,NV_NOSCOPE,nv_dict(np),aflag=='+',tp);
|
||||
tp->wctname = cp;
|
||||
tp->sh->namespace = 0;
|
||||
sh.namespace = 0;
|
||||
/* 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->sh->namespace = nsp;
|
||||
sh.namespace = nsp;
|
||||
if(--tp->indent)
|
||||
sfnputc(iop,'\t',tp->indent);
|
||||
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))
|
||||
sfprintf(iop,"%s ", tp->prefix);
|
||||
table = tp->sh->last_table;
|
||||
table = sh.last_table;
|
||||
sfputr(iop,nv_name(np),aflag=='+'?'\n':'=');
|
||||
tp->sh->last_table = table;
|
||||
sh.last_table = table;
|
||||
if(aflag=='+')
|
||||
return;
|
||||
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;
|
||||
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);
|
||||
Shell_t *shp =tp->sh;
|
||||
if(!shp->prefix)
|
||||
if(!sh.prefix)
|
||||
{
|
||||
if(!tp->pflag)
|
||||
nvflags |= NV_NOSCOPE;
|
||||
}
|
||||
else if(*shp->prefix==0)
|
||||
shp->prefix = 0;
|
||||
else if(*sh.prefix==0)
|
||||
sh.prefix = 0;
|
||||
if(*argv[0]=='+')
|
||||
nvflags |= NV_NOADD;
|
||||
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;
|
||||
Namval_t *mp;
|
||||
unsigned curflag;
|
||||
if(troot == shp->fun_tree)
|
||||
if(troot == sh.fun_tree)
|
||||
{
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
/* 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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
#if SHOPT_NAMESPACE
|
||||
if(shp->namespace)
|
||||
np = sh_fsearch(shp,name,NV_ADD|HASH_NOSCOPE);
|
||||
if(sh.namespace)
|
||||
np = sh_fsearch(name,NV_ADD|HASH_NOSCOPE);
|
||||
else
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(shp->prefix)
|
||||
if(sh.prefix)
|
||||
{
|
||||
sfprintf(shp->strbuf,"%s.%s%c",shp->prefix,name,0);
|
||||
name = sfstruse(shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%s.%s%c",sh.prefix,name,0);
|
||||
name = sfstruse(sh.strbuf);
|
||||
}
|
||||
#if SHOPT_NAMESPACE
|
||||
np = 0;
|
||||
if(shp->namespace)
|
||||
np = sh_fsearch(shp,name,HASH_NOSCOPE);
|
||||
if(sh.namespace)
|
||||
np = sh_fsearch(name,HASH_NOSCOPE);
|
||||
if(!np)
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
if(shp->subshell && !shp->subshare)
|
||||
if(sh.subshell && !sh.subshare)
|
||||
sh_subfork();
|
||||
if(tp->aflag=='-')
|
||||
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++;
|
||||
if(tp->help)
|
||||
{
|
||||
int offset = stktell(shp->stk);
|
||||
int offset = stktell(sh.stk);
|
||||
if(!np)
|
||||
{
|
||||
sfputr(shp->stk,shp->prefix,'.');
|
||||
sfputr(shp->stk,name,0);
|
||||
np = nv_search(stkptr(shp->stk,offset),troot,0);
|
||||
stkseek(shp->stk,offset);
|
||||
sfputr(sh.stk,sh.prefix,'.');
|
||||
sfputr(sh.stk,name,0);
|
||||
np = nv_search(stkptr(sh.stk,offset),troot,0);
|
||||
stkseek(sh.stk,offset);
|
||||
}
|
||||
if(np && np->nvalue.cp)
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
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(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)
|
||||
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)
|
||||
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
|
||||
|
@ -861,7 +860,7 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
|
|||
flag &= ~NV_ASSIGN;
|
||||
if(last=strchr(name,'='))
|
||||
*last = 0;
|
||||
if (shp->typeinit)
|
||||
if (sh.typeinit)
|
||||
continue;
|
||||
curflag = np->nvflag;
|
||||
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;
|
||||
if (tp->aflag && (tp->argnum || (curflag!=newflag)))
|
||||
{
|
||||
if(shp->subshell)
|
||||
if(sh.subshell)
|
||||
sh_assignok(np,2);
|
||||
if(troot!=shp->var_tree)
|
||||
if(troot!=sh.var_tree)
|
||||
nv_setattr(np,newflag&~NV_ASSIGN);
|
||||
else
|
||||
{
|
||||
|
@ -946,12 +945,12 @@ static int setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp
|
|||
if(tp->aflag=='-')
|
||||
{
|
||||
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))
|
||||
hp = dtvnext(shp->var_tree);
|
||||
if(!(hp=(Dt_t*)sh.st.prevst->save_tree))
|
||||
hp = dtvnext(sh.var_tree);
|
||||
}
|
||||
if(tp->sh->mktype)
|
||||
if(sh.mktype)
|
||||
nv_onattr(np,NV_REF|NV_FUNCT);
|
||||
else
|
||||
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
|
||||
{
|
||||
if(shp->prefix)
|
||||
errormsg(SH_DICT,2, e_subcomvar,shp->prefix);
|
||||
if(sh.prefix)
|
||||
errormsg(SH_DICT,2, e_subcomvar,sh.prefix);
|
||||
if(tp->aflag)
|
||||
{
|
||||
if(troot==shp->fun_tree)
|
||||
if(troot==sh.fun_tree)
|
||||
{
|
||||
flag |= NV_FUNCTION;
|
||||
tp->prefix = 0;
|
||||
}
|
||||
else if(troot==shp->var_tree)
|
||||
else if(troot==sh.var_tree)
|
||||
{
|
||||
flag |= (nvflags&NV_ARRAY);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else if(troot==shp->alias_tree)
|
||||
else if(troot==sh.alias_tree)
|
||||
print_scan(sfstdout,0,troot,0,tp);
|
||||
else
|
||||
print_all(sfstdout,troot,tp);
|
||||
|
@ -1029,12 +1028,12 @@ static int maxlib;
|
|||
* 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 r;
|
||||
Libinit_f initfn;
|
||||
Shbltin_t *sp = &shp->bltindata;
|
||||
Shbltin_t *sp = &sh.bltindata;
|
||||
|
||||
sp->nosfio = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
Shbltin_f sh_getlib(Shell_t* shp, char* sym, Pathcomp_t* pp)
|
||||
Shbltin_f sh_getlib(char* sym, Pathcomp_t* pp)
|
||||
{
|
||||
register int n;
|
||||
|
||||
|
@ -1076,18 +1075,6 @@ Shbltin_f sh_getlib(Shell_t* shp, char* sym, Pathcomp_t* pp)
|
|||
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 */
|
||||
|
||||
/*
|
||||
|
@ -1112,10 +1099,9 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
|
|||
#endif
|
||||
NOT_USED(argc);
|
||||
memset(&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
stkp = tdata.sh->stk;
|
||||
if(!tdata.sh->pathlist)
|
||||
path_absolute(tdata.sh,argv[0],NIL(Pathcomp_t*),0);
|
||||
stkp = sh.stk;
|
||||
if(!sh.pathlist)
|
||||
path_absolute(argv[0],NIL(Pathcomp_t*),0);
|
||||
while (n = optget(argv,sh_optbuiltin)) switch (n)
|
||||
{
|
||||
case 's':
|
||||
|
@ -1164,7 +1150,7 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
|
|||
UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
if(tdata.sh->subshell && !tdata.sh->subshare)
|
||||
if(sh.subshell && !sh.subshare)
|
||||
sh_subfork();
|
||||
}
|
||||
#if SHOPT_DYNAMIC
|
||||
|
@ -1177,13 +1163,13 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
|
|||
}
|
||||
if(list)
|
||||
sfprintf(sfstdout, "%s %08lu %s\n", arg, ver, path);
|
||||
sh_addlib(tdata.sh,library,arg,NiL);
|
||||
sh_addlib(library,arg,NiL);
|
||||
}
|
||||
else
|
||||
#endif /* SHOPT_DYNAMIC */
|
||||
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);
|
||||
}
|
||||
r = 0;
|
||||
|
@ -1221,7 +1207,7 @@ int b_builtin(int argc,char *argv[],Shbltin_t *context)
|
|||
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))
|
||||
errmsg = "restricted name";
|
||||
|
@ -1244,11 +1230,10 @@ int b_set(int argc,register char *argv[],Shbltin_t *context)
|
|||
{
|
||||
struct tdata tdata;
|
||||
memset(&tdata,0,sizeof(tdata));
|
||||
tdata.sh = context->shp;
|
||||
tdata.prefix=0;
|
||||
if(argv[1])
|
||||
{
|
||||
if(sh_argopts(argc,argv,tdata.sh) < 0)
|
||||
if(sh_argopts(argc,argv) < 0)
|
||||
return(2);
|
||||
if(sh_isoption(SH_VERBOSE))
|
||||
sh_onstate(SH_VERBOSE);
|
||||
|
@ -1257,7 +1242,7 @@ int b_set(int argc,register char *argv[],Shbltin_t *context)
|
|||
}
|
||||
else
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
Shell_t *shp = context->shp;
|
||||
if(shp->subshell && !shp->subshare)
|
||||
NOT_USED(context);
|
||||
if(sh.subshell && !sh.subshare)
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = context->shp;
|
||||
return(unall(argc,argv,shp->var_tree,shp));
|
||||
NOT_USED(context);
|
||||
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 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;
|
||||
struct checkpt buff;
|
||||
NOT_USED(argc);
|
||||
if(troot==shp->alias_tree)
|
||||
if(troot==sh.alias_tree)
|
||||
name = sh_optunalias;
|
||||
else
|
||||
name = sh_optunset;
|
||||
|
@ -1307,7 +1292,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
|
|||
nflag = NV_NOREF;
|
||||
/* FALLTHROUGH */
|
||||
case 'v':
|
||||
troot = shp->var_tree;
|
||||
troot = sh.var_tree;
|
||||
break;
|
||||
case ':':
|
||||
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)
|
||||
return(1);
|
||||
r = 0;
|
||||
if(troot==shp->var_tree)
|
||||
if(troot==sh.var_tree)
|
||||
nflag |= NV_VARNAME;
|
||||
else
|
||||
nflag = NV_NOSCOPE;
|
||||
|
@ -1334,7 +1319,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
|
|||
dtclear(troot);
|
||||
return(r);
|
||||
}
|
||||
sh_pushcontext(shp,&buff,1);
|
||||
sh_pushcontext(&sh,&buff,1);
|
||||
while(name = *argv++)
|
||||
{
|
||||
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 SHOPT_NAMESPACE
|
||||
if(shp->namespace && troot!=shp->var_tree)
|
||||
np = sh_fsearch(shp,name,nflag?HASH_NOSCOPE:0);
|
||||
if(sh.namespace && troot!=sh.var_tree)
|
||||
np = sh_fsearch(name,nflag?HASH_NOSCOPE:0);
|
||||
if(!np)
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
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;
|
||||
}
|
||||
isfun = is_afunction(np);
|
||||
if(troot==shp->var_tree)
|
||||
if(troot==sh.var_tree)
|
||||
{
|
||||
Namarr_t *ap;
|
||||
#if SHOPT_FIXEDARRAY
|
||||
|
@ -1375,7 +1360,7 @@ static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
|
|||
r=1;
|
||||
continue;
|
||||
}
|
||||
if(shp->subshell)
|
||||
if(sh.subshell)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
* _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 */
|
||||
|
||||
if(!nv_isnull(np) || nv_size(np) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE)))
|
||||
_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);
|
||||
else if(isfun)
|
||||
{
|
||||
if(troot!=shp->fun_base)
|
||||
if(troot!=sh.fun_base)
|
||||
nv_offattr(np,NV_FUNCTION); /* invalidate */
|
||||
else if(!(np->nvalue.rp && np->nvalue.rp->running))
|
||||
nv_delete(np,troot,0);
|
||||
}
|
||||
/* 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);
|
||||
else
|
||||
nv_close(np);
|
||||
|
||||
}
|
||||
else if(troot==shp->alias_tree)
|
||||
else if(troot==sh.alias_tree)
|
||||
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 */
|
||||
}
|
||||
sh_popcontext(shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
@ -1429,7 +1414,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
|
|||
{
|
||||
register char *cp;
|
||||
int indent=tp->indent, outname=0, isfun;
|
||||
sh_sigcheck(tp->sh);
|
||||
sh_sigcheck();
|
||||
if(flag)
|
||||
flag = '\n';
|
||||
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(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
|
||||
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))
|
||||
{
|
||||
fname = 0;
|
||||
iop = tp->sh->heredocs;
|
||||
iop = sh.heredocs;
|
||||
}
|
||||
else if(fname)
|
||||
iop = sfopen(iop,fname,"r");
|
||||
else if(tp->sh->gd->hist_ptr)
|
||||
iop = (tp->sh->gd->hist_ptr)->histfp;
|
||||
else if(sh.hist_ptr)
|
||||
iop = (sh.hist_ptr)->histfp;
|
||||
if(iop && sfseek(iop,(Sfoff_t)np->nvalue.rp->hoffset,SEEK_SET)>=0)
|
||||
sfmove(iop,file, nv_size(np), -1);
|
||||
else
|
||||
|
@ -1546,7 +1531,7 @@ static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, st
|
|||
}
|
||||
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');
|
||||
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;
|
||||
char *name=0;
|
||||
int len;
|
||||
tp->sh->last_table=0;
|
||||
sh.last_table=0;
|
||||
flag &= ~NV_ASSIGN;
|
||||
tp->scanmask = flag&~NV_NOSCOPE;
|
||||
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)
|
||||
tp->scanmask |= NV_UTOL|NV_LTOU;
|
||||
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);
|
||||
if(mbcoll())
|
||||
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);
|
||||
sfwrite(file,":\n",2);
|
||||
|
|
|
@ -70,7 +70,6 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
|
|||
register char *limit;
|
||||
register int mode=0, n;
|
||||
register unsigned long hit = 0;
|
||||
Shell_t *shp = context->shp;
|
||||
#ifdef _lib_getrlimit
|
||||
struct rlimit rlp;
|
||||
#endif /* _lib_getrlimit */
|
||||
|
@ -80,6 +79,7 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
|
|||
rlim_t i;
|
||||
char tmp[41];
|
||||
Optdisc_t disc;
|
||||
NOT_USED(context);
|
||||
memset(&disc, 0, sizeof(disc));
|
||||
disc.version = OPT_VERSION;
|
||||
disc.infof = infof;
|
||||
|
@ -135,7 +135,7 @@ int b_ulimit(int argc,char *argv[],Shbltin_t *context)
|
|||
unit = shtab_units[tp->type];
|
||||
if(limit)
|
||||
{
|
||||
if(shp->subshell && !shp->subshare)
|
||||
if(sh.subshell && !sh.subshare)
|
||||
sh_subfork();
|
||||
if(strcmp(limit,e_unlimited)==0)
|
||||
i = INFINITY;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define Q_FLAG (1 << 5)
|
||||
#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
|
||||
|
@ -54,7 +54,6 @@ static int whence(Shell_t *,char**, int);
|
|||
int b_command(register int argc,char *argv[],Shbltin_t *context)
|
||||
{
|
||||
register int n, flags=0;
|
||||
register Shell_t *shp = context->shp;
|
||||
opt_info.index = opt_info.offset = 0;
|
||||
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)
|
||||
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)
|
||||
{
|
||||
register int flags=0, n;
|
||||
register Shell_t *shp = context->shp;
|
||||
NOT_USED(argc);
|
||||
if(*argv[0]=='t')
|
||||
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));
|
||||
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 Namval_t *np;
|
||||
|
@ -187,7 +185,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
aflag++;
|
||||
}
|
||||
/* 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)
|
||||
&& (cp=nv_getval(np)))
|
||||
{
|
||||
|
@ -207,7 +205,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
}
|
||||
bltins:
|
||||
/* functions */
|
||||
if(!(flags&F_FLAG) && (np = nv_bfsearch(name, shp->fun_tree, &nq, ¬used)) && is_afunction(np))
|
||||
if(!(flags&F_FLAG) && (np = nv_bfsearch(name, sh.fun_tree, &nq, ¬used)) && is_afunction(np))
|
||||
{
|
||||
if(flags&Q_FLAG)
|
||||
continue;
|
||||
|
@ -219,7 +217,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
{
|
||||
sfprintf(sfstdout,sh_translate(is_ufunction));
|
||||
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)=='/')
|
||||
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++;
|
||||
}
|
||||
/* built-ins */
|
||||
if((np = nv_bfsearch(name, shp->bltin_tree, &nq, ¬used)) && !nv_isnull(np))
|
||||
if((np = nv_bfsearch(name, sh.bltin_tree, &nq, ¬used)) && !nv_isnull(np))
|
||||
{
|
||||
if(flags&V_FLAG)
|
||||
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
|
||||
*/
|
||||
if(path_search(shp, name, &pp, aflag>1 ? 3 : 2))
|
||||
if(path_search(name, &pp, aflag>1 ? 3 : 2))
|
||||
{
|
||||
cp = name;
|
||||
if(*cp!='/')
|
||||
|
@ -288,7 +286,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
else if(maybe_undef_fn)
|
||||
{
|
||||
/* 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 */
|
||||
sfputr(sfstdout,sh_fmtq(cp),-1);
|
||||
|
@ -305,13 +303,13 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
else if(cp)
|
||||
{
|
||||
int is_pathbound_builtin = 0;
|
||||
cp = path_fullname(shp,cp); /* resolve '.' & '..' */
|
||||
cp = path_fullname(cp); /* resolve '.' & '..' */
|
||||
if(flags&(V_FLAG|T_FLAG))
|
||||
{
|
||||
if(!(flags&T_FLAG))
|
||||
sfputr(sfstdout,sh_fmtq(name),' ');
|
||||
/* 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)
|
||||
is_pathbound_builtin = 1;
|
||||
|
@ -320,7 +318,7 @@ static int whence(Shell_t *shp,char **argv, register int flags)
|
|||
}
|
||||
/* tracked aliases next */
|
||||
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)
|
||||
&& strcmp(cp,nv_getval(np))==0)
|
||||
msg = sh_translate(is_talias);
|
||||
|
|
|
@ -331,7 +331,7 @@ int ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
|
|||
register int size='x';
|
||||
while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t'))
|
||||
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;
|
||||
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
|
||||
{
|
||||
com = sh_argbuild(ep->sh,&narg,comptr,0);
|
||||
com = sh_argbuild(&narg,comptr,0);
|
||||
/* special handling for leading quotes */
|
||||
if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
|
||||
begin--;
|
||||
}
|
||||
sh_offstate(SH_COMPLETE);
|
||||
/* allow a search to be aborted */
|
||||
if(ep->sh->trapnote&SH_SIGSET)
|
||||
if(sh.trapnote&SH_SIGSET)
|
||||
{
|
||||
rval = -1;
|
||||
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;
|
||||
/* add as tracked alias */
|
||||
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);
|
||||
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);
|
||||
else
|
||||
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
|
||||
/* 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)
|
||||
{
|
||||
register char *cp;
|
||||
if(!shgd->hist_ptr)
|
||||
if(!sh.hist_ptr)
|
||||
return(-1);
|
||||
/* use EDITOR on current command */
|
||||
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;
|
||||
ed_external(ep->e_inbuf, (char *)ep->e_inbuf);
|
||||
#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);
|
||||
hist_flush(shgd->hist_ptr);
|
||||
hist_flush(sh.hist_ptr);
|
||||
}
|
||||
cp = strcopy((char*)ep->e_inbuf,e_runvi);
|
||||
cp = strcopy(cp, fmtbase((long)ep->e_hline,10,0));
|
||||
|
|
|
@ -148,11 +148,11 @@ static const char bellchr[] = "\a"; /* bell char */
|
|||
*/
|
||||
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;
|
||||
Sfio_t *sp;
|
||||
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))
|
||||
return(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)
|
||||
{
|
||||
register Edit_t *ep = (Edit_t*)(shgd->ed_context);
|
||||
register Edit_t *ep = (Edit_t*)(sh.ed_context);
|
||||
if(fd == ep->e_savefd)
|
||||
*tty = ep->e_savetty;
|
||||
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)
|
||||
{
|
||||
register Edit_t *ep = (Edit_t*)(shgd->ed_context);
|
||||
register Edit_t *ep = (Edit_t*)(sh.ed_context);
|
||||
if(fd >=0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
register Edit_t *ep = (Edit_t*)(shgd->ed_context);
|
||||
if(ep->sh->st.trap[SH_KEYTRAP] && savelex)
|
||||
memcpy(ep->sh->lex_context,savelex,sizeof(Lex_t));
|
||||
register Edit_t *ep = (Edit_t*)(sh.ed_context);
|
||||
if(sh.st.trap[SH_KEYTRAP] && savelex)
|
||||
memcpy(sh.lex_context,savelex,sizeof(Lex_t));
|
||||
ep->e_keytrap = 0;
|
||||
if(ep->e_raw==0)
|
||||
return;
|
||||
|
@ -257,7 +257,7 @@ int tty_raw(register int fd, int echomode)
|
|||
#ifdef L_MASK
|
||||
struct ltchars lchars;
|
||||
#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)
|
||||
return(echo?-1:0);
|
||||
else if(ep->e_raw==ECHOMODE)
|
||||
|
@ -381,7 +381,7 @@ int tty_raw(register int fd, int echomode)
|
|||
# ifdef TIOCGETC
|
||||
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;
|
||||
struct tchars ttychars;
|
||||
switch(ep->e_raw)
|
||||
|
@ -429,7 +429,7 @@ 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)
|
||||
{
|
||||
case ECHOMODE:
|
||||
|
@ -580,7 +580,6 @@ void ed_crlf(register Edit_t *ep)
|
|||
|
||||
void ed_setup(register Edit_t *ep, int fd, int reedit)
|
||||
{
|
||||
Shell_t *shp = ep->sh;
|
||||
register char *pp;
|
||||
register char *last, *prev;
|
||||
char *ppmax;
|
||||
|
@ -590,16 +589,16 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
|
|||
ep->e_fd = fd;
|
||||
ep->e_multiline = sh_isoption(SH_MULTILINE)!=0;
|
||||
#ifdef SIGWINCH
|
||||
if(!(shp->sigflag[SIGWINCH]&SH_SIGFAULT))
|
||||
if(!(sh.sigflag[SIGWINCH]&SH_SIGFAULT))
|
||||
{
|
||||
signal(SIGWINCH,sh_fault);
|
||||
shp->sigflag[SIGWINCH] |= SH_SIGFAULT;
|
||||
sh.sigflag[SIGWINCH] |= SH_SIGFAULT;
|
||||
}
|
||||
pp = shp->st.trapcom[SIGWINCH];
|
||||
shp->st.trapcom[SIGWINCH] = 0;
|
||||
pp = sh.st.trapcom[SIGWINCH];
|
||||
sh.st.trapcom[SIGWINCH] = 0;
|
||||
sh_fault(SIGWINCH);
|
||||
shp->st.trapcom[SIGWINCH] = pp;
|
||||
ep->sh->winch = 0;
|
||||
sh.st.trapcom[SIGWINCH] = pp;
|
||||
sh.winch = 0;
|
||||
#endif
|
||||
#if SHOPT_EDPREDICT
|
||||
ep->hlist = 0;
|
||||
|
@ -608,12 +607,12 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
|
|||
#endif /* SHOPT_EDPREDICT */
|
||||
ep->e_stkoff = staktell();
|
||||
ep->e_stkptr = stakfreeze(0);
|
||||
if(!(last = shp->prompt))
|
||||
if(!(last = sh.prompt))
|
||||
last = "";
|
||||
shp->prompt = 0;
|
||||
if(shp->gd->hist_ptr)
|
||||
sh.prompt = 0;
|
||||
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_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)
|
||||
char *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))
|
||||
{
|
||||
Shopt_t o = shp->options;
|
||||
Shopt_t o = sh.options;
|
||||
sigblock(SIGINT);
|
||||
sh_offoption(SH_RESTRICTED);
|
||||
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 */
|
||||
nv_unset(SH_SUBSCRNOD);
|
||||
strcpy(ep->e_termname,term);
|
||||
shp->options = o;
|
||||
sh.options = o;
|
||||
sigrelease(SIGINT);
|
||||
}
|
||||
#endif
|
||||
|
@ -833,11 +832,11 @@ void ed_setup(register Edit_t *ep, int fd, int reedit)
|
|||
ep->e_lbuf[n] = *pp++;
|
||||
ep->e_default = 0;
|
||||
}
|
||||
if(ep->sh->st.trap[SH_KEYTRAP])
|
||||
if(sh.st.trap[SH_KEYTRAP])
|
||||
{
|
||||
if(!savelex)
|
||||
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 */
|
||||
|
@ -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 int rv= -1;
|
||||
register int delim = ((ep->e_raw&RAWMODE)?nttyparm.c_cc[VEOL]:'\n');
|
||||
Shell_t *shp = ep->sh;
|
||||
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 */
|
||||
if(ep->e_raw==ALTMODE)
|
||||
mode = 2;
|
||||
|
@ -884,17 +882,17 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
|||
}
|
||||
sh_onstate(SH_TTYWAIT);
|
||||
errno = EINTR;
|
||||
shp->gd->waitevent = 0;
|
||||
sh.waitevent = 0;
|
||||
while(rv<0 && errno==EINTR)
|
||||
{
|
||||
if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP))
|
||||
if(sh.trapnote&(SH_SIGSET|SH_SIGTRAP))
|
||||
goto done;
|
||||
#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
|
||||
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
|
||||
if(shp->winch && sh_isstate(SH_INTERACTIVE) && sh_isoption(SH_VI))
|
||||
if(sh.winch && sh_isstate(SH_INTERACTIVE) && sh_isoption(SH_VI))
|
||||
#else
|
||||
if(0)
|
||||
#endif
|
||||
|
@ -941,7 +939,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
|||
emacs_redraw(ep->e_emacs);
|
||||
#endif
|
||||
}
|
||||
shp->winch = 0;
|
||||
sh.winch = 0;
|
||||
/* an interrupt that should be ignored */
|
||||
errno = 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);
|
||||
if(rv>=0 || errno!=EINTR)
|
||||
break;
|
||||
if(shp->trapnote&(SH_SIGSET|SH_SIGTRAP))
|
||||
if(sh.trapnote&(SH_SIGSET|SH_SIGTRAP))
|
||||
goto done;
|
||||
/* an interrupt that should be ignored */
|
||||
fixtime();
|
||||
|
@ -985,7 +983,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
|
|||
else if(rv>=0 && mode>0)
|
||||
rv = read(fd,buff,rv>0?rv:1);
|
||||
done:
|
||||
shp->gd->waitevent = waitevent;
|
||||
sh.waitevent = waitevent;
|
||||
sh_offstate(SH_TTYWAIT);
|
||||
return(rv);
|
||||
}
|
||||
|
@ -1114,7 +1112,7 @@ int ed_getchar(register Edit_t *ep,int mode)
|
|||
killpg(getpgrp(),SIGINT);
|
||||
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;
|
||||
n=1;
|
||||
|
@ -1559,7 +1557,7 @@ int ed_genlen(register const genchar *str)
|
|||
|
||||
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;
|
||||
ep->e_tcgeta = 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)
|
||||
{
|
||||
register Edit_t *ep = (Edit_t*)(shgd->ed_context);
|
||||
register Edit_t *ep = (Edit_t*)(sh.ed_context);
|
||||
register int r;
|
||||
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;
|
||||
int savexit;
|
||||
Shell_t *shp = ep->sh;
|
||||
#if SHOPT_MULTIBYTE
|
||||
char buff[MAXLINE];
|
||||
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_TXTNOD,(char*)cp,NV_NOFREE);
|
||||
nv_putval(ED_MODENOD,ep->e_vi_insert,NV_NOFREE);
|
||||
savexit = shp->savexit;
|
||||
sh_trap(shp->st.trap[SH_KEYTRAP],0);
|
||||
shp->savexit = savexit;
|
||||
savexit = sh.savexit;
|
||||
sh_trap(sh.st.trap[SH_KEYTRAP],0);
|
||||
sh.savexit = savexit;
|
||||
if((cp = nv_getval(ED_CHRNOD)) == inbuff)
|
||||
nv_unset(ED_CHRNOD);
|
||||
else if(bufsize>0)
|
||||
|
@ -1723,7 +1720,7 @@ int ed_histgen(Edit_t *ep,const char *pattern)
|
|||
size_t m;
|
||||
char *cp, **argv=0, **av, **ar;
|
||||
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);
|
||||
if(ep->e_cur <=2)
|
||||
maxmatch = 0;
|
||||
|
@ -1733,7 +1730,7 @@ int ed_histgen(Edit_t *ep,const char *pattern)
|
|||
ep->hfirst = 0;
|
||||
return(0);
|
||||
}
|
||||
hp = ep->sh->gd->hist_ptr;
|
||||
hp = sh.hist_ptr;
|
||||
if(*pattern=='#' && *++pattern=='#')
|
||||
return(0);
|
||||
cp = stakalloc(m=strlen(pattern)+6);
|
||||
|
@ -1881,10 +1878,9 @@ void ed_histlist(Edit_t *ep,int n)
|
|||
|
||||
#endif /* SHOPT_EDPREDICT */
|
||||
|
||||
void *ed_open(Shell_t *shp)
|
||||
void *ed_open(void)
|
||||
{
|
||||
Edit_t *ed = sh_newof(0,Edit_t,1,0);
|
||||
ed->sh = shp;
|
||||
strcpy(ed->e_macro,"_??");
|
||||
return((void*)ed);
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
|||
#ifdef ESH_NFIRST
|
||||
ed_ungetchar(ep->ed,cntl('N'));
|
||||
#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)
|
||||
{
|
||||
hline = location.hist_command;
|
||||
|
@ -350,7 +350,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
|
|||
continue;
|
||||
#endif /* u370 */
|
||||
case '\t':
|
||||
if(cur>0 && ep->ed->sh->nextprompt)
|
||||
if(cur>0 && sh.nextprompt)
|
||||
{
|
||||
if(ep->ed->e_tabcount==0)
|
||||
{
|
||||
|
@ -684,7 +684,7 @@ update:
|
|||
hline = location.hist_command; /* start at saved position */
|
||||
hloff = location.hist_line;
|
||||
#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)
|
||||
{
|
||||
beep();
|
||||
|
@ -1348,7 +1348,7 @@ static void search(Emacs_t* ep,genchar *out,int direction)
|
|||
}
|
||||
else
|
||||
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;
|
||||
if(i>0)
|
||||
{
|
||||
|
|
|
@ -303,8 +303,8 @@ getline:
|
|||
{
|
||||
|
||||
/* search history for string */
|
||||
hl = hist_find(shgd->hist_ptr, str,
|
||||
shgd->hist_ptr->histind,
|
||||
hl = hist_find(sh.hist_ptr, str,
|
||||
sh.hist_ptr->histind,
|
||||
flag&HIST_QUESTION, -1);
|
||||
if((n = hl.hist_command) == -1)
|
||||
n = 0; /* not found */
|
||||
|
@ -312,10 +312,10 @@ getline:
|
|||
if(n)
|
||||
{
|
||||
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 */
|
||||
if(n > 0 && hist_seek(shgd->hist_ptr, n) != -1)
|
||||
ref = shgd->hist_ptr->histfp;
|
||||
if(n > 0 && hist_seek(sh.hist_ptr, n) != -1)
|
||||
ref = sh.hist_ptr->histfp;
|
||||
|
||||
}
|
||||
if(!ref)
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#endif
|
||||
|
||||
#define _HIST_PRIVATE \
|
||||
void *histshell; \
|
||||
off_t histcnt; /* offset into history file */\
|
||||
off_t histmarker; /* offset of last command marker */ \
|
||||
int histflush; /* set if flushed outside of hflush() */\
|
||||
|
@ -107,7 +106,7 @@ static History_t *hist_ptr;
|
|||
static int acctinit(History_t *hp)
|
||||
{
|
||||
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)))
|
||||
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);
|
||||
if(*last=='-')
|
||||
id1 = strtol(last+1,&last,10);
|
||||
if(shgd->euserid >=id1 && shgd->euserid <= id2)
|
||||
if(sh.euserid >=id1 && sh.euserid <= id2)
|
||||
r |= 1;
|
||||
if(shgd->userid >=id1 && shgd->userid <= id2)
|
||||
if(sh.userid >=id1 && sh.userid <= id2)
|
||||
r |= 2;
|
||||
cp = last;
|
||||
}
|
||||
|
@ -198,9 +197,8 @@ static void hist_touch(void *handle)
|
|||
* cleaned up.
|
||||
* 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 History_t *hp;
|
||||
register char *histname;
|
||||
|
@ -209,7 +207,7 @@ int sh_histinit(void *sh_context)
|
|||
register char *cp;
|
||||
register off_t hsize = 0;
|
||||
|
||||
if(shgd->hist_ptr=hist_ptr)
|
||||
if(sh.hist_ptr=hist_ptr)
|
||||
return(1);
|
||||
if(!(histname = nv_getval(HISTFILE)))
|
||||
{
|
||||
|
@ -222,7 +220,7 @@ int sh_histinit(void *sh_context)
|
|||
histname = stakptr(offset);
|
||||
}
|
||||
retry:
|
||||
cp = path_relative(shp,histname);
|
||||
cp = path_relative(histname);
|
||||
if(!histinit)
|
||||
histmode = S_IRUSR|S_IWUSR;
|
||||
if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT|O_cloexec,histmode))>=0)
|
||||
|
@ -250,7 +248,7 @@ retry:
|
|||
if(fd < 0)
|
||||
{
|
||||
/* don't allow root a history_file in /tmp */
|
||||
if(shgd->userid)
|
||||
if(sh.userid)
|
||||
{
|
||||
if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*))))
|
||||
return(0);
|
||||
|
@ -267,8 +265,7 @@ retry:
|
|||
maxlines = HIST_DFLT;
|
||||
for(histmask=16;histmask <= maxlines; histmask <<=1 );
|
||||
hp = new_of(History_t,(--histmask)*sizeof(off_t));
|
||||
shgd->hist_ptr = hist_ptr = hp;
|
||||
hp->histshell = (void*)shp;
|
||||
sh.hist_ptr = hist_ptr = hp;
|
||||
hp->histsize = maxlines;
|
||||
hp->histmask = histmask;
|
||||
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)
|
||||
{
|
||||
#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);
|
||||
#endif /* DEBUG */
|
||||
hp = hist_trim(hp,(int)hp->histind-maxlines);
|
||||
|
@ -375,7 +372,7 @@ void hist_close(register History_t *hp)
|
|||
#endif /* SHOPT_AUDIT */
|
||||
free((char*)hp);
|
||||
hist_ptr = 0;
|
||||
shgd->hist_ptr = 0;
|
||||
sh.hist_ptr = 0;
|
||||
#if SHOPT_ACCTFILE
|
||||
if(acctfd)
|
||||
{
|
||||
|
@ -450,7 +447,7 @@ static History_t* hist_trim(History_t *hp, int n)
|
|||
histinit = 1;
|
||||
histmode = statb.st_mode;
|
||||
}
|
||||
if(!sh_histinit(hp->histshell))
|
||||
if(!sh_histinit())
|
||||
{
|
||||
/* use the old history file */
|
||||
return hist_ptr = hist_old;
|
||||
|
@ -722,7 +719,7 @@ void hist_flush(register History_t *hp)
|
|||
if(sfsync(hp->histfp)<0)
|
||||
{
|
||||
hist_close(hp);
|
||||
if(!sh_histinit(hp->histshell))
|
||||
if(!sh_histinit())
|
||||
sh_offoption(SH_HISTORY);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
#endif /* SHOPT_AUDIT */
|
||||
|
@ -933,7 +932,7 @@ Histloc_t hist_find(register History_t*hp,char *string,register int index1,int f
|
|||
return(location);
|
||||
}
|
||||
/* allow a search to be aborted */
|
||||
if(((Shell_t*)hp->histshell)->trapnote&SH_SIGSET)
|
||||
if(sh.trapnote & SH_SIGSET)
|
||||
break;
|
||||
}
|
||||
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)
|
||||
{
|
||||
register int c;
|
||||
register History_t *hp = shgd->hist_ptr;
|
||||
register History_t *hp = sh.hist_ptr;
|
||||
register int count = 0;
|
||||
register char *s1max = s1+size;
|
||||
if(!hp)
|
||||
|
|
|
@ -217,7 +217,7 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit
|
|||
#if SHOPT_RAWONLY
|
||||
# define viraw 1
|
||||
#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
|
||||
clock_t oldtime, newtime;
|
||||
struct tms dummy;
|
||||
|
@ -252,7 +252,7 @@ int ed_viread(void *context, int fd, register char *shbuf, int nchar, int reedit
|
|||
oldtime = times(&dummy);
|
||||
#endif /* FIORDCHK */
|
||||
/* abort of interrupt has occurred */
|
||||
if(ed->sh->trapnote&SH_SIGSET)
|
||||
if(sh.trapnote&SH_SIGSET)
|
||||
i = -1;
|
||||
else
|
||||
{
|
||||
|
@ -1529,7 +1529,7 @@ static void getline(register Vi_t* vp,register int mode)
|
|||
mode != SEARCH &&
|
||||
last_virt >= 0 &&
|
||||
(vp->ed->e_tabcount || !isblank(cur_virt)) &&
|
||||
vp->ed->sh->nextprompt)
|
||||
sh.nextprompt)
|
||||
{
|
||||
if(virtual[cur_virt]=='\\')
|
||||
{
|
||||
|
@ -2302,7 +2302,7 @@ static int search(register Vi_t* vp,register int mode)
|
|||
i = INVALID;
|
||||
if( new_direction==1 && curhline >= histmax )
|
||||
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;
|
||||
strncpy(lsearch, ((char*)virtual)+1, SEARCHSIZE-1);
|
||||
|
|
|
@ -128,7 +128,7 @@ struct argnod
|
|||
|
||||
extern struct dolnod *sh_argcreate(char*[]);
|
||||
extern char *sh_argdolminus(void*);
|
||||
extern int sh_argopts(int,char*[],void*);
|
||||
extern int sh_argopts(int,char*[]);
|
||||
|
||||
|
||||
extern const char e_heading[];
|
||||
|
|
|
@ -33,33 +33,33 @@
|
|||
* IMPORTANT: The offsets on these macros must be synchronous
|
||||
* with the order of shtab_builtins[] in data/builtins.c!
|
||||
*/
|
||||
#define SYSEXEC (shgd->bltin_cmds) /* exec */
|
||||
#define SYSREDIR (shgd->bltin_cmds+1) /* redirect */
|
||||
#define SYSSET (shgd->bltin_cmds+2) /* set */
|
||||
#define SYSEXEC (sh.bltin_cmds) /* exec */
|
||||
#define SYSREDIR (sh.bltin_cmds+1) /* redirect */
|
||||
#define SYSSET (sh.bltin_cmds+2) /* set */
|
||||
/* : */
|
||||
#define SYSTRUE (shgd->bltin_cmds+4) /* true */
|
||||
#define SYSCOMMAND (shgd->bltin_cmds+5) /* command */
|
||||
#define SYSCD (shgd->bltin_cmds+6) /* cd */
|
||||
#define SYSBREAK (shgd->bltin_cmds+7) /* break */
|
||||
#define SYSCONT (shgd->bltin_cmds+8) /* continue */
|
||||
#define SYSTRUE (sh.bltin_cmds+4) /* true */
|
||||
#define SYSCOMMAND (sh.bltin_cmds+5) /* command */
|
||||
#define SYSCD (sh.bltin_cmds+6) /* cd */
|
||||
#define SYSBREAK (sh.bltin_cmds+7) /* break */
|
||||
#define SYSCONT (sh.bltin_cmds+8) /* continue */
|
||||
|
||||
#define SYSTYPESET (shgd->bltin_cmds+9) /* typeset \ */
|
||||
#define SYSTYPESET (sh.bltin_cmds+9) /* typeset \ */
|
||||
/* autoload | */
|
||||
#define SYSCOMPOUND (shgd->bltin_cmds+11) /* compound | */
|
||||
#define SYSCOMPOUND (sh.bltin_cmds+11) /* compound | */
|
||||
/* float >typeset range */
|
||||
/* functions | */
|
||||
/* integer | */
|
||||
#define SYSNAMEREF (shgd->bltin_cmds+15) /* nameref | */
|
||||
#define SYSTYPESET_END (shgd->bltin_cmds+15) /* / */
|
||||
#define SYSNAMEREF (sh.bltin_cmds+15) /* nameref | */
|
||||
#define SYSTYPESET_END (sh.bltin_cmds+15) /* / */
|
||||
|
||||
#define SYSTEST (shgd->bltin_cmds+16) /* test */
|
||||
#define SYSBRACKET (shgd->bltin_cmds+17) /* [ */
|
||||
#define SYSLET (shgd->bltin_cmds+18) /* let */
|
||||
#define SYSEXPORT (shgd->bltin_cmds+19) /* export */
|
||||
#define SYSDOT (shgd->bltin_cmds+20) /* . */
|
||||
#define SYSSOURCE (shgd->bltin_cmds+21) /* source */
|
||||
#define SYSRETURN (shgd->bltin_cmds+22) /* return */
|
||||
#define SYSENUM (shgd->bltin_cmds+23) /* enum */
|
||||
#define SYSTEST (sh.bltin_cmds+16) /* test */
|
||||
#define SYSBRACKET (sh.bltin_cmds+17) /* [ */
|
||||
#define SYSLET (sh.bltin_cmds+18) /* let */
|
||||
#define SYSEXPORT (sh.bltin_cmds+19) /* export */
|
||||
#define SYSDOT (sh.bltin_cmds+20) /* . */
|
||||
#define SYSSOURCE (sh.bltin_cmds+21) /* source */
|
||||
#define SYSRETURN (sh.bltin_cmds+22) /* return */
|
||||
#define SYSENUM (sh.bltin_cmds+23) /* enum */
|
||||
|
||||
/* entry point for shell special builtins */
|
||||
|
||||
|
|
|
@ -124,59 +124,56 @@ extern char* sh_setenviron(const char*);
|
|||
#define SH_READEVAL 0x4000 /* for sh_eval */
|
||||
#define SH_FUNEVAL 0x10000 /* for sh_eval for function load */
|
||||
|
||||
extern void sh_applyopts(Shell_t*,Shopt_t);
|
||||
extern char **sh_argbuild(Shell_t*,int*,const struct comnod*,int);
|
||||
extern struct dolnod *sh_argfree(Shell_t *, struct dolnod*,int);
|
||||
extern struct dolnod *sh_argnew(Shell_t*,char*[],struct dolnod**);
|
||||
extern void *sh_argopen(Shell_t*);
|
||||
extern struct argnod *sh_argprocsub(Shell_t*,struct argnod*);
|
||||
extern void sh_argreset(Shell_t*,struct dolnod*,struct dolnod*);
|
||||
extern char **sh_argbuild(int*,const struct comnod*,int);
|
||||
extern struct dolnod *sh_argfree(struct dolnod*,int);
|
||||
extern struct dolnod *sh_argnew(char*[],struct dolnod**);
|
||||
extern void *sh_argopen(void);
|
||||
extern struct argnod *sh_argprocsub(struct argnod*);
|
||||
extern void sh_argreset(struct dolnod*,struct dolnod*);
|
||||
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 void sh_chktrap(Shell_t*);
|
||||
extern void sh_chktrap(void);
|
||||
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_echolist(Shell_t*,Sfio_t*, int, char**);
|
||||
extern struct argnod *sh_endword(Shell_t*,int);
|
||||
extern int sh_debug(const char*,const char*,const char*,char *const[],int);
|
||||
extern char **sh_envgen(void);
|
||||
extern void sh_envnolocal(Namval_t*,void*);
|
||||
extern Sfdouble_t sh_arith(Shell_t*,const char*);
|
||||
extern void *sh_arithcomp(Shell_t *,char*);
|
||||
extern pid_t sh_fork(Shell_t*,int,int*);
|
||||
extern pid_t _sh_fork(Shell_t*,pid_t, int ,int*);
|
||||
extern char *sh_mactrim(Shell_t*,char*,int);
|
||||
extern int sh_macexpand(Shell_t*,struct argnod*,struct argnod**,int);
|
||||
extern int sh_macfun(Shell_t*,const char*,int);
|
||||
extern void sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*);
|
||||
extern void *sh_macopen(Shell_t*);
|
||||
extern char *sh_macpat(Shell_t*,struct argnod*,int);
|
||||
extern Sfdouble_t sh_mathfun(Shell_t*, void*, int, Sfdouble_t*);
|
||||
extern int sh_outtype(Shell_t*, Sfio_t*);
|
||||
extern char *sh_mactry(Shell_t*,char*);
|
||||
extern Sfdouble_t sh_arith(const char*);
|
||||
extern void *sh_arithcomp(char*);
|
||||
extern pid_t sh_fork(int,int*);
|
||||
extern pid_t _sh_fork(pid_t, int ,int*);
|
||||
extern char *sh_mactrim(char*,int);
|
||||
extern int sh_macexpand(struct argnod*,struct argnod**,int);
|
||||
extern int sh_macfun(const char*,int);
|
||||
extern void sh_machere(Sfio_t*, Sfio_t*, char*);
|
||||
extern void *sh_macopen(void);
|
||||
extern char *sh_macpat(struct argnod*,int);
|
||||
extern Sfdouble_t sh_mathfun(void*, int, Sfdouble_t*);
|
||||
extern int sh_outtype(Sfio_t*);
|
||||
extern char *sh_mactry(char*);
|
||||
extern int sh_mathstd(const char*);
|
||||
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 void sh_setmatch(Shell_t*,const char*,int,int,int[],int);
|
||||
extern void sh_scope(Shell_t*, struct argnod*, int);
|
||||
extern Namval_t *sh_scoped(Shell_t*, Namval_t*);
|
||||
extern void sh_setmatch(const char*,int,int,int[],int);
|
||||
extern void sh_scope(struct argnod*, int);
|
||||
extern Namval_t *sh_scoped(Namval_t*);
|
||||
extern Dt_t *sh_subtracktree(int);
|
||||
extern Dt_t *sh_subfuntree(int);
|
||||
extern void sh_subjobcheck(pid_t);
|
||||
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 void sh_timetraps(Shell_t*);
|
||||
extern void sh_timetraps(void);
|
||||
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 int sh_type(const char*);
|
||||
extern void sh_unscope(Shell_t*);
|
||||
extern void sh_unscope(void);
|
||||
extern void sh_utol(const char*, char*);
|
||||
extern int sh_whence(char**,int);
|
||||
#if SHOPT_NAMESPACE
|
||||
extern Namval_t *sh_fsearch(Shell_t*,const char *,int);
|
||||
extern Namval_t *sh_fsearch(const char *,int);
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
|
||||
/* malloc related wrappers */
|
||||
|
@ -214,7 +211,7 @@ extern char *sh_getcwd(void);
|
|||
#define sh_getstate() (sh.st.states)
|
||||
#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 const char e_dict[];
|
||||
|
@ -243,7 +240,7 @@ extern const char e_dict[];
|
|||
# define STAT_SPAWN 12
|
||||
# define STAT_SUBSHELL 13
|
||||
extern const Shtable_t shtab_stats[];
|
||||
# define sh_stats(x) (shgd->stats[(x)]++)
|
||||
# define sh_stats(x) (sh.stats[(x)]++)
|
||||
#else
|
||||
# define sh_stats(x)
|
||||
#endif /* SHOPT_STATS */
|
||||
|
|
|
@ -131,7 +131,6 @@ typedef struct edit
|
|||
char e_macro[4]; /* macro buffer */
|
||||
void *e_vi; /* vi specific data */
|
||||
void *e_emacs; /* emacs specific data */
|
||||
Shell_t *sh; /* interpreter pointer */
|
||||
char *e_stkptr; /* saved stack pointer */
|
||||
int e_stkoff; /* saved stack offset */
|
||||
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_expand(Edit_t*, char[],int*,int*,int,int);
|
||||
extern int ed_fulledit(Edit_t*);
|
||||
extern void *ed_open(Shell_t*);
|
||||
extern void *ed_open(void);
|
||||
#if SHOPT_MULTIBYTE
|
||||
extern int ed_internal(const char*, genchar*);
|
||||
extern int ed_external(const genchar*, char*);
|
||||
|
|
|
@ -108,11 +108,11 @@ struct checkpt
|
|||
)
|
||||
#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_sigclear(int);
|
||||
extern void sh_sigdone(void);
|
||||
extern void sh_siginit(void*);
|
||||
extern void sh_siginit(void);
|
||||
extern void sh_sigtrap(int);
|
||||
extern void sh_sigreset(int);
|
||||
extern void *sh_timeradd(unsigned long,int ,void (*)(void*),void*);
|
||||
|
|
|
@ -56,7 +56,7 @@ extern int _Hist;
|
|||
#define hist_min(hp) ((_Hist=((int)((hp)->histind-(hp)->histsize)))>=0?_Hist:0)
|
||||
#define hist_max(hp) ((int)((hp)->histind))
|
||||
/* 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_close(History_t*);
|
||||
extern int hist_copy(char*, int, int, int);
|
||||
|
|
|
@ -52,29 +52,28 @@
|
|||
struct ionod;
|
||||
#endif /* !ARG_RAW */
|
||||
|
||||
extern int sh_iocheckfd(Shell_t*,int);
|
||||
extern void sh_ioinit(Shell_t*);
|
||||
extern int sh_iocheckfd(int);
|
||||
extern void sh_ioinit(void);
|
||||
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 int sh_rpipe(int[]);
|
||||
extern void sh_iorestore(Shell_t*,int,int);
|
||||
extern void sh_iorestore(int,int);
|
||||
#if defined(__EXPORT__) && defined(_BLD_DLL)
|
||||
__EXPORT__
|
||||
#endif
|
||||
extern Sfio_t *sh_iostream(Shell_t*,int);
|
||||
extern int sh_redirect(Shell_t*,struct ionod*,int);
|
||||
extern void sh_iosave(Shell_t *, int,int,char*);
|
||||
extern int sh_iovalidfd(Shell_t*, int);
|
||||
extern int sh_iosafefd(Shell_t*, int);
|
||||
extern int sh_inuse(Shell_t*, int);
|
||||
extern void sh_iounsave(Shell_t*);
|
||||
extern void sh_iounpipe(Shell_t*);
|
||||
extern Sfio_t *sh_iostream(int);
|
||||
extern int sh_redirect(struct ionod*,int);
|
||||
extern void sh_iosave(int,int,char*);
|
||||
extern int sh_iovalidfd(int);
|
||||
extern int sh_iosafefd(int);
|
||||
extern int sh_inuse(int);
|
||||
extern void sh_iounsave(void);
|
||||
extern void sh_iounpipe(void);
|
||||
extern int sh_chkopen(const char*);
|
||||
extern int sh_ioaccess(int,int);
|
||||
extern int sh_devtofd(const char*);
|
||||
extern int sh_isdevfd(const char*);
|
||||
extern int sh_source(Shell_t*, Sfio_t*, const char*);
|
||||
|
||||
/* the following are readonly */
|
||||
extern const char e_pexists[];
|
||||
|
|
|
@ -59,7 +59,6 @@ struct process
|
|||
{
|
||||
struct process *p_nxtjob; /* next job structure */
|
||||
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 */
|
||||
pid_t p_pid; /* process id */
|
||||
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_kill(struct process*,int);
|
||||
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_subrestore(void*);
|
||||
#if SHOPT_BGX
|
||||
extern void job_chldtrap(Shell_t*, const char*,int);
|
||||
extern void job_chldtrap(const char*,int);
|
||||
#endif /* SHOPT_BGX */
|
||||
#ifdef JOBS
|
||||
extern void job_init(Shell_t*,int);
|
||||
extern int job_close(Shell_t*);
|
||||
extern void job_init(int);
|
||||
extern int job_close(void);
|
||||
extern int job_list(struct process*,int);
|
||||
extern int job_hup(struct process *, int);
|
||||
extern int job_switch(struct process*,int);
|
||||
extern void job_fork(pid_t);
|
||||
extern int job_reap(int);
|
||||
#else
|
||||
# define job_init(s,flag)
|
||||
# define job_close(s) (0)
|
||||
# define job_init(flag)
|
||||
# define job_close() (0)
|
||||
# define job_fork(p)
|
||||
#endif /* JOBS */
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ typedef struct pathcomp
|
|||
char *blib;
|
||||
unsigned short len;
|
||||
unsigned short flags;
|
||||
Shell_t *shp;
|
||||
} Pathcomp_t;
|
||||
|
||||
#ifndef ARG_RAW
|
||||
|
@ -71,38 +70,42 @@ typedef struct pathcomp
|
|||
#endif /* !ARG_RAW */
|
||||
|
||||
/* 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_unsetfpath(Shell_t*);
|
||||
extern Pathcomp_t *path_addpath(Shell_t*,Pathcomp_t*,const char*,int);
|
||||
extern Pathcomp_t *path_unsetfpath(void);
|
||||
extern Pathcomp_t *path_addpath(Pathcomp_t*,const char*,int);
|
||||
extern Pathcomp_t *path_dup(Pathcomp_t*);
|
||||
extern void path_delete(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_fullname(Shell_t*,const char*);
|
||||
extern int path_expand(Shell_t*,const char*, struct argnod**);
|
||||
extern noreturn void path_exec(Shell_t*,const char*,char*[],struct argnod*);
|
||||
extern pid_t path_spawn(Shell_t*,const char*,char*[],char*[],Pathcomp_t*,int);
|
||||
extern char *path_fullname(const char*);
|
||||
extern int path_expand(const char*, struct argnod**);
|
||||
extern noreturn void path_exec(const char*,char*[],struct argnod*);
|
||||
extern pid_t path_spawn(const char*,char*[],char*[],Pathcomp_t*,int);
|
||||
#if defined(__EXPORT__) && defined(_BLD_DLL)
|
||||
# define extern __EXPORT__
|
||||
#endif
|
||||
extern int path_open(Shell_t*,const char*,Pathcomp_t*);
|
||||
extern Pathcomp_t *path_get(Shell_t*,const char*);
|
||||
extern int path_open(const char*,Pathcomp_t*);
|
||||
extern Pathcomp_t *path_get(const char*);
|
||||
#undef extern
|
||||
extern char *path_pwd(Shell_t*,int);
|
||||
extern Pathcomp_t *path_nextcomp(Shell_t*,Pathcomp_t*,const char*,Pathcomp_t*);
|
||||
extern int path_search(Shell_t*,const char*,Pathcomp_t**,int);
|
||||
extern char *path_relative(Shell_t*,const char*);
|
||||
extern int path_complete(Shell_t*,const char*, const char*,struct argnod**);
|
||||
extern char *path_pwd(void);
|
||||
extern Pathcomp_t *path_nextcomp(Pathcomp_t*,const char*,Pathcomp_t*);
|
||||
extern int path_search(const char*,Pathcomp_t**,int);
|
||||
extern char *path_relative(const char*);
|
||||
extern int path_complete(const char*, const char*,struct argnod**);
|
||||
#if SHOPT_BRACEPAT
|
||||
extern int path_generate(Shell_t*,struct argnod*,struct argnod**);
|
||||
extern int path_generate(struct argnod*,struct argnod**);
|
||||
#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 */
|
||||
extern int sh_addlib(Shell_t*,void*,char*,Pathcomp_t*);
|
||||
extern Shbltin_f sh_getlib(Shell_t*,char*,Pathcomp_t*);
|
||||
extern int sh_addlib(void*,char*,Pathcomp_t*);
|
||||
extern Shbltin_f sh_getlib(char*,Pathcomp_t*);
|
||||
#endif /* SHOPT_DYNAMIC */
|
||||
|
||||
/* constant strings needed for whence */
|
||||
extern const char e_timeformat[];
|
||||
|
|
|
@ -52,7 +52,7 @@ typedef struct Regress_s
|
|||
#define SHOPT_P_SUID sh_regress_p_suid(__LINE__, __FILE__)
|
||||
|
||||
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 uid_t sh_regress_p_suid(unsigned int, const char*);
|
||||
extern char* sh_regress_etc(const char*, unsigned int, const char*);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define SH_VERSION 20211229
|
||||
#define SH_VERSION 20220106
|
||||
|
||||
#include <ast.h>
|
||||
#include <cdt.h>
|
||||
|
@ -226,13 +226,11 @@ struct Shell_s
|
|||
Dt_t *fun_tree; /* for shell functions */
|
||||
Dt_t *alias_tree; /* for alias names */
|
||||
Dt_t *bltin_tree; /* for builtin commands */
|
||||
Dt_t *track_tree; /* for tracked aliases */
|
||||
Shscope_t *topscope; /* pointer to top-level scope */
|
||||
int inlineno; /* line number of current input file */
|
||||
int exitval; /* exit status of the command currently being run */
|
||||
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. */
|
||||
struct limits lim;
|
||||
|
@ -243,7 +241,6 @@ struct Shell_s
|
|||
pid_t pid; /* $$, the main shell's PID (invariable) */
|
||||
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) */
|
||||
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
|
||||
unsigned char sigruntime[2];
|
||||
Namval_t *bltin_nodes;
|
||||
Namval_t *bltin_cmds;
|
||||
|
@ -253,13 +250,18 @@ struct Shell_s
|
|||
char **sigmsg;
|
||||
char **login_files;
|
||||
void *ed_context;
|
||||
int *stats;
|
||||
int sigmax;
|
||||
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. */
|
||||
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 */
|
||||
Stk_t *stk; /* stack pointer */
|
||||
Sfio_t *heredocs; /* current here-doc temp file */
|
||||
|
@ -268,7 +270,6 @@ struct Shell_s
|
|||
char *lastarg;
|
||||
char *lastpath; /* last absolute path found */
|
||||
int path_err; /* last error on path search */
|
||||
Dt_t *track_tree; /* for tracked aliases */
|
||||
Dt_t *var_base; /* global level variables */
|
||||
Dt_t *fun_base; /* global level functions */
|
||||
Dt_t *openmatch;
|
||||
|
@ -414,13 +415,12 @@ extern Libcomp_t *liblist;
|
|||
# define extern __EXPORT__
|
||||
#endif /* _DLL */
|
||||
|
||||
extern Dt_t *sh_bltin_tree(void);
|
||||
extern void sh_subfork(void);
|
||||
extern Shell_t *sh_init(int,char*[],Shinit_f);
|
||||
extern int sh_reinit(char*[]);
|
||||
extern int sh_eval(Sfio_t*,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_fun(Namval_t*,Namval_t*, char*[]);
|
||||
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 Shscope_t *sh_getscope(int,int);
|
||||
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_onoption(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
|
||||
* 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_getinterp(void); /* for libshell ABI compatibility */
|
||||
#define sh_getinterp() (&sh)
|
||||
#define shgd (&sh)
|
||||
|
||||
#ifdef _DLL
|
||||
# undef extern
|
||||
|
|
|
@ -75,7 +75,6 @@ struct _shlex_pvt_lexdata_
|
|||
*/
|
||||
typedef struct _shlex_
|
||||
{
|
||||
Shell_t *sh; /* pointer to the interpreter */
|
||||
struct argnod *arg; /* current word */
|
||||
struct ionod *heredoc; /* pending here document list */
|
||||
int token; /* current token number */
|
||||
|
@ -187,7 +186,7 @@ extern const char e_newline[];
|
|||
|
||||
extern int sh_lex(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 noreturn void sh_syntax(Lex_t*);
|
||||
#if SHOPT_KIA
|
||||
|
|
|
@ -209,13 +209,13 @@ union Shnode_u
|
|||
struct arithnod ar;
|
||||
};
|
||||
|
||||
extern void sh_freeup(Shell_t*);
|
||||
extern void sh_freeup(void);
|
||||
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)
|
||||
__EXPORT__
|
||||
#endif
|
||||
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 */
|
||||
|
|
|
@ -61,6 +61,6 @@ extern const struct shtable3 shtab_builtins[];
|
|||
extern const Shtable_t shtab_reserved[];
|
||||
extern const Shtable_t *sh_locate(const char*, const Shtable_t*, 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 */
|
||||
|
|
|
@ -68,7 +68,6 @@
|
|||
|
||||
struct lval
|
||||
{
|
||||
Shell_t *shp;
|
||||
char *value;
|
||||
char *ovalue;
|
||||
Sfdouble_t (*fun)(Sfdouble_t,...);
|
||||
|
@ -93,7 +92,6 @@ struct mathtab
|
|||
|
||||
typedef struct _arith_
|
||||
{
|
||||
Shell_t *shp;
|
||||
unsigned char *code;
|
||||
const char *expr;
|
||||
Sfdouble_t (*fun)(const char**,struct lval*,int,Sfdouble_t);
|
||||
|
@ -199,7 +197,7 @@ extern const struct mathtab shtab_math[];
|
|||
#define VALUE 2
|
||||
#define MESSAGE 3
|
||||
|
||||
extern Sfdouble_t strval(Shell_t*,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 Sfdouble_t arith_strval(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*);
|
||||
#endif /* !SEQPOINT */
|
||||
|
|
|
@ -57,9 +57,9 @@
|
|||
#define TEST_SGT 17
|
||||
#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_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 test_opchars[];
|
||||
|
|
|
@ -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 */
|
||||
|
||||
#define PATHNOD (shgd->bltin_nodes)
|
||||
#define PS1NOD (shgd->bltin_nodes+1)
|
||||
#define PS2NOD (shgd->bltin_nodes+2)
|
||||
#define IFSNOD (shgd->bltin_nodes+3)
|
||||
#define PWDNOD (shgd->bltin_nodes+4)
|
||||
#define HOME (shgd->bltin_nodes+5)
|
||||
#define MAILNOD (shgd->bltin_nodes+6)
|
||||
#define REPLYNOD (shgd->bltin_nodes+7)
|
||||
#define SHELLNOD (shgd->bltin_nodes+8)
|
||||
#define EDITNOD (shgd->bltin_nodes+9)
|
||||
#define MCHKNOD (shgd->bltin_nodes+10)
|
||||
#define RANDNOD (shgd->bltin_nodes+11)
|
||||
#define ENVNOD (shgd->bltin_nodes+12)
|
||||
#define HISTFILE (shgd->bltin_nodes+13)
|
||||
#define HISTSIZE (shgd->bltin_nodes+14)
|
||||
#define HISTEDIT (shgd->bltin_nodes+15)
|
||||
#define HISTCUR (shgd->bltin_nodes+16)
|
||||
#define FCEDNOD (shgd->bltin_nodes+17)
|
||||
#define CDPNOD (shgd->bltin_nodes+18)
|
||||
#define MAILPNOD (shgd->bltin_nodes+19)
|
||||
#define PS3NOD (shgd->bltin_nodes+20)
|
||||
#define OLDPWDNOD (shgd->bltin_nodes+21)
|
||||
#define VISINOD (shgd->bltin_nodes+22)
|
||||
#define COLUMNS (shgd->bltin_nodes+23)
|
||||
#define LINES (shgd->bltin_nodes+24)
|
||||
#define PPIDNOD (shgd->bltin_nodes+25)
|
||||
#define L_ARGNOD (shgd->bltin_nodes+26)
|
||||
#define TMOUTNOD (shgd->bltin_nodes+27)
|
||||
#define SECONDS (shgd->bltin_nodes+28)
|
||||
#define LINENO (shgd->bltin_nodes+29)
|
||||
#define OPTARGNOD (shgd->bltin_nodes+30)
|
||||
#define OPTINDNOD (shgd->bltin_nodes+31)
|
||||
#define PS4NOD (shgd->bltin_nodes+32)
|
||||
#define FPATHNOD (shgd->bltin_nodes+33)
|
||||
#define LANGNOD (shgd->bltin_nodes+34)
|
||||
#define LCALLNOD (shgd->bltin_nodes+35)
|
||||
#define LCCOLLNOD (shgd->bltin_nodes+36)
|
||||
#define LCTYPENOD (shgd->bltin_nodes+37)
|
||||
#define LCMSGNOD (shgd->bltin_nodes+38)
|
||||
#define LCNUMNOD (shgd->bltin_nodes+39)
|
||||
#define LCTIMENOD (shgd->bltin_nodes+40)
|
||||
#define FIGNORENOD (shgd->bltin_nodes+41)
|
||||
#define VERSIONNOD (shgd->bltin_nodes+42)
|
||||
#define JOBMAXNOD (shgd->bltin_nodes+43)
|
||||
#define DOTSHNOD (shgd->bltin_nodes+44)
|
||||
#define ED_CHRNOD (shgd->bltin_nodes+45)
|
||||
#define ED_COLNOD (shgd->bltin_nodes+46)
|
||||
#define ED_TXTNOD (shgd->bltin_nodes+47)
|
||||
#define ED_MODENOD (shgd->bltin_nodes+48)
|
||||
#define SH_NAMENOD (shgd->bltin_nodes+49)
|
||||
#define SH_SUBSCRNOD (shgd->bltin_nodes+50)
|
||||
#define SH_VALNOD (shgd->bltin_nodes+51)
|
||||
#define SH_VERSIONNOD (shgd->bltin_nodes+52)
|
||||
#define SH_DOLLARNOD (shgd->bltin_nodes+53)
|
||||
#define SH_MATCHNOD (shgd->bltin_nodes+54)
|
||||
#define SH_COMMANDNOD (shgd->bltin_nodes+55)
|
||||
#define SH_PATHNAMENOD (shgd->bltin_nodes+56)
|
||||
#define SH_FUNNAMENOD (shgd->bltin_nodes+57)
|
||||
#define SH_SUBSHELLNOD (shgd->bltin_nodes+58)
|
||||
#define SH_LEVELNOD (shgd->bltin_nodes+59)
|
||||
#define SH_LINENO (shgd->bltin_nodes+60)
|
||||
#define SH_STATS (shgd->bltin_nodes+61)
|
||||
#define SH_MATHNOD (shgd->bltin_nodes+62)
|
||||
#define SH_JOBPOOL (shgd->bltin_nodes+63)
|
||||
#define SH_PIDNOD (shgd->bltin_nodes+64)
|
||||
#define SH_TILDENOD (shgd->bltin_nodes+65)
|
||||
#define SHLVL (shgd->bltin_nodes+66)
|
||||
#define PATHNOD (sh.bltin_nodes)
|
||||
#define PS1NOD (sh.bltin_nodes+1)
|
||||
#define PS2NOD (sh.bltin_nodes+2)
|
||||
#define IFSNOD (sh.bltin_nodes+3)
|
||||
#define PWDNOD (sh.bltin_nodes+4)
|
||||
#define HOME (sh.bltin_nodes+5)
|
||||
#define MAILNOD (sh.bltin_nodes+6)
|
||||
#define REPLYNOD (sh.bltin_nodes+7)
|
||||
#define SHELLNOD (sh.bltin_nodes+8)
|
||||
#define EDITNOD (sh.bltin_nodes+9)
|
||||
#define MCHKNOD (sh.bltin_nodes+10)
|
||||
#define RANDNOD (sh.bltin_nodes+11)
|
||||
#define ENVNOD (sh.bltin_nodes+12)
|
||||
#define HISTFILE (sh.bltin_nodes+13)
|
||||
#define HISTSIZE (sh.bltin_nodes+14)
|
||||
#define HISTEDIT (sh.bltin_nodes+15)
|
||||
#define HISTCUR (sh.bltin_nodes+16)
|
||||
#define FCEDNOD (sh.bltin_nodes+17)
|
||||
#define CDPNOD (sh.bltin_nodes+18)
|
||||
#define MAILPNOD (sh.bltin_nodes+19)
|
||||
#define PS3NOD (sh.bltin_nodes+20)
|
||||
#define OLDPWDNOD (sh.bltin_nodes+21)
|
||||
#define VISINOD (sh.bltin_nodes+22)
|
||||
#define COLUMNS (sh.bltin_nodes+23)
|
||||
#define LINES (sh.bltin_nodes+24)
|
||||
#define PPIDNOD (sh.bltin_nodes+25)
|
||||
#define L_ARGNOD (sh.bltin_nodes+26)
|
||||
#define TMOUTNOD (sh.bltin_nodes+27)
|
||||
#define SECONDS (sh.bltin_nodes+28)
|
||||
#define LINENO (sh.bltin_nodes+29)
|
||||
#define OPTARGNOD (sh.bltin_nodes+30)
|
||||
#define OPTINDNOD (sh.bltin_nodes+31)
|
||||
#define PS4NOD (sh.bltin_nodes+32)
|
||||
#define FPATHNOD (sh.bltin_nodes+33)
|
||||
#define LANGNOD (sh.bltin_nodes+34)
|
||||
#define LCALLNOD (sh.bltin_nodes+35)
|
||||
#define LCCOLLNOD (sh.bltin_nodes+36)
|
||||
#define LCTYPENOD (sh.bltin_nodes+37)
|
||||
#define LCMSGNOD (sh.bltin_nodes+38)
|
||||
#define LCNUMNOD (sh.bltin_nodes+39)
|
||||
#define LCTIMENOD (sh.bltin_nodes+40)
|
||||
#define FIGNORENOD (sh.bltin_nodes+41)
|
||||
#define VERSIONNOD (sh.bltin_nodes+42)
|
||||
#define JOBMAXNOD (sh.bltin_nodes+43)
|
||||
#define DOTSHNOD (sh.bltin_nodes+44)
|
||||
#define ED_CHRNOD (sh.bltin_nodes+45)
|
||||
#define ED_COLNOD (sh.bltin_nodes+46)
|
||||
#define ED_TXTNOD (sh.bltin_nodes+47)
|
||||
#define ED_MODENOD (sh.bltin_nodes+48)
|
||||
#define SH_NAMENOD (sh.bltin_nodes+49)
|
||||
#define SH_SUBSCRNOD (sh.bltin_nodes+50)
|
||||
#define SH_VALNOD (sh.bltin_nodes+51)
|
||||
#define SH_VERSIONNOD (sh.bltin_nodes+52)
|
||||
#define SH_DOLLARNOD (sh.bltin_nodes+53)
|
||||
#define SH_MATCHNOD (sh.bltin_nodes+54)
|
||||
#define SH_COMMANDNOD (sh.bltin_nodes+55)
|
||||
#define SH_PATHNAMENOD (sh.bltin_nodes+56)
|
||||
#define SH_FUNNAMENOD (sh.bltin_nodes+57)
|
||||
#define SH_SUBSHELLNOD (sh.bltin_nodes+58)
|
||||
#define SH_LEVELNOD (sh.bltin_nodes+59)
|
||||
#define SH_LINENO (sh.bltin_nodes+60)
|
||||
#define SH_STATS (sh.bltin_nodes+61)
|
||||
#define SH_MATHNOD (sh.bltin_nodes+62)
|
||||
#define SH_JOBPOOL (sh.bltin_nodes+63)
|
||||
#define SH_PIDNOD (sh.bltin_nodes+64)
|
||||
#define SH_TILDENOD (sh.bltin_nodes+65)
|
||||
#define SHLVL (sh.bltin_nodes+66)
|
||||
|
||||
#endif /* SH_VALNOD */
|
||||
|
|
|
@ -83,7 +83,6 @@ static const int flagval[] =
|
|||
|
||||
typedef struct _arg_
|
||||
{
|
||||
Shell_t *sh;
|
||||
struct dolnod *argfor; /* linked list of blocks to be cleaned up */
|
||||
struct dolnod *dolh;
|
||||
char flagadr[NUM_OPTS+1];
|
||||
|
@ -92,18 +91,16 @@ typedef struct _arg_
|
|||
#endif /* SHOPT_KIA */
|
||||
} Arg_t;
|
||||
|
||||
static int arg_expand(Shell_t*,struct argnod*,struct argnod**,int);
|
||||
static void sh_argset(Arg_t*, char *[]);
|
||||
static int arg_expand(struct argnod*,struct argnod**,int);
|
||||
static void argset(Arg_t*, char *[]);
|
||||
static void applyopts(Shopt_t);
|
||||
|
||||
|
||||
/* ======== option handling ======== */
|
||||
|
||||
void *sh_argopen(Shell_t *shp)
|
||||
void *sh_argopen(void)
|
||||
{
|
||||
void *addr = sh_newof(0,Arg_t,1,0);
|
||||
Arg_t *ap = (Arg_t*)addr;
|
||||
ap->sh = shp;
|
||||
return(addr);
|
||||
return(sh_newof(0,Arg_t,1,0));
|
||||
}
|
||||
|
||||
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
|
||||
* 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 Arg_t *ap = (Arg_t*)(shp->arg_context);
|
||||
register Arg_t *ap = (Arg_t*)(sh.arg_context);
|
||||
#if SHOPT_KIA
|
||||
Lex_t *lp = (Lex_t*)(shp->lex_context);
|
||||
Lex_t *lp = (Lex_t*)(sh.lex_context);
|
||||
#endif
|
||||
Shopt_t newflags;
|
||||
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;
|
||||
int verbose,f;
|
||||
Optdisc_t disc;
|
||||
newflags=ap->sh->options;
|
||||
newflags=sh.options;
|
||||
memset(&disc, 0, sizeof(disc));
|
||||
disc.version = OPT_VERSION;
|
||||
disc.infof = infof;
|
||||
|
@ -150,7 +146,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
switch(n)
|
||||
{
|
||||
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)
|
||||
nv_unset(np);
|
||||
continue;
|
||||
|
@ -193,9 +189,9 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
goto skip;
|
||||
case 'T':
|
||||
if (opt_info.num)
|
||||
ap->sh->test |= opt_info.num;
|
||||
sh.test |= opt_info.num;
|
||||
else
|
||||
ap->sh->test = 0;
|
||||
sh.test = 0;
|
||||
continue;
|
||||
case 's':
|
||||
if(setflag)
|
||||
|
@ -263,7 +259,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
on_option(&newflags,SH_LETOCTAL);
|
||||
}
|
||||
on_option(&newflags,o);
|
||||
off_option(&ap->sh->offoptions,o);
|
||||
off_option(&sh.offoptions,o);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -283,7 +279,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
trace = 0;
|
||||
off_option(&newflags,o);
|
||||
if(setflag==0)
|
||||
on_option(&ap->sh->offoptions,o);
|
||||
on_option(&sh.offoptions,o);
|
||||
}
|
||||
}
|
||||
if(error_info.errors)
|
||||
|
@ -301,7 +297,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
trace = 0;
|
||||
}
|
||||
if(trace)
|
||||
sh_trace(shp,argv,1);
|
||||
sh_trace(argv,1);
|
||||
argc -= opt_info.index;
|
||||
argv += opt_info.index;
|
||||
if(action==PRINT)
|
||||
|
@ -313,7 +309,7 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
if(argc>0)
|
||||
strsort(argv,argc,strcoll);
|
||||
else
|
||||
strsort(ap->sh->st.dolv+1,ap->sh->st.dolc,strcoll);
|
||||
strsort(sh.st.dolv+1,sh.st.dolc,strcoll);
|
||||
}
|
||||
if(np)
|
||||
{
|
||||
|
@ -321,11 +317,11 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
nv_close(np);
|
||||
}
|
||||
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))
|
||||
{
|
||||
if(!(ap->sh->comdiv = *argv++))
|
||||
if(!(sh.comdiv = *argv++))
|
||||
{
|
||||
errormsg(SH_DICT,2,e_cneedsarg);
|
||||
errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
|
||||
|
@ -333,8 +329,8 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
}
|
||||
argc--;
|
||||
}
|
||||
/* SH_INTERACTIVE and SH_PRIVILEGED are handled in sh_applyopts() */
|
||||
sh_applyopts(ap->sh,newflags);
|
||||
/* SH_INTERACTIVE and SH_PRIVILEGED are handled in applyopts() */
|
||||
applyopts(newflags);
|
||||
#if SHOPT_KIA
|
||||
if(ap->kiafile)
|
||||
{
|
||||
|
@ -370,28 +366,29 @@ int sh_argopts(int argc,register char *argv[], void *context)
|
|||
|
||||
/* 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 */
|
||||
if(sh_isoption(SH_INTERACTIVE))
|
||||
off_option(&newflags,SH_NOEXEC);
|
||||
if(is_option(&newflags,SH_PRIVILEGED))
|
||||
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))
|
||||
{
|
||||
setuid(shp->gd->userid);
|
||||
setgid(shp->gd->groupid);
|
||||
if(shp->gd->euserid==0)
|
||||
setuid(sh.userid);
|
||||
setgid(sh.groupid);
|
||||
if(sh.euserid==0)
|
||||
{
|
||||
shp->gd->euserid = shp->gd->userid;
|
||||
shp->gd->egroupid = shp->gd->groupid;
|
||||
sh.euserid = sh.userid;
|
||||
sh.egroupid = sh.groupid;
|
||||
}
|
||||
}
|
||||
else if((shp->gd->userid!=shp->gd->euserid && setuid(shp->gd->euserid)<0) ||
|
||||
(shp->gd->groupid!=shp->gd->egroupid && setgid(shp->gd->egroupid)<0) ||
|
||||
(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid))
|
||||
else if((sh.userid!=sh.euserid && setuid(sh.euserid)<0) ||
|
||||
(sh.groupid!=sh.egroupid && setgid(sh.egroupid)<0) ||
|
||||
(sh.userid==sh.euserid && sh.groupid==sh.egroupid))
|
||||
off_option(&newflags,SH_PRIVILEGED);
|
||||
}
|
||||
/* 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);
|
||||
else if(sh_isoption(SH_MONITOR) && !is_option(&newflags,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
|
||||
*/
|
||||
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);
|
||||
/* link into chain */
|
||||
ap->dolh->dolnxt = ap->argfor;
|
||||
ap->argfor = ap->dolh;
|
||||
ap->sh->st.dolc = ap->dolh->dolnum-1;
|
||||
ap->sh->st.dolv = ap->dolh->dolval;
|
||||
sh.st.dolc = ap->dolh->dolnum-1;
|
||||
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
|
||||
* 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* argblk;
|
||||
register Arg_t *ap = (Arg_t*)shp->arg_context;
|
||||
register Arg_t *ap = (Arg_t*)sh.arg_context;
|
||||
if(argblk=argr)
|
||||
{
|
||||
if((--argblk->dolrefcnt)==0)
|
||||
|
@ -507,39 +504,39 @@ struct dolnod *sh_argcreate(register char *argv[])
|
|||
/*
|
||||
* 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;
|
||||
*savargfor = ap->argfor;
|
||||
ap->dolh = 0;
|
||||
ap->argfor = 0;
|
||||
sh_argset(ap,argi);
|
||||
argset(ap,argi);
|
||||
return(olddolh);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
while(ap->argfor=sh_argfree(shp,ap->argfor,0));
|
||||
register Arg_t *ap = (Arg_t*)sh.arg_context;
|
||||
while(ap->argfor=sh_argfree(ap->argfor,0));
|
||||
ap->argfor = afor;
|
||||
if(ap->dolh = blk)
|
||||
{
|
||||
shp->st.dolc = ap->dolh->dolnum-1;
|
||||
shp->st.dolv = ap->dolh->dolval;
|
||||
sh.st.dolc = ap->dolh->dolnum-1;
|
||||
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 Arg_t *ap = (Arg_t*)shp->arg_context;
|
||||
register Arg_t *ap = (Arg_t*)sh.arg_context;
|
||||
if(dh=ap->dolh)
|
||||
dh->dolrefcnt++;
|
||||
return(dh);
|
||||
|
@ -639,11 +636,11 @@ void sh_printopts(Shopt_t oflags,register int mode, Shopt_t *mask)
|
|||
/*
|
||||
* 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;
|
||||
struct argnod *arghead=0;
|
||||
shp->xargmin = 0;
|
||||
sh.xargmin = 0;
|
||||
{
|
||||
register const struct comnod *ac = comptr;
|
||||
register int n;
|
||||
|
@ -659,19 +656,19 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
|
|||
*nargs = ap->dolnum;
|
||||
return(ap->dolval+ap->dolbot);
|
||||
}
|
||||
shp->lastpath = 0;
|
||||
sh.lastpath = 0;
|
||||
*nargs = 0;
|
||||
if(ac)
|
||||
{
|
||||
argp = ac->comarg;
|
||||
while(argp)
|
||||
{
|
||||
n = arg_expand(shp,argp,&arghead,flag);
|
||||
n = arg_expand(argp,&arghead,flag);
|
||||
if(n>1)
|
||||
{
|
||||
if(shp->xargmin==0)
|
||||
shp->xargmin = *nargs;
|
||||
shp->xargmax = *nargs+n;
|
||||
if(sh.xargmin==0)
|
||||
sh.xargmin = *nargs;
|
||||
sh.xargmax = *nargs+n;
|
||||
}
|
||||
*nargs += n;
|
||||
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 */
|
||||
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;
|
||||
*comargn = NIL(char*);
|
||||
if(!argp)
|
||||
|
@ -710,7 +707,7 @@ char **sh_argbuild(Shell_t *shp,int *nargs, const struct comnod *comptr,int flag
|
|||
comargm = comargn;
|
||||
}
|
||||
}
|
||||
shp->last_table = 0;
|
||||
sh.last_table = 0;
|
||||
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)
|
||||
#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) */
|
||||
register struct argnod *ap;
|
||||
int fd, pv[3];
|
||||
int savestates = sh_getstate();
|
||||
char savejobcontrol = job.jobcontrol;
|
||||
unsigned int savesubshell = shp->subshell;
|
||||
ap = (struct argnod*)stkseek(shp->stk,ARGVAL);
|
||||
unsigned int savesubshell = sh.subshell;
|
||||
ap = (struct argnod*)stkseek(sh.stk,ARGVAL);
|
||||
ap->argflag |= ARG_MAKE;
|
||||
ap->argflag &= ~ARG_RAW;
|
||||
fd = argp->argflag&ARG_RAW;
|
||||
if(fd==0 && shp->subshell)
|
||||
sh_subtmpfile(shp);
|
||||
if(fd==0 && sh.subshell)
|
||||
sh_subtmpfile();
|
||||
#if SHOPT_DEVFD
|
||||
sfwrite(shp->stk,e_devfdNN,8);
|
||||
sfwrite(sh.stk,e_devfdNN,8);
|
||||
pv[2] = 0;
|
||||
sh_pipe(pv);
|
||||
#else
|
||||
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)
|
||||
continue; /* lost race (name conflict or tmp dir change); try again */
|
||||
shp->fifo = 0;
|
||||
sh.fifo = 0;
|
||||
break;
|
||||
}
|
||||
if(!shp->fifo)
|
||||
if(!sh.fifo)
|
||||
{
|
||||
errormsg(SH_DICT, ERROR_SYSTEM|ERROR_PANIC, "process substitution: FIFO creation failed");
|
||||
UNREACHABLE();
|
||||
}
|
||||
chmod(shp->fifo,S_IRUSR|S_IWUSR); /* mkfifo + chmod works regardless of umask */
|
||||
sfputr(shp->stk,shp->fifo,0);
|
||||
chmod(sh.fifo,S_IRUSR|S_IWUSR); /* mkfifo + chmod works regardless of umask */
|
||||
sfputr(sh.stk,sh.fifo,0);
|
||||
#endif /* SHOPT_DEVFD */
|
||||
sfputr(shp->stk,fmtbase((long)pv[fd],10,0),0);
|
||||
ap = (struct argnod*)stkfreeze(shp->stk,0);
|
||||
shp->inpipe = shp->outpipe = 0;
|
||||
sfputr(sh.stk,fmtbase((long)pv[fd],10,0),0);
|
||||
ap = (struct argnod*)stkfreeze(sh.stk,0);
|
||||
sh.inpipe = sh.outpipe = 0;
|
||||
/* turn off job control */
|
||||
sh_offstate(SH_INTERACTIVE);
|
||||
sh_offstate(SH_MONITOR);
|
||||
sh_offstate(SH_PROFILE);
|
||||
job.jobcontrol = 0;
|
||||
/* run the process substitution */
|
||||
shp->subshell = 0;
|
||||
sh.subshell = 0;
|
||||
if(fd)
|
||||
shp->inpipe = pv;
|
||||
sh.inpipe = pv;
|
||||
else
|
||||
shp->outpipe = pv;
|
||||
sh.outpipe = pv;
|
||||
sh_exec((Shnode_t*)argp->argchn.ap,(int)sh_isstate(SH_ERREXIT));
|
||||
/* restore the previous state */
|
||||
shp->subshell = savesubshell;
|
||||
sh.subshell = savesubshell;
|
||||
job.jobcontrol = savejobcontrol;
|
||||
sh_setstate(savestates);
|
||||
#if SHOPT_DEVFD
|
||||
sh_close(pv[1-fd]);
|
||||
sh_iosave(shp,-pv[fd], shp->topfd, (char*)0);
|
||||
sh_iosave(-pv[fd], sh.topfd, (char*)0);
|
||||
#else
|
||||
/* remember the FIFO for cleanup in case the command never opens it (see fifo_cleanup(), xec.c) */
|
||||
if(!shp->fifo_tree)
|
||||
shp->fifo_tree = dtopen(&_Nvdisc,Dtoset);
|
||||
nv_search(shp->fifo,shp->fifo_tree,NV_ADD);
|
||||
free(shp->fifo);
|
||||
shp->fifo = 0;
|
||||
if(!sh.fifo_tree)
|
||||
sh.fifo_tree = dtopen(&_Nvdisc,Dtoset);
|
||||
nv_search(sh.fifo,sh.fifo_tree,NV_ADD);
|
||||
free(sh.fifo);
|
||||
sh.fifo = 0;
|
||||
#endif /* SHOPT_DEVFD */
|
||||
return(ap);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
argp->argflag &= ~ARG_MAKE;
|
||||
if(*argp->argval==0 && (argp->argflag&ARG_EXP))
|
||||
{
|
||||
struct argnod *ap;
|
||||
ap = sh_argprocsub(shp,argp);
|
||||
ap = sh_argprocsub(argp);
|
||||
ap->argchn.ap = *argchain;
|
||||
*argchain = ap;
|
||||
count++;
|
||||
|
@ -819,7 +816,7 @@ static int arg_expand(Shell_t *shp,register struct argnod *argp, struct argnod *
|
|||
}
|
||||
else
|
||||
#endif /* SHOPT_OPTIMIZE */
|
||||
count = sh_macexpand(shp,argp,argchain,flag);
|
||||
count = sh_macexpand(argp,argchain,flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -62,11 +62,10 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
|
|||
register int flag = lvalue->flag;
|
||||
register char *sub=0, *cp=(char*)np;
|
||||
register Namval_t *mp;
|
||||
Shell_t *shp = lvalue->shp;
|
||||
int c=0,nosub = lvalue->nosub;
|
||||
Dt_t *sdict = (shp->st.real_fun? shp->st.real_fun->sdict:0);
|
||||
Dt_t *nsdict = (shp->namespace?nv_dict(shp->namespace):0);
|
||||
Dt_t *root = shp->var_tree;
|
||||
Dt_t *sdict = (sh.st.real_fun? sh.st.real_fun->sdict:0);
|
||||
Dt_t *nsdict = (sh.namespace?nv_dict(sh.namespace):0);
|
||||
Dt_t *root = sh.var_tree;
|
||||
assign = assign?NV_ASSIGN:NV_NOASSIGN;
|
||||
lvalue->nosub = 0;
|
||||
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 */
|
||||
int c = cp[flag];
|
||||
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;
|
||||
nv_onattr(&FunNode,NV_NOFREE|NV_LDOUBLE|NV_RDONLY);
|
||||
cp[flag] = c;
|
||||
return(&FunNode);
|
||||
}
|
||||
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;
|
||||
if(!np)
|
||||
return(0);
|
||||
root = shp->last_root;
|
||||
root = sh.last_root;
|
||||
if(cp[flag+1]=='[')
|
||||
flag++;
|
||||
else
|
||||
|
@ -156,13 +156,13 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
|
|||
*cp = 0;
|
||||
if(c || hasdot)
|
||||
{
|
||||
sfprintf(shp->strbuf,"%s%s%c",nv_name(np),sub,0);
|
||||
sub = sfstruse(shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%s%s%c",nv_name(np),sub,0);
|
||||
sub = sfstruse(sh.strbuf);
|
||||
}
|
||||
*cp = flag;
|
||||
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);
|
||||
}
|
||||
#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)
|
||||
{
|
||||
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)))
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = lvalue->shp;
|
||||
register Sfdouble_t r= 0;
|
||||
char *str = (char*)*ptr;
|
||||
register char *cp;
|
||||
|
@ -293,14 +292,14 @@ static Sfdouble_t arith(const char **ptr, struct lval *lvalue, int type, Sfdoubl
|
|||
}
|
||||
if(c=='(')
|
||||
{
|
||||
int off=stktell(shp->stk);
|
||||
int off=stktell(sh.stk);
|
||||
int fsize = str- (char*)(*ptr);
|
||||
const struct mathtab *tp;
|
||||
c = **ptr;
|
||||
lvalue->fun = 0;
|
||||
sfprintf(shp->stk,".sh.math.%.*s%c",fsize,*ptr,0);
|
||||
stkseek(shp->stk,off);
|
||||
if(np=nv_search(stkptr(shp->stk,off),shp->fun_tree,0))
|
||||
sfprintf(sh.stk,".sh.math.%.*s%c",fsize,*ptr,0);
|
||||
stkseek(sh.stk,off);
|
||||
if(np=nv_search(stkptr(sh.stk,off),sh.fun_tree,0))
|
||||
{
|
||||
lvalue->nargs = -np->nvalue.rp->argc;
|
||||
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();
|
||||
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;
|
||||
cp = str;
|
||||
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);
|
||||
lvalue->eflag = 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 */
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
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)
|
||||
{
|
||||
d = 0.0;
|
||||
|
@ -558,14 +556,14 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
|
|||
if(sh_isstate(SH_INIT))
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
d = 0.0;
|
||||
else
|
||||
{
|
||||
if(!last || *last!='.' || last[1]!='.')
|
||||
d = strval(shp,str,&last,arith,mode);
|
||||
d = arith_strval(str,&last,arith,mode);
|
||||
if(!ptr && *last && mode>0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void *sh_arithcomp(Shell_t *shp,register char *str)
|
||||
void *sh_arithcomp(register char *str)
|
||||
{
|
||||
const char *ptr = str;
|
||||
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)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*ptr,str);
|
||||
|
|
|
@ -1194,7 +1194,7 @@ Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode)
|
|||
size = nv_getnum(mp);
|
||||
}
|
||||
else
|
||||
size = (int)sh_arith(&sh,(char*)sp);
|
||||
size = (int)sh_arith((char*)sp);
|
||||
}
|
||||
if(size <0 && ap)
|
||||
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->incr = fp->max+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)
|
||||
{
|
||||
cp = nv_endsubscript(np,ep,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)
|
||||
{
|
||||
free((void*)ap);
|
||||
|
@ -1454,7 +1454,7 @@ static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
|
|||
}
|
||||
else
|
||||
fp->curi = 0;
|
||||
size = (int)sh_arith(&sh,(char*)sub);
|
||||
size = (int)sh_arith((char*)sub);
|
||||
fp->cur[n] = size;
|
||||
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[-1]=0;
|
||||
size = (int)sh_arith(&sh,(char*)ep+1);
|
||||
size = (int)sh_arith((char*)ep+1);
|
||||
if(size >= fp->max[n] || (size < 0))
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np));
|
||||
|
|
|
@ -54,10 +54,9 @@ static int scantree(Dt_t*,const char*, struct argnod**);
|
|||
|
||||
static char *nextdir(glob_t *gp, char *dir)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
Pathcomp_t *pp = (Pathcomp_t*)gp->gl_handle;
|
||||
if(!dir)
|
||||
pp = path_get(shp,"");
|
||||
pp = path_get(Empty);
|
||||
else
|
||||
pp = pp->next;
|
||||
gp->gl_handle = (void*)pp;
|
||||
|
@ -66,7 +65,7 @@ static char *nextdir(glob_t *gp, char *dir)
|
|||
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;
|
||||
register struct argnod *ap;
|
||||
|
@ -85,23 +84,23 @@ int path_expand(Shell_t *shp,const char *pattern, struct argnod **arghead)
|
|||
#endif
|
||||
if(sh_isstate(SH_COMPLETE)) /* command completion */
|
||||
{
|
||||
extra += scantree(shp->alias_tree,pattern,arghead);
|
||||
extra += scantree(shp->fun_tree,pattern,arghead);
|
||||
extra += scantree(sh.alias_tree,pattern,arghead);
|
||||
extra += scantree(sh.fun_tree,pattern,arghead);
|
||||
gp->gl_nextdir = nextdir;
|
||||
flags |= GLOB_COMPLETE;
|
||||
flags &= ~GLOB_NOCHECK;
|
||||
}
|
||||
if(sh_isstate(SH_FCOMPLETE)) /* file name completion */
|
||||
flags |= GLOB_FCOMPLETE;
|
||||
gp->gl_fignore = nv_getval(sh_scoped(shp,FIGNORENOD));
|
||||
gp->gl_fignore = nv_getval(sh_scoped(FIGNORENOD));
|
||||
if(suflen)
|
||||
gp->gl_suffix = sufstr;
|
||||
gp->gl_intr = &shp->trapnote;
|
||||
gp->gl_intr = &sh.trapnote;
|
||||
suflen = 0;
|
||||
if(memcmp(pattern,"~(N",3)==0)
|
||||
flags &= ~GLOB_NOCHECK;
|
||||
glob(pattern, flags, 0, gp);
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
for(ap= (struct argnod*)gp->gl_list; ap; 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
|
||||
*/
|
||||
|
||||
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;
|
||||
suflen = strlen(suffix);
|
||||
return(path_expand(shp,name,arghead));
|
||||
return(path_expand(name,arghead));
|
||||
}
|
||||
|
||||
#if SHOPT_BRACEPAT
|
||||
|
@ -160,7 +159,7 @@ static int checkfmt(Sfio_t* sp, void* vp, Sffmt_t* fp)
|
|||
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;
|
||||
return count satisfying count>=1;
|
||||
|
@ -286,7 +285,7 @@ again:
|
|||
{
|
||||
apin = ap->argchn.ap;
|
||||
if(!sh_isoption(SH_NOGLOB))
|
||||
brace=path_expand(shp,ap->argval,arghead);
|
||||
brace=path_expand(ap->argval,arghead);
|
||||
else
|
||||
{
|
||||
ap->argchn.ap = *arghead;
|
||||
|
@ -347,7 +346,7 @@ endloop1:
|
|||
endloop2:
|
||||
brace = *cp;
|
||||
*cp = 0;
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
ap = (struct argnod*)stakseek(ARGVAL);
|
||||
ap->argflag = ARG_RAW;
|
||||
ap->argchn.ap = todo;
|
||||
|
|
|
@ -62,10 +62,9 @@ static int cursig = -1;
|
|||
*/
|
||||
void sh_fault(register int sig)
|
||||
{
|
||||
register Shell_t *shp = sh_getinterp();
|
||||
register int flag=0;
|
||||
register char *trap;
|
||||
register struct checkpt *pp = (struct checkpt*)shp->jmplist;
|
||||
register struct checkpt *pp = (struct checkpt*)sh.jmplist;
|
||||
int action=0;
|
||||
/* reset handler */
|
||||
if(!(sig&SH_TRAP))
|
||||
|
@ -81,79 +80,79 @@ void sh_fault(register int sig)
|
|||
nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
if(v = rows)
|
||||
nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY);
|
||||
shp->winch++;
|
||||
sh.winch++;
|
||||
}
|
||||
#endif /* SIGWINCH */
|
||||
trap = shp->st.trapcom[sig];
|
||||
if(shp->savesig)
|
||||
trap = sh.st.trapcom[sig];
|
||||
if(sh.savesig)
|
||||
{
|
||||
/* critical region, save and process later */
|
||||
if(!(shp->sigflag[sig]&SH_SIGIGNORE))
|
||||
shp->savesig = sig;
|
||||
if(!(sh.sigflag[sig]&SH_SIGIGNORE))
|
||||
sh.savesig = sig;
|
||||
return;
|
||||
}
|
||||
if(sig==SIGALRM && shp->bltinfun==b_sleep)
|
||||
if(sig==SIGALRM && sh.bltinfun==b_sleep)
|
||||
{
|
||||
if(trap && *trap)
|
||||
{
|
||||
shp->trapnote |= SH_SIGTRAP;
|
||||
shp->sigflag[sig] |= SH_SIGTRAP;
|
||||
sh.trapnote |= SH_SIGTRAP;
|
||||
sh.sigflag[sig] |= SH_SIGTRAP;
|
||||
}
|
||||
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();
|
||||
shp->exitval = 0;
|
||||
sh.exitval = 0;
|
||||
return;
|
||||
}
|
||||
/* handle ignored signals */
|
||||
if(trap && *trap==0)
|
||||
return;
|
||||
flag = shp->sigflag[sig]&~SH_SIGOFF;
|
||||
flag = sh.sigflag[sig]&~SH_SIGOFF;
|
||||
if(!trap)
|
||||
{
|
||||
if(sig==SIGINT && (shp->trapnote&SH_SIGIGNORE))
|
||||
if(sig==SIGINT && (sh.trapnote&SH_SIGIGNORE))
|
||||
return;
|
||||
if(flag&SH_SIGIGNORE)
|
||||
{
|
||||
if(shp->subshell)
|
||||
shp->ignsig = sig;
|
||||
if(sh.subshell)
|
||||
sh.ignsig = sig;
|
||||
sigrelease(sig);
|
||||
return;
|
||||
}
|
||||
if(flag&SH_SIGDONE)
|
||||
{
|
||||
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 */
|
||||
if(sig==SIGTERM && job.in_critical)
|
||||
shp->trapnote |= SH_SIGTERM;
|
||||
sh.trapnote |= SH_SIGTERM;
|
||||
return;
|
||||
}
|
||||
shp->lastsig = sig;
|
||||
sh.lastsig = sig;
|
||||
sigrelease(sig);
|
||||
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
|
||||
pp->mode = SH_JMPEXIT;
|
||||
}
|
||||
if(shp->subshell)
|
||||
if(sh.subshell)
|
||||
sh_exit(SH_EXITSIG);
|
||||
if(sig==SIGABRT || (abortsig(sig) && (ptr = malloc(1))))
|
||||
{
|
||||
if(ptr)
|
||||
free(ptr);
|
||||
sh_done(shp,sig);
|
||||
sh_done(sig);
|
||||
}
|
||||
/* mark signal and continue */
|
||||
shp->trapnote |= SH_SIGSET;
|
||||
if(sig <= shp->gd->sigmax)
|
||||
shp->sigflag[sig] |= SH_SIGSET;
|
||||
sh.trapnote |= SH_SIGSET;
|
||||
if(sig <= sh.sigmax)
|
||||
sh.sigflag[sig] |= SH_SIGSET;
|
||||
#if defined(VMFL)
|
||||
if(abortsig(sig))
|
||||
{
|
||||
|
@ -168,8 +167,8 @@ void sh_fault(register int sig)
|
|||
}
|
||||
}
|
||||
errno = 0;
|
||||
if(pp->mode==SH_JMPCMD || (pp->mode==1 && shp->bltinfun) && !(flag&SH_SIGIGNORE))
|
||||
shp->lastsig = sig;
|
||||
if(pp->mode==SH_JMPCMD || (pp->mode==1 && sh.bltinfun) && !(flag&SH_SIGIGNORE))
|
||||
sh.lastsig = sig;
|
||||
if(trap)
|
||||
{
|
||||
/*
|
||||
|
@ -181,12 +180,12 @@ void sh_fault(register int sig)
|
|||
}
|
||||
else
|
||||
{
|
||||
shp->lastsig = sig;
|
||||
sh.lastsig = sig;
|
||||
flag = SH_SIGSET;
|
||||
#ifdef SIGTSTP
|
||||
if(sig==SIGTSTP)
|
||||
{
|
||||
shp->trapnote |= SH_SIGTSTP;
|
||||
sh.trapnote |= SH_SIGTSTP;
|
||||
if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
|
||||
{
|
||||
sigrelease(sig);
|
||||
|
@ -197,19 +196,19 @@ void sh_fault(register int sig)
|
|||
#endif /* SIGTSTP */
|
||||
}
|
||||
#ifdef ERROR_NOTIFY
|
||||
if((error_info.flags&ERROR_NOTIFY) && shp->bltinfun)
|
||||
action = (*shp->bltinfun)(-sig,(char**)0,(void*)0);
|
||||
if((error_info.flags&ERROR_NOTIFY) && sh.bltinfun)
|
||||
action = (*sh.bltinfun)(-sig,(char**)0,(void*)0);
|
||||
if(action>0)
|
||||
return;
|
||||
#endif
|
||||
if(shp->bltinfun && shp->bltindata.notify)
|
||||
if(sh.bltinfun && sh.bltindata.notify)
|
||||
{
|
||||
shp->bltindata.sigset = 1;
|
||||
sh.bltindata.sigset = 1;
|
||||
return;
|
||||
}
|
||||
shp->trapnote |= flag;
|
||||
if(sig <= shp->gd->sigmax)
|
||||
shp->sigflag[sig] |= flag;
|
||||
sh.trapnote |= flag;
|
||||
if(sig <= sh.sigmax)
|
||||
sh.sigflag[sig] |= flag;
|
||||
if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
|
||||
{
|
||||
if(action<0)
|
||||
|
@ -222,9 +221,8 @@ void sh_fault(register int sig)
|
|||
/*
|
||||
* initialize signal handling
|
||||
*/
|
||||
void sh_siginit(void *ptr)
|
||||
void sh_siginit(void)
|
||||
{
|
||||
Shell_t *shp = (Shell_t*)ptr;
|
||||
register int sig, n;
|
||||
register const struct shtable2 *tp = shtab_signals;
|
||||
sig_begin();
|
||||
|
@ -232,8 +230,8 @@ void sh_siginit(void *ptr)
|
|||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if ((n = SIGRTMIN) > 0 && (sig = SIGRTMAX) > n && sig < SH_TRAP)
|
||||
{
|
||||
shp->gd->sigruntime[SH_SIGRTMIN] = n;
|
||||
shp->gd->sigruntime[SH_SIGRTMAX] = sig;
|
||||
sh.sigruntime[SH_SIGRTMIN] = n;
|
||||
sh.sigruntime[SH_SIGRTMAX] = sig;
|
||||
}
|
||||
#endif /* SIGRTMIN && SIGRTMAX */
|
||||
n = SIGTERM;
|
||||
|
@ -243,29 +241,29 @@ void sh_siginit(void *ptr)
|
|||
if (!(sig-- & SH_TRAP))
|
||||
{
|
||||
if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME)
|
||||
sig = shp->gd->sigruntime[sig];
|
||||
sig = sh.sigruntime[sig];
|
||||
if(sig>n && sig<SH_TRAP)
|
||||
n = sig;
|
||||
}
|
||||
tp++;
|
||||
}
|
||||
shp->gd->sigmax = n++;
|
||||
shp->st.trapcom = (char**)sh_calloc(n,sizeof(char*));
|
||||
shp->sigflag = (unsigned char*)sh_calloc(n,1);
|
||||
shp->gd->sigmsg = (char**)sh_calloc(n,sizeof(char*));
|
||||
sh.sigmax = n++;
|
||||
sh.st.trapcom = (char**)sh_calloc(n,sizeof(char*));
|
||||
sh.sigflag = (unsigned char*)sh_calloc(n,1);
|
||||
sh.sigmsg = (char**)sh_calloc(n,sizeof(char*));
|
||||
for(tp=shtab_signals; sig=tp->sh_number; tp++)
|
||||
{
|
||||
n = (sig>>SH_SIGBITS);
|
||||
if((sig &= ((1<<SH_SIGBITS)-1)) > (shp->gd->sigmax+1))
|
||||
if((sig &= ((1<<SH_SIGBITS)-1)) > (sh.sigmax+1))
|
||||
continue;
|
||||
sig--;
|
||||
if(n&SH_SIGRUNTIME)
|
||||
sig = shp->gd->sigruntime[sig];
|
||||
sig = sh.sigruntime[sig];
|
||||
if(sig>=0)
|
||||
{
|
||||
shp->sigflag[sig] = n;
|
||||
sh.sigflag[sig] = n;
|
||||
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)
|
||||
{
|
||||
register int flag, sig = shgd->sigmax;
|
||||
register int flag, sig = sh.sigmax;
|
||||
sh.sigflag[0] |= SH_SIGFAULT;
|
||||
for(sig=shgd->sigmax; sig>0; sig--)
|
||||
for(sig=sh.sigmax; sig>0; sig--)
|
||||
{
|
||||
flag = sh.sigflag[sig];
|
||||
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
|
||||
*/
|
||||
|
||||
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;
|
||||
if(!(shp->trapnote&~SH_SIGIGNORE))
|
||||
if(!(sh.trapnote&~SH_SIGIGNORE))
|
||||
sig=0;
|
||||
shp->trapnote &= ~SH_SIGTRAP;
|
||||
sh.trapnote &= ~SH_SIGTRAP;
|
||||
/* execute errexit trap first */
|
||||
if(sh_isstate(SH_ERREXIT) && shp->exitval)
|
||||
if(sh_isstate(SH_ERREXIT) && sh.exitval)
|
||||
{
|
||||
int sav_trapnote = shp->trapnote;
|
||||
shp->trapnote &= ~SH_SIGSET;
|
||||
if(shp->st.trap[SH_ERRTRAP])
|
||||
int sav_trapnote = sh.trapnote;
|
||||
sh.trapnote &= ~SH_SIGSET;
|
||||
if(sh.st.trap[SH_ERRTRAP])
|
||||
{
|
||||
trap = shp->st.trap[SH_ERRTRAP];
|
||||
shp->st.trap[SH_ERRTRAP] = 0;
|
||||
trap = sh.st.trap[SH_ERRTRAP];
|
||||
sh.st.trap[SH_ERRTRAP] = 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))
|
||||
{
|
||||
struct checkpt *pp = (struct checkpt*)shp->jmplist;
|
||||
struct checkpt *pp = (struct checkpt*)sh.jmplist;
|
||||
pp->mode = SH_JMPEXIT;
|
||||
sh_exit(shp->exitval);
|
||||
sh_exit(sh.exitval);
|
||||
}
|
||||
}
|
||||
if(shp->sigflag[SIGALRM]&SH_SIGALRM)
|
||||
sh_timetraps(shp);
|
||||
if(sh.sigflag[SIGALRM]&SH_SIGALRM)
|
||||
sh_timetraps();
|
||||
#if SHOPT_BGX
|
||||
if((shp->sigflag[SIGCHLD]&SH_SIGTRAP) && shp->st.trapcom[SIGCHLD])
|
||||
job_chldtrap(shp,shp->st.trapcom[SIGCHLD],1);
|
||||
if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
|
||||
job_chldtrap(sh.st.trapcom[SIGCHLD],1);
|
||||
#endif /* SHOPT_BGX */
|
||||
while(--sig>=0)
|
||||
{
|
||||
|
@ -425,10 +423,10 @@ void sh_chktrap(Shell_t* shp)
|
|||
if(sig==SIGCHLD)
|
||||
continue;
|
||||
#endif /* SHOPT_BGX */
|
||||
if(shp->sigflag[sig]&SH_SIGTRAP)
|
||||
if(sh.sigflag[sig]&SH_SIGTRAP)
|
||||
{
|
||||
shp->sigflag[sig] &= ~SH_SIGTRAP;
|
||||
if(trap=shp->st.trapcom[sig])
|
||||
sh.sigflag[sig] &= ~SH_SIGTRAP;
|
||||
if(trap=sh.st.trapcom[sig])
|
||||
{
|
||||
cursig = sig;
|
||||
sh_trap(trap,0);
|
||||
|
@ -455,8 +453,7 @@ void sh_chktrap(Shell_t* shp)
|
|||
*/
|
||||
int sh_trap(const char *trap, int mode)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
int jmpval, savxit = shp->exitval, savxit_return;
|
||||
int jmpval, savxit = sh.exitval, savxit_return;
|
||||
int was_history = sh_isstate(SH_HISTORY);
|
||||
int was_verbose = sh_isstate(SH_VERBOSE);
|
||||
int staktop = staktell();
|
||||
|
@ -466,8 +463,8 @@ int sh_trap(const char *trap, int mode)
|
|||
fcsave(&savefc);
|
||||
sh_offstate(SH_HISTORY);
|
||||
sh_offstate(SH_VERBOSE);
|
||||
shp->intrap++;
|
||||
sh_pushcontext(shp,&buff,SH_JMPTRAP);
|
||||
sh.intrap++;
|
||||
sh_pushcontext(&sh,&buff,SH_JMPTRAP);
|
||||
jmpval = sigsetjmp(buff.buff,0);
|
||||
if(jmpval == 0)
|
||||
{
|
||||
|
@ -490,16 +487,16 @@ int sh_trap(const char *trap, int mode)
|
|||
else
|
||||
{
|
||||
if(jmpval==SH_JMPEXIT)
|
||||
savxit = shp->exitval;
|
||||
savxit = sh.exitval;
|
||||
jmpval=SH_JMPTRAP;
|
||||
}
|
||||
}
|
||||
sh_popcontext(shp,&buff);
|
||||
shp->intrap--;
|
||||
sfsync(shp->outpool);
|
||||
savxit_return = shp->exitval;
|
||||
sh_popcontext(&sh,&buff);
|
||||
sh.intrap--;
|
||||
sfsync(sh.outpool);
|
||||
savxit_return = sh.exitval;
|
||||
if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
|
||||
shp->exitval=savxit;
|
||||
sh.exitval=savxit;
|
||||
stakset(savptr,staktop);
|
||||
fcrestore(&savefc);
|
||||
if(was_history)
|
||||
|
@ -507,8 +504,8 @@ int sh_trap(const char *trap, int mode)
|
|||
if(was_verbose)
|
||||
sh_onstate(SH_VERBOSE);
|
||||
exitset();
|
||||
if(jmpval>SH_JMPTRAP && (((struct checkpt*)shp->jmpbuffer)->prev || ((struct checkpt*)shp->jmpbuffer)->mode==SH_JMPSCRIPT))
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
if(jmpval>SH_JMPTRAP && (((struct checkpt*)sh.jmpbuffer)->prev || ((struct checkpt*)sh.jmpbuffer)->mode==SH_JMPSCRIPT))
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
return(savxit_return);
|
||||
}
|
||||
|
||||
|
@ -517,86 +514,85 @@ int sh_trap(const char *trap, int mode)
|
|||
*/
|
||||
void sh_exit(register int xno)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
register struct checkpt *pp = (struct checkpt*)shp->jmplist;
|
||||
register struct checkpt *pp = (struct checkpt*)sh.jmplist;
|
||||
register int sig=0;
|
||||
register Sfio_t* pool;
|
||||
/* POSIX requires exit status >= 2 for error in 'test'/'[' */
|
||||
if(xno == 1 && (shp->bltindata.bnode==SYSTEST || shp->bltindata.bnode==SYSBRACKET))
|
||||
shp->exitval = 2;
|
||||
if(xno == 1 && (sh.bltindata.bnode==SYSTEST || sh.bltindata.bnode==SYSBRACKET))
|
||||
sh.exitval = 2;
|
||||
else
|
||||
shp->exitval = xno;
|
||||
sh.exitval = xno;
|
||||
if(xno==SH_EXITSIG)
|
||||
shp->exitval |= (sig=shp->lastsig);
|
||||
sh.exitval |= (sig=sh.lastsig);
|
||||
if(pp && pp->mode>1)
|
||||
cursig = -1;
|
||||
#ifdef SIGTSTP
|
||||
if((shp->trapnote&SH_SIGTSTP) && job.jobcontrol)
|
||||
if((sh.trapnote&SH_SIGTSTP) && job.jobcontrol)
|
||||
{
|
||||
/* ^Z detected by the shell */
|
||||
shp->trapnote = 0;
|
||||
shp->sigflag[SIGTSTP] = 0;
|
||||
if(!shp->subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK))
|
||||
sh.trapnote = 0;
|
||||
sh.sigflag[SIGTSTP] = 0;
|
||||
if(!sh.subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK))
|
||||
return;
|
||||
if(sh_isstate(SH_TIMING))
|
||||
return;
|
||||
/* Handles ^Z for shell builtins, subshells, and functs */
|
||||
shp->lastsig = 0;
|
||||
sh.lastsig = 0;
|
||||
sh_onstate(SH_MONITOR);
|
||||
sh_offstate(SH_STOPOK);
|
||||
shp->trapnote = 0;
|
||||
shp->forked = 1;
|
||||
if(sh_isstate(SH_INTERACTIVE) && (sig=sh_fork(shp,0,NIL(int*))))
|
||||
sh.trapnote = 0;
|
||||
sh.forked = 1;
|
||||
if(sh_isstate(SH_INTERACTIVE) && (sig=sh_fork(0,NIL(int*))))
|
||||
{
|
||||
job.curpgid = 0;
|
||||
job.parent = (pid_t)-1;
|
||||
job_wait(sig);
|
||||
shp->forked = 0;
|
||||
sh.forked = 0;
|
||||
job.parent = 0;
|
||||
shp->sigflag[SIGTSTP] = 0;
|
||||
sh.sigflag[SIGTSTP] = 0;
|
||||
/* wait for child to stop */
|
||||
shp->exitval = (SH_EXITSIG|SIGTSTP);
|
||||
sh.exitval = (SH_EXITSIG|SIGTSTP);
|
||||
/* return to prompt mode */
|
||||
pp->mode = SH_JMPERREXIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(shp->subshell)
|
||||
if(sh.subshell)
|
||||
sh_subfork();
|
||||
/* script or child process; put to sleep */
|
||||
sh_offstate(SH_STOPOK);
|
||||
sh_offstate(SH_MONITOR);
|
||||
shp->sigflag[SIGTSTP] = 0;
|
||||
sh.sigflag[SIGTSTP] = 0;
|
||||
/* stop child job */
|
||||
killpg(job.curpgid,SIGTSTP);
|
||||
/* child resumes */
|
||||
job_clear();
|
||||
shp->exitval = (xno&SH_EXITMASK);
|
||||
sh.exitval = (xno&SH_EXITMASK);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* SIGTSTP */
|
||||
/* unlock output pool */
|
||||
sh_offstate(SH_NOTRACK);
|
||||
if(!(pool=sfpool(NIL(Sfio_t*),shp->outpool,SF_WRITE)))
|
||||
pool = shp->outpool; /* can't happen? */
|
||||
if(!(pool=sfpool(NIL(Sfio_t*),sh.outpool,SF_WRITE)))
|
||||
pool = sh.outpool; /* can't happen? */
|
||||
sfclrlock(pool);
|
||||
#ifdef SIGPIPE
|
||||
if(shp->lastsig==SIGPIPE)
|
||||
if(sh.lastsig==SIGPIPE)
|
||||
sfpurge(pool);
|
||||
#endif /* SIGPIPE */
|
||||
sfclrlock(sfstdin);
|
||||
if(!pp)
|
||||
sh_done(shp,sig);
|
||||
shp->arithrecursion = 0;
|
||||
shp->prefix = 0;
|
||||
sh_done(sig);
|
||||
sh.arithrecursion = 0;
|
||||
sh.prefix = 0;
|
||||
#if SHOPT_TYPEDEF
|
||||
shp->mktype = 0;
|
||||
sh.mktype = 0;
|
||||
#endif /* SHOPT_TYPEDEF */
|
||||
if(job.in_critical)
|
||||
job_unlock();
|
||||
if(pp->mode == SH_JMPSCRIPT && !pp->prev)
|
||||
sh_done(shp,sig);
|
||||
sh_done(sig);
|
||||
if(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
|
||||
*/
|
||||
|
||||
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 int savxit = shp->exitval;
|
||||
shp->trapnote = 0;
|
||||
register int savxit = sh.exitval;
|
||||
sh.trapnote = 0;
|
||||
indone=1;
|
||||
if(sig)
|
||||
savxit = SH_EXITSIG|sig;
|
||||
if(shp->userinit)
|
||||
(*shp->userinit)(shp, -1);
|
||||
if(t=shp->st.trapcom[0])
|
||||
if(sh.userinit)
|
||||
(*sh.userinit)(&sh, -1);
|
||||
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);
|
||||
savxit = shp->exitval;
|
||||
savxit = sh.exitval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* avoid recursive call for set -e */
|
||||
sh_offstate(SH_ERREXIT);
|
||||
sh_chktrap(shp);
|
||||
sh_chktrap();
|
||||
}
|
||||
nv_scan(shp->var_tree,array_notify,(void*)0,NV_ARRAY,NV_ARRAY);
|
||||
sh_freeup(shp);
|
||||
nv_scan(sh.var_tree,array_notify,(void*)0,NV_ARRAY,NV_ARRAY);
|
||||
sh_freeup();
|
||||
#if SHOPT_ACCT
|
||||
sh_accend();
|
||||
#endif /* SHOPT_ACCT */
|
||||
|
@ -654,16 +649,16 @@ noreturn void sh_done(void *ptr, register int sig)
|
|||
tty_cooked(-1);
|
||||
#endif /* SHOPT_VSH || SHOPT_ESH */
|
||||
#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**));
|
||||
#endif /* JOBS */
|
||||
job_close(shp);
|
||||
if(nv_search("VMTRACE", shp->var_tree,0))
|
||||
job_close();
|
||||
if(nv_search("VMTRACE", sh.var_tree,0))
|
||||
strmatch((char*)0,(char*)0);
|
||||
sfsync((Sfio_t*)sfstdin);
|
||||
sfsync((Sfio_t*)shp->outpool);
|
||||
sfsync((Sfio_t*)sh.outpool);
|
||||
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;
|
||||
if(sig)
|
||||
{
|
||||
|
@ -681,12 +676,12 @@ noreturn void sh_done(void *ptr, register int sig)
|
|||
}
|
||||
signal(sig,SIG_DFL);
|
||||
sigrelease(sig);
|
||||
kill(shgd->current_pid,sig);
|
||||
kill(sh.current_pid,sig);
|
||||
pause();
|
||||
}
|
||||
#if SHOPT_KIA
|
||||
if(sh_isoption(SH_NOEXEC))
|
||||
kiaclose((Lex_t*)shp->lex_context);
|
||||
kiaclose((Lex_t*)sh.lex_context);
|
||||
#endif /* SHOPT_KIA */
|
||||
|
||||
/* 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
|
@ -219,34 +219,34 @@ static struct back_save bck;
|
|||
typedef int (*Waitevent_f)(int,long,int);
|
||||
|
||||
#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;
|
||||
pid_t bckpid;
|
||||
int oldexit,trapnote;
|
||||
job_lock();
|
||||
shp->sigflag[SIGCHLD] &= ~SH_SIGTRAP;
|
||||
trapnote = shp->trapnote;
|
||||
shp->trapnote = 0;
|
||||
sh.sigflag[SIGCHLD] &= ~SH_SIGTRAP;
|
||||
trapnote = sh.trapnote;
|
||||
sh.trapnote = 0;
|
||||
for(pw=job.pwlist;pw;pw=pwnext)
|
||||
{
|
||||
pwnext = pw->p_nxtjob;
|
||||
if((pw->p_flag&(P_BG|P_DONE)) != (P_BG|P_DONE))
|
||||
continue;
|
||||
pw->p_flag &= ~P_BG;
|
||||
bckpid = shp->bckpid;
|
||||
oldexit = shp->savexit;
|
||||
shp->bckpid = pw->p_pid;
|
||||
shp->savexit = pw->p_exit;
|
||||
bckpid = sh.bckpid;
|
||||
oldexit = sh.savexit;
|
||||
sh.bckpid = pw->p_pid;
|
||||
sh.savexit = pw->p_exit;
|
||||
if(pw->p_flag&P_SIGNALLED)
|
||||
shp->savexit |= SH_EXITSIG;
|
||||
sh.savexit |= SH_EXITSIG;
|
||||
sh_trap(trap,0);
|
||||
if(pw->p_pid==bckpid && unpost)
|
||||
job_unpost(pw,0);
|
||||
shp->savexit = oldexit;
|
||||
shp->bckpid = bckpid;
|
||||
sh.savexit = oldexit;
|
||||
sh.bckpid = bckpid;
|
||||
}
|
||||
shp->trapnote = trapnote;
|
||||
sh.trapnote = trapnote;
|
||||
job_unlock();
|
||||
}
|
||||
#endif /* SHOPT_BGX */
|
||||
|
@ -258,7 +258,7 @@ static struct jobsave *jobsave_create(pid_t pid)
|
|||
{
|
||||
register struct jobsave *jp = job_savelist;
|
||||
job_chksave(pid);
|
||||
if(++bck.count > shgd->lim.child_max)
|
||||
if(++bck.count > sh.lim.child_max)
|
||||
job_chksave(0);
|
||||
if(jp)
|
||||
{
|
||||
|
@ -283,14 +283,13 @@ static struct jobsave *jobsave_create(pid_t pid)
|
|||
*/
|
||||
int job_reap(register int sig)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
register pid_t pid;
|
||||
register struct process *pw = NIL(struct process*);
|
||||
struct process *px;
|
||||
register int flags;
|
||||
struct jobsave *jp;
|
||||
int nochild=0, oerrno, wstat;
|
||||
Waitevent_f waitevent = shp->gd->waitevent;
|
||||
Waitevent_f waitevent = sh.waitevent;
|
||||
static int wcontinued = WCONTINUED;
|
||||
int was_ttywait_on;
|
||||
if (vmbusy())
|
||||
|
@ -300,7 +299,7 @@ int job_reap(register int sig)
|
|||
abort();
|
||||
}
|
||||
#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);
|
||||
sfsync(sfstderr);
|
||||
#endif /* DEBUG */
|
||||
|
@ -309,7 +308,7 @@ int job_reap(register int sig)
|
|||
flags = WNOHANG|WUNTRACED|wcontinued;
|
||||
else
|
||||
flags = WUNTRACED|wcontinued;
|
||||
shp->gd->waitevent = 0;
|
||||
sh.waitevent = 0;
|
||||
oerrno = errno;
|
||||
was_ttywait_on = sh_isstate(SH_TTYWAIT); /* save tty wait state */
|
||||
while(1)
|
||||
|
@ -331,7 +330,7 @@ int job_reap(register int sig)
|
|||
|
||||
if (pid<0 && errno==EINVAL && (flags&WCONTINUED))
|
||||
pid = waitpid((pid_t)-1,&wstat,flags&=~WCONTINUED);
|
||||
sh_sigcheck(shp);
|
||||
sh_sigcheck();
|
||||
if(pid<0 && errno==EINTR && (sig||job.savesig))
|
||||
{
|
||||
errno = 0;
|
||||
|
@ -348,7 +347,7 @@ int job_reap(register int sig)
|
|||
if(!(pw=job_bypid(pid)))
|
||||
{
|
||||
#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 */
|
||||
if (WIFCONTINUED(wstat) && wcontinued)
|
||||
continue;
|
||||
|
@ -378,7 +377,7 @@ int job_reap(register int sig)
|
|||
pw->p_flag |= (P_NOTIFY|P_SIGNALLED|P_STOPPED);
|
||||
pw->p_exit = WSTOPSIG(wstat);
|
||||
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)
|
||||
{
|
||||
/* move to top of job list */
|
||||
|
@ -392,14 +391,14 @@ int job_reap(register int sig)
|
|||
#endif /* SIGTSTP */
|
||||
{
|
||||
/* check for coprocess completion */
|
||||
if(pid==shp->cpid)
|
||||
if(pid==sh.cpid)
|
||||
{
|
||||
sh_close(sh.coutpipe);
|
||||
sh_close(sh.cpipe[1]);
|
||||
sh.cpipe[1] = -1;
|
||||
sh.coutpipe = -1;
|
||||
}
|
||||
else if(shp->subshell)
|
||||
else if(sh.subshell)
|
||||
sh_subjobcheck(pid);
|
||||
|
||||
pw->p_flag &= ~(P_STOPPED|P_SIGNALLED);
|
||||
|
@ -416,7 +415,7 @@ int job_reap(register int sig)
|
|||
{
|
||||
pw->p_flag &= ~P_NOTIFY;
|
||||
sh_offstate(SH_STOPOK);
|
||||
kill(shgd->current_pid,SIGINT);
|
||||
kill(sh.current_pid,SIGINT);
|
||||
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))
|
||||
{
|
||||
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)
|
||||
job_chldtrap(shp,shp->st.trapcom[SIGCHLD],0);
|
||||
job_chldtrap(sh.st.trapcom[SIGCHLD],0);
|
||||
else
|
||||
shp->trapnote |= SH_SIGTRAP;
|
||||
sh.trapnote |= SH_SIGTRAP;
|
||||
}
|
||||
else
|
||||
pw->p_flag &= ~P_BG;
|
||||
|
@ -453,7 +452,7 @@ int job_reap(register int sig)
|
|||
jp->exitval |= SH_EXITSIG;
|
||||
}
|
||||
#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);
|
||||
#endif /* DEBUG */
|
||||
/* only top-level process in job should have notify set */
|
||||
|
@ -467,10 +466,10 @@ int job_reap(register int sig)
|
|||
tcsetpgrp(JOBTTY,job.mypid);
|
||||
}
|
||||
#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;
|
||||
shp->trapnote |= SH_SIGTRAP;
|
||||
sh.sigflag[SIGCHLD] |= SH_SIGTRAP;
|
||||
sh.trapnote |= SH_SIGTRAP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -482,7 +481,7 @@ int job_reap(register int sig)
|
|||
#endif /* SHOPT_BGX */
|
||||
nochild = 1;
|
||||
}
|
||||
shp->gd->waitevent = waitevent;
|
||||
sh.waitevent = waitevent;
|
||||
if(pw && sh_isoption(SH_NOTIFY) && sh_isstate(SH_TTYWAIT))
|
||||
{
|
||||
outfile = sfstderr;
|
||||
|
@ -513,7 +512,7 @@ static void job_waitsafe(int sig)
|
|||
* initialize job control if possible
|
||||
* 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;
|
||||
job.fd = JOBTTY;
|
||||
|
@ -555,7 +554,7 @@ void job_init(Shell_t *shp, int lflag)
|
|||
register int fd;
|
||||
register char *ttynam;
|
||||
#ifndef SIGTSTP
|
||||
setpgid(0,shp->gd->pid);
|
||||
setpgid(0,sh.pid);
|
||||
#endif /*SIGTSTP */
|
||||
if(sh_isoption(SH_INTERACTIVE))
|
||||
{
|
||||
|
@ -566,12 +565,12 @@ void job_init(Shell_t *shp, int lflag)
|
|||
if((fd = open(ttynam,O_RDWR)) <0)
|
||||
return;
|
||||
if(fd!=JOBTTY)
|
||||
sh_iorenumber(shp,fd,JOBTTY);
|
||||
sh_iorenumber(fd,JOBTTY);
|
||||
#ifdef SIGTSTP
|
||||
tcsetpgrp(JOBTTY,shp->gd->pid);
|
||||
tcsetpgrp(JOBTTY,sh.pid);
|
||||
#endif /* SIGTSTP */
|
||||
}
|
||||
job.mypgid = shp->gd->pid;
|
||||
job.mypgid = sh.pid;
|
||||
}
|
||||
#ifdef SIGTSTP
|
||||
possible = (setpgid(0,job.mypgid) >= 0) || errno==EPERM;
|
||||
|
@ -584,7 +583,7 @@ void job_init(Shell_t *shp, int lflag)
|
|||
return;
|
||||
/* Stop this shell until continued */
|
||||
signal(SIGTTIN,SIG_DFL);
|
||||
kill(shp->gd->pid,SIGTTIN);
|
||||
kill(sh.pid,SIGTTIN);
|
||||
/* resumes here after continue tries again */
|
||||
if(ntry++ > IOMAXTRY)
|
||||
{
|
||||
|
@ -625,8 +624,8 @@ void job_init(Shell_t *shp, int lflag)
|
|||
|
||||
#ifdef SIGTSTP
|
||||
/* make sure that we are a process group leader */
|
||||
setpgid(0,shp->gd->pid);
|
||||
job.mypid = shp->gd->pid;
|
||||
setpgid(0,sh.pid);
|
||||
job.mypid = sh.pid;
|
||||
if(!sh_isoption(SH_INTERACTIVE))
|
||||
return;
|
||||
# if defined(SA_NOCLDSTOP) || defined(SA_NOCLDWAIT)
|
||||
|
@ -642,7 +641,7 @@ void job_init(Shell_t *shp, int lflag)
|
|||
signal(SIGTTOU,SIG_IGN);
|
||||
/* The shell now handles ^Z */
|
||||
signal(SIGTSTP,sh_fault);
|
||||
tcsetpgrp(JOBTTY,shp->gd->pid);
|
||||
tcsetpgrp(JOBTTY,sh.pid);
|
||||
# ifdef CNSUSP
|
||||
/* set the switch character */
|
||||
tty_get(JOBTTY,&my_stty);
|
||||
|
@ -664,7 +663,7 @@ void job_init(Shell_t *shp, int lflag)
|
|||
* see if there are any stopped jobs
|
||||
* restore tty driver and pgrp
|
||||
*/
|
||||
int job_close(Shell_t* shp)
|
||||
int job_close(void)
|
||||
{
|
||||
register struct process *pw;
|
||||
register int count = 0, running = 0;
|
||||
|
@ -672,7 +671,7 @@ int job_close(Shell_t* shp)
|
|||
return(0);
|
||||
else if(!possible && (!sh_isstate(SH_MONITOR) || sh_isstate(SH_FORKED)))
|
||||
return(0);
|
||||
else if(shgd->current_pid != job.mypid)
|
||||
else if(sh.current_pid != job.mypid)
|
||||
return(0);
|
||||
job_lock();
|
||||
if(!tty_check(0))
|
||||
|
@ -696,7 +695,7 @@ int job_close(Shell_t* shp)
|
|||
errormsg(SH_DICT,0,e_terminate);
|
||||
return(-1);
|
||||
}
|
||||
else if(running && shp->login_sh)
|
||||
else if(running && sh.login_sh)
|
||||
{
|
||||
errormsg(SH_DICT,0,e_jobsrunning);
|
||||
return(-1);
|
||||
|
@ -743,7 +742,6 @@ int job_close(Shell_t* shp)
|
|||
|
||||
static void job_set(register struct process *pw)
|
||||
{
|
||||
Shell_t *shp = pw->p_shp;
|
||||
if(!job.jobcontrol)
|
||||
return;
|
||||
/* save current terminal state */
|
||||
|
@ -754,12 +752,12 @@ static void job_set(register struct process *pw)
|
|||
tty_set(job.fd,TCSAFLUSH,&pw->p_stty);
|
||||
}
|
||||
#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);
|
||||
/* if job is stopped, resume it in the background */
|
||||
if(!shp->forked)
|
||||
if(!sh.forked)
|
||||
job_unstop(pw);
|
||||
shp->forked = 0;
|
||||
sh.forked = 0;
|
||||
#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)))
|
||||
{
|
||||
pw = &dummy;
|
||||
pw->p_shp = sh_getinterp();
|
||||
pw->p_pid = 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)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
register struct process *px = pw;
|
||||
register int n;
|
||||
register const char *msg;
|
||||
register int msize;
|
||||
if(!pw || pw->p_job<=0)
|
||||
return(1);
|
||||
if(pw->p_env != shp->jobenv)
|
||||
if(pw->p_env != sh.jobenv)
|
||||
return(0);
|
||||
if((flag&JOB_NFLAG) && (!(px->p_flag&P_NOTIFY)||px->p_pgrp==0))
|
||||
return(0);
|
||||
|
@ -965,7 +961,7 @@ int job_list(struct process *pw,register int flag)
|
|||
px = 0;
|
||||
}
|
||||
if(!px)
|
||||
hist_list(shgd->hist_ptr,outfile,pw->p_name,0,";");
|
||||
hist_list(sh.hist_ptr,outfile,pw->p_name,0,";");
|
||||
else
|
||||
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)
|
||||
{
|
||||
Shell_t *shp;
|
||||
register pid_t pid;
|
||||
register int r;
|
||||
const char *msg;
|
||||
|
@ -1020,14 +1015,13 @@ int job_kill(register struct process *pw,register int sig)
|
|||
errno = ECHILD;
|
||||
if(!pw)
|
||||
goto error; /* not an actual shell job */
|
||||
shp = pw->p_shp;
|
||||
pid = pw->p_pid;
|
||||
if(by_number)
|
||||
{
|
||||
if(pid==0 && job.jobcontrol)
|
||||
r = job_walk(outfile, job_kill,sig, (char**)0);
|
||||
#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 */
|
||||
errno = EPERM;
|
||||
|
@ -1139,13 +1133,12 @@ static struct process *job_byname(char *name)
|
|||
register int *flag = 0;
|
||||
register char *cp = name;
|
||||
int offset;
|
||||
if(!shgd->hist_ptr)
|
||||
if(!sh.hist_ptr)
|
||||
return(NIL(struct process*));
|
||||
if(*cp=='?')
|
||||
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)
|
||||
{
|
||||
|
@ -1171,10 +1164,9 @@ static struct process *job_byname(char *name)
|
|||
|
||||
void job_clear(void)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
register struct process *pw, *px;
|
||||
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;
|
||||
job_lock();
|
||||
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
|
||||
*/
|
||||
|
||||
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 History_t *hp = shp->gd->hist_ptr;
|
||||
register History_t *hp = sh.hist_ptr;
|
||||
#if SHOPT_BGX
|
||||
int val,bg=0;
|
||||
#else
|
||||
int val;
|
||||
#endif
|
||||
shp->jobenv = shp->curenv;
|
||||
sh.jobenv = sh.curenv;
|
||||
if(job.toclear)
|
||||
{
|
||||
job_clear();
|
||||
|
@ -1279,12 +1271,11 @@ int job_post(Shell_t *shp,pid_t pid, pid_t join)
|
|||
}
|
||||
pw->p_exitval = job.exitval;
|
||||
job.pwlist = pw;
|
||||
pw->p_shp = shp;
|
||||
pw->p_env = shp->curenv;
|
||||
pw->p_env = sh.curenv;
|
||||
pw->p_pid = pid;
|
||||
if(!shp->outpipe || shp->cpid==pid)
|
||||
if(!sh.outpipe || sh.cpid==pid)
|
||||
pw->p_flag = P_EXITSAVE;
|
||||
pw->p_exitmin = shp->xargexit;
|
||||
pw->p_exitmin = sh.xargexit;
|
||||
pw->p_exit = 0;
|
||||
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_pgrp = pw->p_fgrp;
|
||||
#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);
|
||||
sfsync(sfstderr);
|
||||
#endif /* DEBUG */
|
||||
#ifdef JOBS
|
||||
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
|
||||
pw->p_name = -1;
|
||||
#endif /* JOBS */
|
||||
|
@ -1398,7 +1389,6 @@ static void job_prmsg(register struct process *pw)
|
|||
|
||||
int job_wait(register pid_t pid)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
register struct process *pw=0,*px;
|
||||
register int jobid = 0;
|
||||
int nochild = 1;
|
||||
|
@ -1423,20 +1413,20 @@ int job_wait(register pid_t pid)
|
|||
}
|
||||
if(pid > 1)
|
||||
{
|
||||
if(pid==shp->spid)
|
||||
shp->spid = 0;
|
||||
if(pid==sh.spid)
|
||||
sh.spid = 0;
|
||||
if(!(pw=job_bypid(pid)))
|
||||
{
|
||||
/* check to see whether job status has been saved */
|
||||
if((shp->exitval = job_chksave(pid)) < 0)
|
||||
shp->exitval = ERROR_NOENT;
|
||||
if((sh.exitval = job_chksave(pid)) < 0)
|
||||
sh.exitval = ERROR_NOENT;
|
||||
exitset();
|
||||
job_unlock();
|
||||
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();
|
||||
return(nochild);
|
||||
}
|
||||
|
@ -1448,16 +1438,16 @@ int job_wait(register pid_t pid)
|
|||
}
|
||||
pwfg = pw;
|
||||
#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)
|
||||
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 */
|
||||
errno = 0;
|
||||
if(shp->coutpipe>=0 && lastpid && shp->cpid==lastpid)
|
||||
if(sh.coutpipe>=0 && lastpid && sh.cpid==lastpid)
|
||||
{
|
||||
sh_close(shp->coutpipe);
|
||||
sh_close(shp->cpipe[1]);
|
||||
shp->cpipe[1] = shp->coutpipe = -1;
|
||||
sh_close(sh.coutpipe);
|
||||
sh_close(sh.cpipe[1]);
|
||||
sh.cpipe[1] = sh.coutpipe = -1;
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
|
@ -1516,9 +1506,9 @@ int job_wait(register pid_t pid)
|
|||
px = 0;
|
||||
if(px)
|
||||
{
|
||||
shp->exitval=px->p_exit;
|
||||
sh.exitval=px->p_exit;
|
||||
if(px->p_flag&P_SIGNALLED)
|
||||
shp->exitval |= SH_EXITSIG;
|
||||
sh.exitval |= SH_EXITSIG;
|
||||
if(intr)
|
||||
px->p_flag &= ~P_EXITSAVE;
|
||||
}
|
||||
|
@ -1537,13 +1527,13 @@ int job_wait(register pid_t pid)
|
|||
continue;
|
||||
if(nochild)
|
||||
break;
|
||||
if(shp->sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
sh_timetraps(shp);
|
||||
if((intr && shp->trapnote) || (pid==1 && !intr))
|
||||
if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
|
||||
sh_timetraps();
|
||||
if((intr && sh.trapnote) || (pid==1 && !intr))
|
||||
break;
|
||||
}
|
||||
if(intr && shp->trapnote)
|
||||
shp->exitval = 1;
|
||||
if(intr && sh.trapnote)
|
||||
sh.exitval = 1;
|
||||
pwfg = 0;
|
||||
job_unlock();
|
||||
if(pid==1)
|
||||
|
@ -1555,13 +1545,13 @@ int job_wait(register pid_t pid)
|
|||
{
|
||||
job_reset(pw);
|
||||
/* propagate keyboard interrupts to parent */
|
||||
if((pw->p_flag&P_SIGNALLED) && pw->p_exit==SIGINT && !(shp->sigflag[SIGINT]&SH_SIGOFF))
|
||||
kill(shgd->current_pid,SIGINT);
|
||||
if((pw->p_flag&P_SIGNALLED) && pw->p_exit==SIGINT && !(sh.sigflag[SIGINT]&SH_SIGOFF))
|
||||
kill(sh.current_pid,SIGINT);
|
||||
#ifdef SIGTSTP
|
||||
else if((pw->p_flag&P_STOPPED) && pw->p_exit==SIGTSTP)
|
||||
{
|
||||
job.parent = 0;
|
||||
kill(shgd->current_pid,SIGTSTP);
|
||||
kill(sh.current_pid,SIGTSTP);
|
||||
}
|
||||
#endif /* SIGTSTP */
|
||||
}
|
||||
|
@ -1578,7 +1568,7 @@ int job_wait(register pid_t pid)
|
|||
done:
|
||||
if(!job.waitall && sh_isoption(SH_PIPEFAIL))
|
||||
return(nochild);
|
||||
if(!shp->intrap)
|
||||
if(!sh.intrap)
|
||||
{
|
||||
job_lock();
|
||||
for(pw=job.pwlist; pw; pw=px)
|
||||
|
@ -1630,7 +1620,7 @@ int job_switch(register struct process *pw,int bgflag)
|
|||
job.pwlist = pw;
|
||||
msg = "";
|
||||
}
|
||||
hist_list(shgd->hist_ptr,outfile,pw->p_name,'&',";");
|
||||
hist_list(sh.hist_ptr,outfile,pw->p_name,'&',";");
|
||||
sfputr(outfile,msg,'\n');
|
||||
sfsync(outfile);
|
||||
if(bgflag=='f')
|
||||
|
@ -1705,7 +1695,7 @@ static struct process *job_unpost(register struct process *pwtop,int notify)
|
|||
register struct process *pw;
|
||||
/* make sure all processes are done */
|
||||
#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);
|
||||
#endif /* DEBUG */
|
||||
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;
|
||||
#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);
|
||||
#endif /* DEBUG */
|
||||
job_free((int)pwtop->p_job);
|
||||
|
@ -1783,13 +1773,13 @@ static int job_alloc(void)
|
|||
register int j=0;
|
||||
register unsigned mask = 1;
|
||||
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 */
|
||||
for(j=0;job.freejobs[j] == UCHAR_MAX; j++);
|
||||
if(j >= jmax)
|
||||
{
|
||||
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))
|
||||
break;
|
||||
|
@ -1821,16 +1811,16 @@ static void job_free(register int n)
|
|||
static char *job_sigmsg(int sig)
|
||||
{
|
||||
static char signo[40];
|
||||
if(sig<=shgd->sigmax && shgd->sigmsg[sig])
|
||||
return(shgd->sigmsg[sig]);
|
||||
if(sig<=sh.sigmax && sh.sigmsg[sig])
|
||||
return(sh.sigmsg[sig]);
|
||||
#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];
|
||||
if(sig>sh.gd->sigruntime[SH_SIGRTMIN]+(sh.gd->sigruntime[SH_SIGRTMAX]-sig<=sh.gd->sigruntime[SH_SIGRTMIN])/2)
|
||||
sfsprintf(sigrt,sizeof(sigrt),"SIGRTMAX-%d",sh.gd->sigruntime[SH_SIGRTMAX]-sig);
|
||||
if(sig>sh.sigruntime[SH_SIGRTMIN]+(sh.sigruntime[SH_SIGRTMAX]-sig<=sh.sigruntime[SH_SIGRTMIN])/2)
|
||||
sfsprintf(sigrt,sizeof(sigrt),"SIGRTMAX-%d",sh.sigruntime[SH_SIGRTMAX]-sig);
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
@ -1925,7 +1915,7 @@ void job_subrestore(void* ptr)
|
|||
bck.list = bp->list;
|
||||
bck.count += bp->count;
|
||||
bck.prev = bp->prev;
|
||||
while(bck.count > shgd->lim.child_max)
|
||||
while(bck.count > sh.lim.child_max)
|
||||
job_chksave(0);
|
||||
for(pw=job.pwlist; pw; pw=pwnext)
|
||||
{
|
||||
|
@ -1949,7 +1939,7 @@ int sh_waitsafe(void)
|
|||
void job_fork(pid_t parent)
|
||||
{
|
||||
#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 */
|
||||
switch (parent)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ local_iswblank(wchar_t wc)
|
|||
#define poplevel(lp) (lp->lexd.lastc=lp->lexd.lex_match[--lp->lexd.level])
|
||||
|
||||
static char *fmttoken(Lex_t*, int);
|
||||
static struct argnod *endword(int);
|
||||
static int alias_exceptf(Sfio_t*, int, void*, Sfdisc_t*);
|
||||
static void setupalias(Lex_t*,const char*, Namval_t*);
|
||||
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)
|
||||
{
|
||||
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());
|
||||
unsigned long r;
|
||||
if(lp->lexd.first)
|
||||
|
@ -92,16 +91,16 @@ static void refvar(Lex_t *lp, int type)
|
|||
}
|
||||
else
|
||||
{
|
||||
int n,offset = stktell(stkp);
|
||||
int n,offset = stktell(sh.stk);
|
||||
char *savptr,*begin;
|
||||
off = offset + (fcseek(0)-(type+1)) - fcfirst();
|
||||
if(lp->lexd.kiaoff < offset)
|
||||
{
|
||||
/* variable starts on stak, copy remainder */
|
||||
if(off>offset)
|
||||
sfwrite(stkp,fcfirst()+type,off-offset);
|
||||
n = stktell(stkp)-lp->lexd.kiaoff;
|
||||
begin = stkptr(stkp,lp->lexd.kiaoff);
|
||||
sfwrite(sh.stk,fcfirst()+type,off-offset);
|
||||
n = stktell(sh.stk)-lp->lexd.kiaoff;
|
||||
begin = stkptr(sh.stk,lp->lexd.kiaoff);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -109,11 +108,11 @@ static void refvar(Lex_t *lp, int type)
|
|||
begin = fcfirst()+(type+lp->lexd.kiaoff-offset);
|
||||
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,"");
|
||||
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 */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
register Lex_t *lp = (Lex_t*)context;
|
||||
register Shell_t *shp = lp->sh;
|
||||
register Sfio_t *log= shp->funlog;
|
||||
Stk_t *stkp = shp->stk;
|
||||
register Sfio_t *log= sh.funlog;
|
||||
/* write to history file and to stderr if necessary */
|
||||
if(iop && !sfstacked(iop))
|
||||
{
|
||||
if(sh_isstate(SH_HISTORY) && shp->gd->hist_ptr)
|
||||
log = shp->gd->hist_ptr->histfp;
|
||||
if(sh_isstate(SH_HISTORY) && sh.hist_ptr)
|
||||
log = sh.hist_ptr->histfp;
|
||||
sfwrite(log, (void*)buff, size);
|
||||
if(sh_isstate(SH_VERBOSE))
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if(sffileno(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);
|
||||
buff = lp->lexd.first;
|
||||
if(!lp->lexd.noarg)
|
||||
lp->arg = (struct argnod*)stkseek(stkp,ARGVAL);
|
||||
lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
|
||||
#if SHOPT_KIA
|
||||
lp->lexd.kiaoff += ARGVAL;
|
||||
#endif /* SHOPT_KIA */
|
||||
}
|
||||
if(size>0 && (lp->arg||lp->lexd.noarg))
|
||||
{
|
||||
sfwrite(stkp,buff,size);
|
||||
sfwrite(sh.stk,buff,size);
|
||||
lp->lexd.first = 0;
|
||||
}
|
||||
}
|
||||
|
@ -201,13 +198,10 @@ static int lexfill(Lex_t *lp)
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
lp = (Lex_t*)sh_newof(0,Lex_t,1,0);
|
||||
lp->sh = sp;
|
||||
}
|
||||
fcnotify(lex_advance,lp);
|
||||
lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 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*);
|
||||
int sh_lex(Lex_t *lp)
|
||||
{
|
||||
Shell_t *shp = lp->sh;
|
||||
register int flag;
|
||||
char *quoted, *macro, *split, *expand;
|
||||
register int tok = lextoken(lp);
|
||||
|
@ -244,7 +237,7 @@ int sh_lex(Lex_t *lp)
|
|||
if(flag&ARG_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));
|
||||
return(tok);
|
||||
}
|
||||
|
@ -258,10 +251,8 @@ int sh_lex(Lex_t *lp)
|
|||
*/
|
||||
int sh_lex(Lex_t* lp)
|
||||
{
|
||||
register Shell_t *shp = lp->sh;
|
||||
register const char *state;
|
||||
register int n, c, mode=ST_BEGIN, wordflags=0;
|
||||
Stk_t *stkp = shp->stk;
|
||||
int inlevel=lp->lexd.level, assignment=0, ingrave=0;
|
||||
int epatchar=0;
|
||||
#if SHOPT_MULTIBYTE
|
||||
|
@ -316,7 +307,7 @@ int sh_lex(Lex_t* lp)
|
|||
else
|
||||
lp->lexd.first = 0;
|
||||
}
|
||||
lp->lastline = lp->sh->inlineno;
|
||||
lp->lastline = sh.inlineno;
|
||||
while(1)
|
||||
{
|
||||
/* skip over characters in the current state */
|
||||
|
@ -342,11 +333,11 @@ int sh_lex(Lex_t* lp)
|
|||
/* check for zero byte in file */
|
||||
if(n==0 && fcfile())
|
||||
{
|
||||
if(shp->readscript)
|
||||
if(sh.readscript)
|
||||
{
|
||||
char *cp = error_info.id;
|
||||
errno = ENOEXEC;
|
||||
error_info.id = shp->readscript;
|
||||
error_info.id = sh.readscript;
|
||||
errormsg(SH_DICT,ERROR_system(ERROR_NOEXEC),e_exec,cp);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -400,10 +391,10 @@ int sh_lex(Lex_t* lp)
|
|||
while(fcgetc(c)>0 && c!='\n');
|
||||
if(c<=0 || lp->heredoc)
|
||||
{
|
||||
shp->inlineno++;
|
||||
sh.inlineno++;
|
||||
break;
|
||||
}
|
||||
while(shp->inlineno++,fcpeek(0)=='\n')
|
||||
while(sh.inlineno++,fcpeek(0)=='\n')
|
||||
fcseek(1);
|
||||
while(state[c=fcpeek(0)]==0)
|
||||
fcseek(1);
|
||||
|
@ -413,7 +404,7 @@ int sh_lex(Lex_t* lp)
|
|||
if(c<0)
|
||||
return(lp->token=EOFSYM);
|
||||
n = S_NLTOK;
|
||||
shp->inlineno--;
|
||||
sh.inlineno--;
|
||||
/* FALLTHROUGH */
|
||||
case S_NLTOK:
|
||||
/* check for here-document */
|
||||
|
@ -421,7 +412,7 @@ int sh_lex(Lex_t* lp)
|
|||
{
|
||||
if(!lp->lexd.dolparen)
|
||||
lp->lexd.nocopy++;
|
||||
c = shp->inlineno;
|
||||
c = sh.inlineno;
|
||||
if(here_copy(lp,lp->heredoc)<=0 && lp->lasttok)
|
||||
{
|
||||
lp->lasttok = IODOCSYM;
|
||||
|
@ -439,7 +430,7 @@ int sh_lex(Lex_t* lp)
|
|||
case S_NL:
|
||||
/* skip over new-lines */
|
||||
lp->lex.last_quote = 0;
|
||||
while(shp->inlineno++,fcget()=='\n');
|
||||
while(sh.inlineno++,fcget()=='\n');
|
||||
fcseek(-LEN);
|
||||
if(n==S_NLTOK)
|
||||
{
|
||||
|
@ -498,7 +489,7 @@ int sh_lex(Lex_t* lp)
|
|||
if(lp->lex.intest)
|
||||
return(c);
|
||||
lp->lexd.nest=1;
|
||||
lp->lastline = shp->inlineno;
|
||||
lp->lastline = sh.inlineno;
|
||||
lp->lexd.lex_state = ST_NESTED;
|
||||
fcseek(1);
|
||||
return(sh_lex(lp));
|
||||
|
@ -568,7 +559,7 @@ int sh_lex(Lex_t* lp)
|
|||
else
|
||||
{
|
||||
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)
|
||||
|
@ -596,7 +587,7 @@ int sh_lex(Lex_t* lp)
|
|||
{
|
||||
Sfio_t *sp;
|
||||
struct argnod *ap;
|
||||
shp->inlineno++;
|
||||
sh.inlineno++;
|
||||
/* synchronize */
|
||||
if(!(sp=fcfile()))
|
||||
state=fcseek(0);
|
||||
|
@ -607,8 +598,8 @@ int sh_lex(Lex_t* lp)
|
|||
else
|
||||
fcsopen((char*)state);
|
||||
/* remove \new-line */
|
||||
n = stktell(stkp)-c;
|
||||
stkseek(stkp,n);
|
||||
n = stktell(sh.stk)-c;
|
||||
stkseek(sh.stk,n);
|
||||
lp->arg = ap;
|
||||
if(n<=ARGVAL)
|
||||
{
|
||||
|
@ -625,7 +616,7 @@ int sh_lex(Lex_t* lp)
|
|||
endchar(lp)==RBRACE &&
|
||||
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 */
|
||||
break;
|
||||
case S_NAME:
|
||||
|
@ -683,7 +674,7 @@ int sh_lex(Lex_t* lp)
|
|||
/* skip new-line joining */
|
||||
if(c=='\\' && fcpeek(0)=='\n')
|
||||
{
|
||||
shp->inlineno++;
|
||||
sh.inlineno++;
|
||||
fcseek(1);
|
||||
continue;
|
||||
}
|
||||
|
@ -718,23 +709,23 @@ int sh_lex(Lex_t* lp)
|
|||
if(oldmode(lp)==ST_QUOTE) /* $' within "" or `` */
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
lp->lex.last_quote = 0;
|
||||
lp->lastline = shp->inlineno;
|
||||
lp->lastline = sh.inlineno;
|
||||
if(mode!=ST_DOL)
|
||||
pushlevel(lp,'\'',mode);
|
||||
mode = ST_LIT;
|
||||
continue;
|
||||
}
|
||||
/* check for multi-line single-quoted string */
|
||||
else if(shp->inlineno > lp->lastline)
|
||||
else if(sh.inlineno > lp->lastline)
|
||||
lp->lex.last_quote = '\'';
|
||||
mode = oldmode(lp);
|
||||
poplevel(lp);
|
||||
|
@ -745,12 +736,12 @@ int sh_lex(Lex_t* lp)
|
|||
{
|
||||
fcgetc(n);
|
||||
if(n=='\n')
|
||||
shp->inlineno++;
|
||||
sh.inlineno++;
|
||||
}
|
||||
continue;
|
||||
case S_GRAVE:
|
||||
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);
|
||||
if(mode==ST_QUOTE)
|
||||
ingrave = !ingrave;
|
||||
|
@ -767,10 +758,10 @@ int sh_lex(Lex_t* lp)
|
|||
{
|
||||
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);
|
||||
lp->lex.last_quote=0;
|
||||
lp->lastline = shp->inlineno;
|
||||
lp->lastline = sh.inlineno;
|
||||
pushlevel(lp,c,mode);
|
||||
}
|
||||
ingrave ^= (c=='`');
|
||||
|
@ -779,7 +770,7 @@ int sh_lex(Lex_t* lp)
|
|||
}
|
||||
else if((n=endchar(lp))==c)
|
||||
{
|
||||
if(shp->inlineno > lp->lastline)
|
||||
if(sh.inlineno > lp->lastline)
|
||||
lp->lex.last_quote = c;
|
||||
mode = oldmode(lp);
|
||||
poplevel(lp);
|
||||
|
@ -795,7 +786,7 @@ int sh_lex(Lex_t* lp)
|
|||
if(lp->lexd.first)
|
||||
lp->lexd.kiaoff = fcseek(0)-lp->lexd.first;
|
||||
else
|
||||
lp->lexd.kiaoff = stktell(stkp)+fcseek(0)-fcfirst();
|
||||
lp->lexd.kiaoff = stktell(sh.stk)+fcseek(0)-fcfirst();
|
||||
#endif /* SHOPT_KIA */
|
||||
pushlevel(lp,'$',mode);
|
||||
mode = ST_DOL;
|
||||
|
@ -826,7 +817,7 @@ int sh_lex(Lex_t* lp)
|
|||
refvar(lp,0);
|
||||
#endif /* SHOPT_KIA */
|
||||
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);
|
||||
mode = oldmode(lp);
|
||||
poplevel(lp);
|
||||
|
@ -957,7 +948,7 @@ int sh_lex(Lex_t* lp)
|
|||
sh_syntax(lp);
|
||||
}
|
||||
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
|
||||
{
|
||||
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)
|
||||
wordflags |= ARG_MESSAGE;
|
||||
fcseek(-LEN);
|
||||
|
@ -1000,7 +991,7 @@ int sh_lex(Lex_t* lp)
|
|||
continue;
|
||||
case S_META:
|
||||
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;
|
||||
case S_PUSH:
|
||||
fcgetc(n);
|
||||
|
@ -1045,13 +1036,13 @@ int sh_lex(Lex_t* lp)
|
|||
if(c==';' && n!=';')
|
||||
{
|
||||
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;
|
||||
}
|
||||
if(mode==ST_QNEST)
|
||||
{
|
||||
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;
|
||||
}
|
||||
mode = oldmode(lp);
|
||||
|
@ -1075,7 +1066,7 @@ int sh_lex(Lex_t* lp)
|
|||
/* backward compatibility */
|
||||
{
|
||||
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))
|
||||
state = fcfirst();
|
||||
else
|
||||
|
@ -1135,7 +1126,7 @@ int sh_lex(Lex_t* lp)
|
|||
{
|
||||
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();
|
||||
}
|
||||
if(!epatchar || epatchar=='%')
|
||||
|
@ -1224,7 +1215,7 @@ int sh_lex(Lex_t* lp)
|
|||
continue;
|
||||
}
|
||||
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)
|
||||
fcseek(-LEN);
|
||||
if(n=='=' && c=='+' && mode==ST_NAME)
|
||||
|
@ -1251,13 +1242,13 @@ breakloop:
|
|||
state = fcfirst();
|
||||
n = fcseek(0)-(char*)state;
|
||||
if(!lp->arg)
|
||||
lp->arg = (struct argnod*)stkseek(stkp,ARGVAL);
|
||||
lp->arg = (struct argnod*)stkseek(sh.stk,ARGVAL);
|
||||
if(n>0)
|
||||
sfwrite(stkp,state,n);
|
||||
sfputc(stkp,0);
|
||||
stkseek(stkp,stktell(stkp)-1);
|
||||
state = stkptr(stkp,ARGVAL);
|
||||
n = stktell(stkp)-ARGVAL;
|
||||
sfwrite(sh.stk,state,n);
|
||||
sfputc(sh.stk,0);
|
||||
stkseek(sh.stk,stktell(sh.stk)-1);
|
||||
state = stkptr(sh.stk,ARGVAL);
|
||||
n = stktell(sh.stk)-ARGVAL;
|
||||
lp->lexd.first=0;
|
||||
if(n==1)
|
||||
{
|
||||
|
@ -1284,8 +1275,8 @@ breakloop:
|
|||
if(!strchr(state,','))
|
||||
{
|
||||
/* Redirection of the form {varname}>file, etc. */
|
||||
stkseek(stkp,stktell(stkp)-1);
|
||||
lp->arg = (struct argnod*)stkfreeze(stkp,1);
|
||||
stkseek(sh.stk,stktell(sh.stk)-1);
|
||||
lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
|
||||
return(lp->token=IOVNAME);
|
||||
}
|
||||
c = wordflags;
|
||||
|
@ -1294,8 +1285,8 @@ breakloop:
|
|||
c = wordflags;
|
||||
if(assignment<0)
|
||||
{
|
||||
stkseek(stkp,stktell(stkp)-1);
|
||||
lp->arg = (struct argnod*)stkfreeze(stkp,1);
|
||||
stkseek(sh.stk,stktell(sh.stk)-1);
|
||||
lp->arg = (struct argnod*)stkfreeze(sh.stk,1);
|
||||
lp->lex.reservok = 1;
|
||||
return(lp->token=LABLSYM);
|
||||
}
|
||||
|
@ -1306,23 +1297,23 @@ breakloop:
|
|||
if(mode==ST_NONE)
|
||||
{
|
||||
/* eliminate trailing )) */
|
||||
stkseek(stkp,stktell(stkp)-2);
|
||||
stkseek(sh.stk,stktell(sh.stk)-2);
|
||||
}
|
||||
if(c&ARG_MESSAGE)
|
||||
{
|
||||
if(sh_isoption(SH_DICTIONARY))
|
||||
lp->arg = sh_endword(shp,2);
|
||||
lp->arg = endword(2);
|
||||
c |= ARG_MAC;
|
||||
}
|
||||
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);
|
||||
}
|
||||
else if(mode==ST_NONE)
|
||||
lp->arg = sh_endword(shp,-1);
|
||||
lp->arg = endword(-1);
|
||||
else
|
||||
lp->arg = sh_endword(shp,0);
|
||||
lp->arg = endword(0);
|
||||
state = lp->arg->argval;
|
||||
lp->comp_assign = assignment;
|
||||
if(assignment)
|
||||
|
@ -1332,7 +1323,7 @@ breakloop:
|
|||
{
|
||||
char *cp = strchr(state, '=');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1351,7 +1342,7 @@ breakloop:
|
|||
strchr(test_opchars,state[1]))
|
||||
{
|
||||
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->token = TESTUNOP;
|
||||
}
|
||||
|
@ -1381,7 +1372,7 @@ breakloop:
|
|||
{
|
||||
case TEST_SEQ:
|
||||
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 */
|
||||
default:
|
||||
if(lp->lex.testop2)
|
||||
|
@ -1418,7 +1409,7 @@ breakloop:
|
|||
break;
|
||||
}
|
||||
errormsg(SH_DICT, ERROR_warn(0), e_lexobsolete4,
|
||||
shp->inlineno, state, alt);
|
||||
sh.inlineno, state, alt);
|
||||
}
|
||||
if(c&TEST_STRCMP)
|
||||
lp->lex.incase = 1;
|
||||
|
@ -1442,7 +1433,7 @@ breakloop:
|
|||
if(n==1 && (c=='{' || c=='}' || c=='!'))
|
||||
{
|
||||
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)
|
||||
lp->lex.incase = 0;
|
||||
return(lp->token=c);
|
||||
|
@ -1494,7 +1485,7 @@ breakloop:
|
|||
/* check for aliases */
|
||||
Namval_t* np;
|
||||
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)
|
||||
&& (lp->aliasok!=2 || nv_isattr(np,BLT_DCL))
|
||||
&& (!sh_isstate(SH_NOALIAS) || nv_isattr(np,NV_NOFREE))
|
||||
|
@ -1520,14 +1511,14 @@ breakloop:
|
|||
static int comsub(register Lex_t *lp, int endtok)
|
||||
{
|
||||
register int n,c,count=1;
|
||||
register int line=lp->sh->inlineno;
|
||||
register int line=sh.inlineno;
|
||||
struct ionod *inheredoc = lp->heredoc;
|
||||
char *first,*cp=fcseek(0),word[5];
|
||||
int off, messages=0, assignok=lp->assignok, csub;
|
||||
struct _shlex_pvt_lexstate_ save;
|
||||
save = lp->lex;
|
||||
csub = lp->comsub;
|
||||
sh_lexopen(lp,lp->sh,1);
|
||||
sh_lexopen(lp,1);
|
||||
lp->lexd.dolparen++;
|
||||
lp->lex.incase=0;
|
||||
pushlevel(lp,0,0);
|
||||
|
@ -1659,7 +1650,7 @@ done:
|
|||
if(lp->heredoc && !inheredoc)
|
||||
{
|
||||
/* 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();
|
||||
}
|
||||
return(messages);
|
||||
|
@ -1674,23 +1665,22 @@ static void nested_here(register Lex_t *lp)
|
|||
register struct ionod *iop;
|
||||
register int n=0,offset;
|
||||
struct argnod *arg = lp->arg;
|
||||
Stk_t *stkp = lp->sh->stk;
|
||||
char *base;
|
||||
if(offset=stktell(stkp))
|
||||
base = stkfreeze(stkp,0);
|
||||
if(offset=stktell(sh.stk))
|
||||
base = stkfreeze(sh.stk,0);
|
||||
if(lp->lexd.docend)
|
||||
n = fcseek(0)-lp->lexd.docend;
|
||||
iop = sh_newof(0,struct ionod,1,lp->lexd.docextra+n+ARGVAL);
|
||||
iop->iolst = lp->heredoc;
|
||||
stkseek(stkp,ARGVAL);
|
||||
stkseek(sh.stk,ARGVAL);
|
||||
if(lp->lexd.docextra)
|
||||
{
|
||||
sfseek(lp->sh->strbuf,(Sfoff_t)0, SEEK_SET);
|
||||
sfmove(lp->sh->strbuf,stkp,lp->lexd.docextra,-1);
|
||||
sfseek(lp->sh->strbuf,(Sfoff_t)0, SEEK_SET);
|
||||
sfseek(sh.strbuf,(Sfoff_t)0, SEEK_SET);
|
||||
sfmove(sh.strbuf,sh.stk,lp->lexd.docextra,-1);
|
||||
sfseek(sh.strbuf,(Sfoff_t)0, SEEK_SET);
|
||||
}
|
||||
sfwrite(stkp,lp->lexd.docend,n);
|
||||
lp->arg = sh_endword(lp->sh,0);
|
||||
sfwrite(sh.stk,lp->lexd.docend,n);
|
||||
lp->arg = endword(0);
|
||||
iop->ioname = (char*)(iop+1);
|
||||
strcpy(iop->ioname,lp->arg->argval);
|
||||
iop->iofile = (IODOC|IORAW);
|
||||
|
@ -1700,9 +1690,9 @@ static void nested_here(register Lex_t *lp)
|
|||
lp->arg = arg;
|
||||
lp->lexd.docword = 0;
|
||||
if(offset)
|
||||
stkset(stkp,base,offset);
|
||||
stkset(sh.stk,base,offset);
|
||||
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))
|
||||
cp = fcfirst();
|
||||
if((copy = fcseek(0)-cp) > 0)
|
||||
sfwrite(lp->sh->stk,cp,copy);
|
||||
sfwrite(sh.stk,cp,copy);
|
||||
}
|
||||
else
|
||||
lp->lexd.nocopy--;
|
||||
|
@ -1769,13 +1759,13 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
|
|||
register const char *state;
|
||||
register int c,n;
|
||||
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;
|
||||
if(funlog=lp->sh->funlog)
|
||||
if(funlog=sh.funlog)
|
||||
{
|
||||
if(fcfill()>0)
|
||||
fcseek(-LEN);
|
||||
lp->sh->funlog = 0;
|
||||
sh.funlog = 0;
|
||||
}
|
||||
if(iop->iolst)
|
||||
here_copy(lp,iop->iolst);
|
||||
|
@ -1881,7 +1871,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
|
|||
switch(n)
|
||||
{
|
||||
case S_NL:
|
||||
lp->sh->inlineno++;
|
||||
sh.inlineno++;
|
||||
if((stripcol && c==' ') || (stripflg && c=='\t'))
|
||||
{
|
||||
if(!lp->lexd.dolparen)
|
||||
|
@ -1942,7 +1932,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
|
|||
}
|
||||
#endif /* SHOPT_CRNL */
|
||||
if(c==NL)
|
||||
lp->sh->inlineno++;
|
||||
sh.inlineno++;
|
||||
if(iop->iodelim[n]==0 && (c==NL||c==RPAREN))
|
||||
{
|
||||
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)
|
||||
iop->iosize += n;
|
||||
}
|
||||
lp->sh->inlineno--;
|
||||
sh.inlineno--;
|
||||
if(c==RPAREN)
|
||||
fcseek(-LEN);
|
||||
goto done;
|
||||
|
@ -1995,7 +1985,7 @@ static int here_copy(Lex_t *lp,register struct ionod *iop)
|
|||
if(c==NL)
|
||||
{
|
||||
/* new-line joining */
|
||||
lp->sh->inlineno++;
|
||||
sh.inlineno++;
|
||||
if(!lp->lexd.dolparen && (n=(fcseek(0)-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;
|
||||
}
|
||||
done:
|
||||
lp->sh->funlog = funlog;
|
||||
sh.funlog = funlog;
|
||||
if(lp->lexd.dolparen)
|
||||
free((void*)iop);
|
||||
else if(!special)
|
||||
|
@ -2088,7 +2078,6 @@ static char *fmttoken(Lex_t *lp, register int sym)
|
|||
|
||||
noreturn void sh_syntax(Lex_t *lp)
|
||||
{
|
||||
register Shell_t *shp = lp->sh;
|
||||
register const char *cp = sh_translate(e_unexpected);
|
||||
register char *tokstr;
|
||||
register int tok = lp->token;
|
||||
|
@ -2099,9 +2088,9 @@ noreturn void sh_syntax(Lex_t *lp)
|
|||
cp = sh_translate(e_unmatched);
|
||||
}
|
||||
else
|
||||
lp->lastline = shp->inlineno;
|
||||
lp->lastline = sh.inlineno;
|
||||
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 */
|
||||
register Sfio_t *top;
|
||||
|
@ -2112,10 +2101,10 @@ noreturn void sh_syntax(Lex_t *lp)
|
|||
}
|
||||
else
|
||||
fcclose();
|
||||
shp->inlineno = lp->inlineno;
|
||||
shp->st.firstline = lp->firstline;
|
||||
sh.inlineno = lp->inlineno;
|
||||
sh.st.firstline = lp->firstline;
|
||||
/* reset lexer state */
|
||||
sh_lexopen(lp, &sh, 0);
|
||||
sh_lexopen(lp, 0);
|
||||
if(!sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_PROFILE))
|
||||
errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax1,lp->lastline,tokstr,cp);
|
||||
else
|
||||
|
@ -2123,15 +2112,15 @@ noreturn void sh_syntax(Lex_t *lp)
|
|||
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 int offset = stktell(stkp);
|
||||
register int left = offset-(sp-stkptr(stkp,0));
|
||||
register int offset = stktell(sh.stk);
|
||||
register int left = offset-(sp-stkptr(sh.stk,0));
|
||||
register int shift = (dp+1-sp);
|
||||
offset += shift;
|
||||
stkseek(stkp,offset);
|
||||
sp = stkptr(stkp,offset);
|
||||
stkseek(sh.stk,offset);
|
||||
sp = stkptr(sh.stk,offset);
|
||||
ep = sp - shift;
|
||||
while(left--)
|
||||
*--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
|
||||
* 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 int n;
|
||||
|
@ -2155,9 +2144,8 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
struct argnod* argp=0;
|
||||
char *ep=0, *xp=0;
|
||||
int bracket=0;
|
||||
Stk_t *stkp=shp->stk;
|
||||
sfputc(stkp,0);
|
||||
sp = stkptr(stkp,ARGVAL);
|
||||
sfputc(sh.stk,0);
|
||||
sp = stkptr(sh.stk,ARGVAL);
|
||||
if(mbwide())
|
||||
{
|
||||
do
|
||||
|
@ -2196,10 +2184,10 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
switch(n)
|
||||
{
|
||||
case S_EOF:
|
||||
stkseek(stkp,dp-stkptr(stkp,0));
|
||||
stkseek(sh.stk,dp-stkptr(sh.stk,0));
|
||||
if(mode<=0)
|
||||
{
|
||||
argp = (struct argnod*)stkfreeze(stkp,0);
|
||||
argp = (struct argnod*)stkfreeze(sh.stk,0);
|
||||
argp->argflag = ARG_RAW|ARG_QUOTED;
|
||||
}
|
||||
return(argp);
|
||||
|
@ -2243,7 +2231,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
dp = ep+n;
|
||||
if(sp-dp <= 1)
|
||||
{
|
||||
sp = stack_shift(stkp,sp,dp);
|
||||
sp = stack_shift(sp,dp);
|
||||
dp = sp-1;
|
||||
ep = dp-n;
|
||||
}
|
||||
|
@ -2292,7 +2280,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
{
|
||||
if(dp>=sp)
|
||||
{
|
||||
sp = stack_shift(stkp,sp,dp+1);
|
||||
sp = stack_shift(sp,dp+1);
|
||||
dp = sp-2;
|
||||
}
|
||||
*dp++ = '\\';
|
||||
|
@ -2328,7 +2316,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
dp[-1] = '\\';
|
||||
if(dp>=sp)
|
||||
{
|
||||
sp = stack_shift(stkp,sp,dp);
|
||||
sp = stack_shift(sp,dp);
|
||||
dp = sp-1;
|
||||
}
|
||||
*dp++ = ']';
|
||||
|
@ -2344,7 +2332,7 @@ struct argnod *sh_endword(Shell_t *shp,int mode)
|
|||
dp[-1] = '\\';
|
||||
if(dp>=sp)
|
||||
{
|
||||
sp = stack_shift(stkp,sp,dp);
|
||||
sp = stack_shift(sp,dp);
|
||||
dp = sp-1;
|
||||
}
|
||||
*dp++ = '[';
|
||||
|
@ -2455,7 +2443,7 @@ static void setupalias(Lex_t *lp, const char *string,Namval_t *np)
|
|||
{
|
||||
unsigned long r;
|
||||
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 */
|
||||
if((ap->nextc=fcget())==0)
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
static int _c_;
|
||||
typedef struct _mac_
|
||||
{
|
||||
Shell_t *shp; /* pointer to shell interpreter */
|
||||
Sfio_t *sp; /* stream pointer for here-document */
|
||||
struct argnod **arghead; /* address of head of argument list */
|
||||
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 int varsub(Mac_t*);
|
||||
static void mac_copy(Mac_t*,const char*, int);
|
||||
static void tilde_expand2(Shell_t*,int);
|
||||
static char *sh_tilde(Shell_t*,const char*);
|
||||
static char *special(Shell_t *,int);
|
||||
static void tilde_expand2(int);
|
||||
static char *sh_tilde(const char*);
|
||||
static char *special(int);
|
||||
static void endfield(Mac_t*,int);
|
||||
static char *mac_getstring(char*);
|
||||
static int charlen(const char*,int);
|
||||
|
@ -114,33 +113,30 @@ static int charlen(const char*,int);
|
|||
# define lastchar(string,endstring) (endstring)
|
||||
#endif /* SHOPT_MULTIBYTE */
|
||||
|
||||
void *sh_macopen(Shell_t *shp)
|
||||
void *sh_macopen(void)
|
||||
{
|
||||
void *addr = sh_newof(0,Mac_t,1,0);
|
||||
Mac_t *mp = (Mac_t*)addr;
|
||||
mp->shp = shp;
|
||||
return(addr);
|
||||
return(sh_newof(0,Mac_t,1,0));
|
||||
}
|
||||
|
||||
/*
|
||||
* perform only parameter substitution and catch failures
|
||||
* (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)
|
||||
{
|
||||
int jmp_val;
|
||||
int savexit = shp->savexit;
|
||||
int savexit = sh.savexit;
|
||||
struct checkpt buff;
|
||||
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);
|
||||
if(jmp_val == 0)
|
||||
string = sh_mactrim(shp,string,0);
|
||||
sh_popcontext(shp,&buff);
|
||||
string = sh_mactrim(string,0);
|
||||
sh_popcontext(&sh,&buff);
|
||||
*lexp = savelex;
|
||||
shp->savexit = savexit;
|
||||
sh.savexit = savexit;
|
||||
return(string);
|
||||
}
|
||||
return("");
|
||||
|
@ -153,15 +149,15 @@ char *sh_mactry(Shell_t *shp,register char *string)
|
|||
* yields a single pathname.
|
||||
* 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;
|
||||
Stk_t *stkp = shp->stk;
|
||||
register Mac_t *mp = (Mac_t*)sh.mac_context;
|
||||
Stk_t *stkp = sh.stk;
|
||||
Mac_t savemac;
|
||||
savemac = *mp;
|
||||
stkseek(stkp,0);
|
||||
mp->arith = (mode==3);
|
||||
shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
mp->pattern = (mode==1||mode==2);
|
||||
mp->patfound = 0;
|
||||
mp->assign = 0;
|
||||
|
@ -169,7 +165,7 @@ char *sh_mactrim(Shell_t *shp, char *str, register int mode)
|
|||
mp->assign = -mode;
|
||||
mp->quoted = mp->lit = mp->split = mp->quote = 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;
|
||||
else
|
||||
mp->ifs = ' ';
|
||||
|
@ -181,7 +177,7 @@ char *sh_mactrim(Shell_t *shp, char *str, register int mode)
|
|||
{
|
||||
/* expand only if unique */
|
||||
struct argnod *arglist=0;
|
||||
if((mode=path_expand(shp,str,&arglist))==1)
|
||||
if((mode=path_expand(str,&arglist))==1)
|
||||
str = arglist->argval;
|
||||
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>
|
||||
*/
|
||||
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 char *str = argp->argval;
|
||||
register Mac_t *mp = (Mac_t*)shp->mac_context;
|
||||
char **saveargaddr = shp->argaddr;
|
||||
register Mac_t *mp = (Mac_t*)sh.mac_context;
|
||||
char **saveargaddr = sh.argaddr;
|
||||
Mac_t savemac;
|
||||
Stk_t *stkp = shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
savemac = *mp;
|
||||
mp->sp = 0;
|
||||
if(mp->ifsp=nv_getval(sh_scoped(shp,IFSNOD)))
|
||||
if(mp->ifsp=nv_getval(sh_scoped(IFSNOD)))
|
||||
mp->ifs = *mp->ifsp;
|
||||
else
|
||||
mp->ifs = ' ';
|
||||
if((flag&ARG_OPTIMIZE) && !shp->indebug && !(flags&ARG_MESSAGE))
|
||||
shp->argaddr = (char**)&argp->argchn.ap;
|
||||
if((flag&ARG_OPTIMIZE) && !sh.indebug && !(flags&ARG_MESSAGE))
|
||||
sh.argaddr = (char**)&argp->argchn.ap;
|
||||
else
|
||||
shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
mp->arghead = arghead;
|
||||
mp->quoted = mp->lit = mp->quote = 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)
|
||||
{
|
||||
argp->argchn.cp = stkfreeze(stkp,1);
|
||||
if(shp->argaddr)
|
||||
if(sh.argaddr)
|
||||
argp->argflag |= ARG_MAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
endfield(mp,mp->quoted|mp->atmode);
|
||||
flags = mp->fields;
|
||||
if(flags==1 && shp->argaddr)
|
||||
if(flags==1 && sh.argaddr)
|
||||
argp->argchn.ap = *arghead;
|
||||
}
|
||||
shp->argaddr = saveargaddr;
|
||||
sh.argaddr = saveargaddr;
|
||||
*mp = savemac;
|
||||
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>
|
||||
* 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 const char *state = sh_lexstates[ST_QUOTE];
|
||||
register char *cp;
|
||||
register Mac_t *mp = (Mac_t*)shp->mac_context;
|
||||
Lex_t *lp = (Lex_t*)mp->shp->lex_context;
|
||||
register Mac_t *mp = (Mac_t*)sh.mac_context;
|
||||
Lex_t *lp = (Lex_t*)sh.lex_context;
|
||||
Fcin_t save;
|
||||
Mac_t savemac;
|
||||
Stk_t *stkp = shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
savemac = *mp;
|
||||
stkseek(stkp,0);
|
||||
shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
mp->sp = outfile;
|
||||
mp->split = mp->assign = mp->pattern = mp->patfound = mp->lit = mp->arith = 0;
|
||||
mp->quote = 1;
|
||||
mp->ifsp = nv_getval(sh_scoped(shp,IFSNOD));
|
||||
mp->ifsp = nv_getval(sh_scoped(IFSNOD));
|
||||
mp->ifs = ' ';
|
||||
fcsave(&save);
|
||||
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
|
||||
*/
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
if(!(flags&ARG_OPTIMIZE) || !(arg->argflag&ARG_MAKE))
|
||||
arg->argchn.cp = 0;
|
||||
|
@ -436,7 +432,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
register int c,n;
|
||||
register const char *state = sh_lexstates[ST_MACRO];
|
||||
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 oldquote = mp->quote;
|
||||
int ansi_c = 0;
|
||||
|
@ -444,7 +440,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
int ere = 0;
|
||||
int brace = 0;
|
||||
Sfio_t *sp = mp->sp;
|
||||
Stk_t *stkp = mp->shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
char *resume = 0;
|
||||
mp->sp = NIL(Sfio_t*);
|
||||
mp->quote = newquote;
|
||||
|
@ -666,7 +662,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
c += (n!=S_EOF);
|
||||
first = fcseek(c);
|
||||
if(tilde>=0)
|
||||
tilde_expand2(mp->shp,tilde);
|
||||
tilde_expand2(tilde);
|
||||
goto done;
|
||||
case S_QUOTE:
|
||||
if(mp->lit || mp->arith)
|
||||
|
@ -815,7 +811,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
|
|||
if(c)
|
||||
sfwrite(stkp,first,c);
|
||||
first = fcseek(c);
|
||||
tilde_expand2(mp->shp,tilde);
|
||||
tilde_expand2(tilde);
|
||||
#if _WINIX
|
||||
if(Skip)
|
||||
{
|
||||
|
@ -895,18 +891,18 @@ static void mac_substitute(Mac_t *mp, register char *cp,char *str,register int s
|
|||
}
|
||||
|
||||
#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)
|
||||
|
||||
/*
|
||||
* compute the arguments $1 ... $n and $# from the current line as needed
|
||||
* 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 unsigned char *first,*last,*cp = (unsigned char*)shp->cur_line;
|
||||
register int m=shp->offsets[0],delim=0;
|
||||
register int c=S_DELIM, d=sh.ifstable['\\'];
|
||||
register unsigned char *first,*last,*cp = (unsigned char*)sh.cur_line;
|
||||
register int m=sh.offsets[0],delim=0;
|
||||
if(m==0)
|
||||
return(0);
|
||||
if(m<0)
|
||||
|
@ -917,21 +913,21 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
|
|||
m--;
|
||||
if(m >= MAX_OFFSETS-1)
|
||||
m = MAX_OFFSETS-2;
|
||||
cp += shp->offsets[m+1];
|
||||
cp += sh.offsets[m+1];
|
||||
n -= m;
|
||||
shp->ifstable['\\'] = 0;
|
||||
shp->ifstable[0] = S_EOF;
|
||||
sh.ifstable['\\'] = 0;
|
||||
sh.ifstable[0] = S_EOF;
|
||||
while(1)
|
||||
{
|
||||
if(c==S_DELIM)
|
||||
while(shp->ifstable[*cp++]==S_SPACE);
|
||||
while(sh.ifstable[*cp++]==S_SPACE);
|
||||
first = --cp;
|
||||
if(++m < MAX_OFFSETS)
|
||||
shp->offsets[m] = (first-(unsigned char*)shp->cur_line);
|
||||
while((c=shp->ifstable[*cp++])==0);
|
||||
sh.offsets[m] = (first-(unsigned char*)sh.cur_line);
|
||||
while((c=sh.ifstable[*cp++])==0);
|
||||
last = cp-1;
|
||||
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(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);
|
||||
}
|
||||
shp->ifstable['\\'] = d;
|
||||
if(m > shp->offsets[0])
|
||||
shp->offsets[0] = m;
|
||||
sh.ifstable['\\'] = d;
|
||||
if(m > sh.offsets[0])
|
||||
sh.offsets[0] = m;
|
||||
if(n)
|
||||
first = last = 0;
|
||||
if(size)
|
||||
|
@ -957,14 +953,14 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
|
|||
/*
|
||||
* get the prefix after name reference resolution
|
||||
*/
|
||||
static char *prefix(Shell_t *shp, char *id)
|
||||
static char *prefix(char *id)
|
||||
{
|
||||
Namval_t *np;
|
||||
register char *sub=0, *cp = strchr(id,'.');
|
||||
if(cp)
|
||||
{
|
||||
*cp = 0;
|
||||
np = nv_search(id, shp->var_tree,0);
|
||||
np = nv_search(id, sh.var_tree,0);
|
||||
*cp = '.';
|
||||
if(isastchar(cp[1]))
|
||||
cp[1] = 0;
|
||||
|
@ -972,7 +968,7 @@ static char *prefix(Shell_t *shp, char *id)
|
|||
{
|
||||
int n;
|
||||
char *sp;
|
||||
shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
while(nv_isref(np) && np->nvalue.cp)
|
||||
{
|
||||
sub = nv_refsub(np);
|
||||
|
@ -1003,7 +999,7 @@ static int subcopy(Mac_t *mp, int flag)
|
|||
{
|
||||
int split = mp->split;
|
||||
int xpattern = mp->pattern;
|
||||
int loc = stktell(mp->shp->stk);
|
||||
int loc = stktell(sh.stk);
|
||||
int xarith = mp->arith;
|
||||
int arrayok = mp->arrayok;
|
||||
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
|
||||
* 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;
|
||||
np = nv_bfsearch(name,shp->fun_tree,&nq,(char**)0);
|
||||
np = nv_bfsearch(name,sh.fun_tree,&nq,(char**)0);
|
||||
if(np)
|
||||
{
|
||||
/* 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(&d,0,sizeof(d));
|
||||
t.node.com.comarg = &d.arg;
|
||||
t.node.com.comline = shp->inlineno;
|
||||
t.node.com.comline = sh.inlineno;
|
||||
d.dol.dolnum = 1;
|
||||
d.dol.dolval[0] = sh_strdup(name);
|
||||
stkseek(shp->stk,offset);
|
||||
comsubst((Mac_t*)shp->mac_context,&t.node,2);
|
||||
stkseek(sh.stk,offset);
|
||||
comsubst((Mac_t*)sh.mac_context,&t.node,2);
|
||||
free(d.dol.dolval[0]);
|
||||
return(1);
|
||||
}
|
||||
|
@ -1091,13 +1087,13 @@ static int varsub(Mac_t *mp)
|
|||
register char *v,*argp=0;
|
||||
register Namval_t *np = NIL(Namval_t*);
|
||||
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;
|
||||
int dolmax=0, vsize= -1, offset= -1, nulflg, replen=0, bysub=0;
|
||||
char idbuff[3], *id = idbuff, *pattern=0, *repstr=0, *arrmax=0;
|
||||
char *idx = 0;
|
||||
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:
|
||||
idbuff[0] = 0;
|
||||
idbuff[1] = 0;
|
||||
|
@ -1141,19 +1137,19 @@ retry1:
|
|||
case S_SPC2:
|
||||
var = 0;
|
||||
*id = c;
|
||||
v = special(mp->shp,c);
|
||||
v = special(c);
|
||||
if(isastchar(c))
|
||||
{
|
||||
mode = c;
|
||||
#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;
|
||||
}
|
||||
else
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
dolmax = mp->shp->st.dolc+1;
|
||||
dolmax = sh.st.dolc+1;
|
||||
mp->atmode = (v && mp->quoted && c=='@');
|
||||
dolg = (v!=0);
|
||||
}
|
||||
|
@ -1171,7 +1167,7 @@ retry1:
|
|||
case S_DIG:
|
||||
var = 0;
|
||||
c -= '0';
|
||||
mp->shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
if(type)
|
||||
{
|
||||
register int d;
|
||||
|
@ -1181,18 +1177,18 @@ retry1:
|
|||
}
|
||||
idnum = c;
|
||||
if(c==0)
|
||||
v = special(mp->shp,c);
|
||||
v = special(c);
|
||||
#if SHOPT_FILESCAN
|
||||
else if(mp->shp->cur_line)
|
||||
else if(sh.cur_line)
|
||||
{
|
||||
mp->shp->used_pos = 1;
|
||||
v = getdolarg(mp->shp,c,&vsize);
|
||||
sh.used_pos = 1;
|
||||
v = getdolarg(c,&vsize);
|
||||
}
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
else if(c <= mp->shp->st.dolc)
|
||||
else if(c <= sh.st.dolc)
|
||||
{
|
||||
mp->shp->used_pos = 1;
|
||||
v = mp->shp->st.dolv[c];
|
||||
sh.used_pos = 1;
|
||||
v = sh.st.dolv[c];
|
||||
}
|
||||
else
|
||||
v = 0;
|
||||
|
@ -1226,7 +1222,7 @@ retry1:
|
|||
while((d=c,(c=fcmbget(&LEN)),isaname(c))||type && c=='.');
|
||||
while(c==LBRACT && (type||mp->arrayok))
|
||||
{
|
||||
mp->shp->argaddr=0;
|
||||
sh.argaddr=0;
|
||||
if((c=fcmbget(&LEN),isastchar(c)) && fcpeek(0)==RBRACT && d!='.')
|
||||
{
|
||||
if(type==M_VNAME)
|
||||
|
@ -1308,31 +1304,31 @@ retry1:
|
|||
flag &= ~NV_NOADD;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
else
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
{
|
||||
if(mp->shp->argaddr)
|
||||
if(sh.argaddr)
|
||||
flag &= ~NV_NOADD;
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
sfprintf(mp->shp->strbuf,"%s%c",id,0);
|
||||
id = sfstruse(mp->shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%s%c",id,0);
|
||||
id = sfstruse(sh.strbuf);
|
||||
}
|
||||
}
|
||||
if(isastchar(mode))
|
||||
var = 0;
|
||||
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);
|
||||
return(1);
|
||||
|
@ -1343,7 +1339,7 @@ retry1:
|
|||
if(nv_isattr(np,NV_NOFREE))
|
||||
nv_offattr(np,NV_NOFREE);
|
||||
#if SHOPT_FILESCAN
|
||||
else if(np!=REPLYNOD || !mp->shp->cur_line)
|
||||
else if(np!=REPLYNOD || !sh.cur_line)
|
||||
#else
|
||||
else
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
|
@ -1368,14 +1364,14 @@ retry1:
|
|||
dolmax =1;
|
||||
if(array_assoc(ap))
|
||||
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);
|
||||
if(type==M_SUBNAME)
|
||||
bysub = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((int)sh_arith(mp->shp,v))
|
||||
if((int)sh_arith(v))
|
||||
np = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1405,14 +1401,14 @@ retry1:
|
|||
if(cc==0)
|
||||
mp->assign = 1;
|
||||
}
|
||||
if((type==M_VNAME||type==M_SUBNAME) && mp->shp->argaddr && strcmp(nv_name(np),id))
|
||||
mp->shp->argaddr = 0;
|
||||
if((type==M_VNAME||type==M_SUBNAME) && sh.argaddr && strcmp(nv_name(np),id))
|
||||
sh.argaddr = 0;
|
||||
c = (type>M_BRACE && isastchar(mode));
|
||||
/*
|
||||
* Check if the parameter is set or unset.
|
||||
*/
|
||||
#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() */
|
||||
#endif /* SHOPT_OPTIMIZE */
|
||||
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);
|
||||
type = M_BRACE;
|
||||
if(nq)
|
||||
nv_typename(nq,mp->shp->strbuf);
|
||||
nv_typename(nq,sh.strbuf);
|
||||
else
|
||||
nv_attribute(np,mp->shp->strbuf,"typeset",1);
|
||||
v = sfstruse(mp->shp->strbuf);
|
||||
nv_attribute(np,sh.strbuf,"typeset",1);
|
||||
v = sfstruse(sh.strbuf);
|
||||
}
|
||||
#endif /* SHOPT_TYPEDEF */
|
||||
#if SHOPT_FILESCAN
|
||||
else if(mp->shp->cur_line && np==REPLYNOD)
|
||||
v = mp->shp->cur_line;
|
||||
else if(sh.cur_line && np==REPLYNOD)
|
||||
v = sh.cur_line;
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
else if(type==M_TREE)
|
||||
v = nv_getvtree(np,(Namfun_t*)0);
|
||||
|
@ -1485,7 +1481,7 @@ retry1:
|
|||
if(ap)
|
||||
{
|
||||
#if SHOPT_OPTIMIZE
|
||||
if(mp->shp->argaddr)
|
||||
if(sh.argaddr)
|
||||
nv_optimize(np);
|
||||
#endif
|
||||
if(isastchar(mode) && array_elem(ap)> !c)
|
||||
|
@ -1513,8 +1509,8 @@ retry1:
|
|||
mac_error(np);
|
||||
if(type==M_NAMESCAN || type==M_NAMECOUNT)
|
||||
{
|
||||
mp->shp->last_root = mp->shp->var_tree;
|
||||
id = idx = prefix(mp->shp,id);
|
||||
sh.last_root = sh.var_tree;
|
||||
id = idx = prefix(id);
|
||||
stkseek(stkp,offset);
|
||||
if(type==M_NAMECOUNT)
|
||||
{
|
||||
|
@ -1528,7 +1524,7 @@ retry1:
|
|||
dolg = -1;
|
||||
nextname(mp,id,0);
|
||||
/* 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;
|
||||
else
|
||||
v = nextname(mp,id,dolmax);
|
||||
|
@ -1556,14 +1552,14 @@ retry1:
|
|||
else if(dolg>0)
|
||||
{
|
||||
#if SHOPT_FILESCAN
|
||||
if(mp->shp->cur_line)
|
||||
if(sh.cur_line)
|
||||
{
|
||||
getdolarg(mp->shp,MAX_ARGN,(int*)0);
|
||||
c = mp->shp->offsets[0];
|
||||
getdolarg(MAX_ARGN,(int*)0);
|
||||
c = sh.offsets[0];
|
||||
}
|
||||
else
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
c = mp->shp->st.dolc;
|
||||
c = sh.st.dolc;
|
||||
}
|
||||
else if(dolg<0)
|
||||
c = array_elem(ap);
|
||||
|
@ -1673,17 +1669,17 @@ retry1:
|
|||
if(type<0 && (type+= dolmax)<0)
|
||||
type = 0;
|
||||
if(type==0)
|
||||
v = special(mp->shp,dolg=0);
|
||||
v = special(dolg=0);
|
||||
#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)
|
||||
dolmax = type;
|
||||
}
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
else if(type < dolmax)
|
||||
v = mp->shp->st.dolv[dolg=type];
|
||||
v = sh.st.dolv[dolg=type];
|
||||
else
|
||||
v = 0;
|
||||
}
|
||||
|
@ -1846,7 +1842,7 @@ retry2:
|
|||
else
|
||||
nmatch=strgrpmatch(v,pattern,match,elementsof(match)/2,flag);
|
||||
if(nmatch && replen>0)
|
||||
sh_setmatch(mp->shp,v,vsize,nmatch,match,index++);
|
||||
sh_setmatch(v,vsize,nmatch,match,index++);
|
||||
if(nmatch)
|
||||
{
|
||||
vlast = v;
|
||||
|
@ -1878,16 +1874,16 @@ retry2:
|
|||
break;
|
||||
}
|
||||
if(replen==0)
|
||||
sh_setmatch(mp->shp,vlast,vsize_last,nmatch,match,index++);
|
||||
sh_setmatch(vlast,vsize_last,nmatch,match,index++);
|
||||
}
|
||||
if(vsize)
|
||||
mac_copy(mp,v,vsize>0?vsize:strlen(v));
|
||||
if(addsub)
|
||||
{
|
||||
mp->shp->instance++;
|
||||
sfprintf(mp->shp->strbuf,"[%s]",nv_getsub(np));
|
||||
mp->shp->instance--;
|
||||
v = sfstruse(mp->shp->strbuf);
|
||||
sh.instance++;
|
||||
sfprintf(sh.strbuf,"[%s]",nv_getsub(np));
|
||||
sh.instance--;
|
||||
v = sfstruse(sh.strbuf);
|
||||
mac_copy(mp, v, strlen(v));
|
||||
}
|
||||
if(dolg==0 && dolmax==0)
|
||||
|
@ -1916,11 +1912,11 @@ retry2:
|
|||
if(++dolg >= dolmax)
|
||||
break;
|
||||
#if SHOPT_FILESCAN
|
||||
if(mp->shp->cur_line)
|
||||
if(sh.cur_line)
|
||||
{
|
||||
if(dolmax==MAX_ARGN && isastchar(mode))
|
||||
break;
|
||||
if(!(v=getdolarg(mp->shp,dolg,&vsize)))
|
||||
if(!(v=getdolarg(dolg,&vsize)))
|
||||
{
|
||||
dolmax = dolg;
|
||||
break;
|
||||
|
@ -1928,7 +1924,7 @@ retry2:
|
|||
}
|
||||
else
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
v = mp->shp->st.dolv[dolg];
|
||||
v = sh.st.dolv[dolg];
|
||||
}
|
||||
else if(!np)
|
||||
{
|
||||
|
@ -2013,7 +2009,7 @@ retry2:
|
|||
{
|
||||
if(np)
|
||||
{
|
||||
if(mp->shp->subshell)
|
||||
if(sh.subshell)
|
||||
np = sh_assignok(np,1);
|
||||
nv_putval(np,argp,0);
|
||||
v = nv_getval(np);
|
||||
|
@ -2031,8 +2027,8 @@ retry2:
|
|||
{
|
||||
if(nv_isarray(np))
|
||||
{
|
||||
sfprintf(mp->shp->strbuf,"%s[%s]\0",nv_name(np),nv_getsub(np));
|
||||
id = sfstruse(mp->shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%s[%s]\0",nv_name(np),nv_getsub(np));
|
||||
id = sfstruse(sh.strbuf);
|
||||
}
|
||||
else
|
||||
id = nv_name(np);
|
||||
|
@ -2075,9 +2071,9 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
|
|||
register int c;
|
||||
register char *str;
|
||||
Sfio_t *sp;
|
||||
Stk_t *stkp = mp->shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
Fcin_t save;
|
||||
struct slnod *saveslp = mp->shp->st.staklist;
|
||||
struct slnod *saveslp = sh.st.staklist;
|
||||
struct _mac_ savemac;
|
||||
int savtop = stktell(stkp);
|
||||
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;
|
||||
Sfoff_t foff;
|
||||
Namval_t *np;
|
||||
mp->shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
savemac = *mp;
|
||||
mp->shp->st.staklist=0;
|
||||
sh.st.staklist=0;
|
||||
if(type)
|
||||
{
|
||||
sp = 0;
|
||||
fcseek(-1);
|
||||
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)
|
||||
{
|
||||
fcsave(&save);
|
||||
if(t->ar.arcomp)
|
||||
num = arith_exec(t->ar.arcomp);
|
||||
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
|
||||
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:
|
||||
stkset(stkp,savptr,savtop);
|
||||
*mp = savemac;
|
||||
if((Sflong_t)num!=num)
|
||||
sfprintf(mp->shp->strbuf,"%.*Lg",LDBL_DIG,num);
|
||||
sfprintf(sh.strbuf,"%.*Lg",LDBL_DIG,num);
|
||||
else if(num)
|
||||
sfprintf(mp->shp->strbuf,"%lld",(Sflong_t)num);
|
||||
sfprintf(sh.strbuf,"%lld",(Sflong_t)num);
|
||||
else
|
||||
sfprintf(mp->shp->strbuf,"%Lg",num);
|
||||
str = sfstruse(mp->shp->strbuf);
|
||||
sfprintf(sh.strbuf,"%Lg",num);
|
||||
str = sfstruse(sh.strbuf);
|
||||
mac_copy(mp,str,strlen(str));
|
||||
mp->shp->st.staklist = saveslp;
|
||||
sh.st.staklist = saveslp;
|
||||
fcrestore(&save);
|
||||
return;
|
||||
}
|
||||
|
@ -2143,10 +2139,10 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
|
|||
if(mp->sp)
|
||||
sfsync(mp->sp); /* flush before executing command */
|
||||
sp = sfnew(NIL(Sfio_t*),str,c,-1,SF_STRING|SF_READ);
|
||||
c = mp->shp->inlineno;
|
||||
mp->shp->inlineno = error_info.line+mp->shp->st.firstline;
|
||||
t = (Shnode_t*)sh_parse(mp->shp, sp,SH_EOF|SH_NL);
|
||||
mp->shp->inlineno = c;
|
||||
c = sh.inlineno;
|
||||
sh.inlineno = error_info.line+sh.st.firstline;
|
||||
t = (Shnode_t*)sh_parse(sp,SH_EOF|SH_NL);
|
||||
sh.inlineno = c;
|
||||
type = 1;
|
||||
}
|
||||
if(t)
|
||||
|
@ -2160,23 +2156,23 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
|
|||
int r=0;
|
||||
struct checkpt buff;
|
||||
struct ionod *ip=0;
|
||||
sh_pushcontext(mp->shp,&buff,SH_JMPIO);
|
||||
sh_pushcontext(&sh,&buff,SH_JMPIO);
|
||||
if((ip=t->tre.treio) &&
|
||||
((ip->iofile&IOLSEEK) || !(ip->iofile&IOUFD)) &&
|
||||
(r=sigsetjmp(buff.buff,0))==0)
|
||||
fd = sh_redirect(mp->shp,ip,3);
|
||||
fd = sh_redirect(ip,3);
|
||||
else
|
||||
fd = sh_chkopen(e_devnull);
|
||||
sh_popcontext(mp->shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
if(r==0 && ip && (ip->iofile&IOLSEEK))
|
||||
{
|
||||
if(sp=mp->shp->sftable[fd])
|
||||
if(sp=sh.sftable[fd])
|
||||
num = sftell(sp);
|
||||
else
|
||||
num = lseek(fd, (off_t)0, SEEK_CUR);
|
||||
goto out_offset;
|
||||
}
|
||||
if(!(sp=mp->shp->sftable[fd]))
|
||||
if(!(sp=sh.sftable[fd]))
|
||||
{
|
||||
char *cp = (char*)sh_malloc(IOBSIZE+1);
|
||||
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)
|
||||
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);
|
||||
}
|
||||
else
|
||||
sp = sfopen(NIL(Sfio_t*),"","sr");
|
||||
sh_freeup(mp->shp);
|
||||
mp->shp->st.staklist = saveslp;
|
||||
sh_freeup();
|
||||
sh.st.staklist = saveslp;
|
||||
if(was_history)
|
||||
sh_onstate(SH_HISTORY);
|
||||
if(was_verbose)
|
||||
sh_onstate(SH_VERBOSE);
|
||||
*mp = savemac;
|
||||
np = sh_scoped(mp->shp,IFSNOD);
|
||||
np = sh_scoped(IFSNOD);
|
||||
nv_putval(np,mp->ifsp,NV_RDONLY);
|
||||
mp->ifsp = nv_getval(np);
|
||||
stkset(stkp,savptr,savtop);
|
||||
|
@ -2255,7 +2251,7 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
|
|||
{
|
||||
if(mp->sp)
|
||||
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);
|
||||
else
|
||||
sfnputc(stkp,'\n',newlines);
|
||||
|
@ -2281,7 +2277,7 @@ static void comsubst(Mac_t *mp,register Shnode_t* t, int type)
|
|||
}
|
||||
if(was_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)
|
||||
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 const char *cp=str;
|
||||
register int c,n,nopat,len;
|
||||
Stk_t *stkp=mp->shp->stk;
|
||||
Stk_t *stkp=sh.stk;
|
||||
int oldpat = mp->pattern;
|
||||
nopat = (mp->quote||(mp->assign==1)||mp->arith);
|
||||
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))
|
||||
{
|
||||
/* split words at ifs characters */
|
||||
state = mp->shp->ifstable;
|
||||
state = sh.ifstable;
|
||||
if(mp->pattern)
|
||||
{
|
||||
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)
|
||||
state[c] = 0;
|
||||
}
|
||||
if(mp->shp->ifstable[ESCAPE]==S_ESC)
|
||||
mp->shp->ifstable[ESCAPE] = 0;
|
||||
if(sh.ifstable[ESCAPE]==S_ESC)
|
||||
sh.ifstable[ESCAPE] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2493,7 +2489,7 @@ static void endfield(register Mac_t *mp,int split)
|
|||
{
|
||||
register struct argnod *argp;
|
||||
register int count=0;
|
||||
Stk_t *stkp = mp->shp->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
if(stktell(stkp) > ARGVAL || split)
|
||||
{
|
||||
argp = (struct argnod*)stkfreeze(stkp,1);
|
||||
|
@ -2502,13 +2498,13 @@ static void endfield(register Mac_t *mp,int split)
|
|||
mp->atmode = 0;
|
||||
if(mp->patfound)
|
||||
{
|
||||
mp->shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
#if SHOPT_BRACEPAT
|
||||
if(sh_isoption(SH_BRACEEXPAND))
|
||||
count = path_generate(mp->shp,argp,mp->arghead);
|
||||
count = path_generate(argp,mp->arghead);
|
||||
else
|
||||
#endif /* SHOPT_BRACEPAT */
|
||||
count = path_expand(mp->shp,argp->argval,mp->arghead);
|
||||
count = path_expand(argp->argval,mp->arghead);
|
||||
if(count)
|
||||
mp->fields += count;
|
||||
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
|
||||
*/
|
||||
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 *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);
|
||||
if(!cp)
|
||||
cp = sh_tilde(shp,&stakp[offset]);
|
||||
cp = sh_tilde(&stakp[offset]);
|
||||
if(cp)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
static char *sh_tilde(Shell_t *shp,register const char *string)
|
||||
static char *sh_tilde(register const char *string)
|
||||
{
|
||||
register char *cp;
|
||||
register int c;
|
||||
|
@ -2682,7 +2678,7 @@ static char *sh_tilde(Shell_t *shp,register const char *string)
|
|||
if((c = *string)==0)
|
||||
{
|
||||
static char *username;
|
||||
if(cp = nv_getval(sh_scoped(shp, HOME)))
|
||||
if(cp = nv_getval(sh_scoped(HOME)))
|
||||
return(cp);
|
||||
/* Fallback for unset HOME: get username and treat ~ like ~username */
|
||||
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=='+')
|
||||
cp = nv_getval(sh_scoped(shp,PWDNOD));
|
||||
cp = nv_getval(sh_scoped(PWDNOD));
|
||||
else
|
||||
cp = nv_getval(sh_scoped(shp,OLDPWDNOD));
|
||||
cp = nv_getval(sh_scoped(OLDPWDNOD));
|
||||
return(cp);
|
||||
}
|
||||
#if _WINIX
|
||||
|
@ -2734,14 +2730,14 @@ skip:
|
|||
if(!logins_tree)
|
||||
{
|
||||
logins_tree = dtopen(&_Nvdisc,Dtbag);
|
||||
dtuserdata(logins_tree,shp,1);
|
||||
dtuserdata(logins_tree,&sh,1);
|
||||
}
|
||||
if(np=nv_search(string,logins_tree,NV_ADD))
|
||||
{
|
||||
save = shp->subshell;
|
||||
shp->subshell = 0;
|
||||
save = sh.subshell;
|
||||
sh.subshell = 0;
|
||||
nv_putval(np, pw->pw_dir,0);
|
||||
shp->subshell = save;
|
||||
sh.subshell = save;
|
||||
}
|
||||
return(pw->pw_dir);
|
||||
}
|
||||
|
@ -2749,41 +2745,41 @@ skip:
|
|||
/*
|
||||
* return values for special macros
|
||||
*/
|
||||
static char *special(Shell_t *shp,register int c)
|
||||
static char *special(register int c)
|
||||
{
|
||||
if(c!='$')
|
||||
shp->argaddr = 0;
|
||||
sh.argaddr = 0;
|
||||
switch(c)
|
||||
{
|
||||
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 '#':
|
||||
#if SHOPT_FILESCAN
|
||||
if(shp->cur_line)
|
||||
if(sh.cur_line)
|
||||
{
|
||||
getdolarg(shp,MAX_ARGN,(int*)0);
|
||||
return(ltos(shp->offsets[0]));
|
||||
getdolarg(MAX_ARGN,(int*)0);
|
||||
return(ltos(sh.offsets[0]));
|
||||
}
|
||||
#endif /* SHOPT_FILESCAN */
|
||||
return(ltos(shp->st.dolc));
|
||||
return(ltos(sh.st.dolc));
|
||||
case '!':
|
||||
if(shp->bckpid)
|
||||
return(ltos(shp->bckpid));
|
||||
if(sh.bckpid)
|
||||
return(ltos(sh.bckpid));
|
||||
break;
|
||||
case '$':
|
||||
if(nv_isnull(SH_DOLLARNOD))
|
||||
return(ltos(shp->gd->pid));
|
||||
return(ltos(sh.pid));
|
||||
return(nv_getval(SH_DOLLARNOD));
|
||||
case '-':
|
||||
return(sh_argdolminus(shp->arg_context));
|
||||
return(sh_argdolminus(sh.arg_context));
|
||||
case '?':
|
||||
return(ltos(shp->savexit));
|
||||
return(ltos(sh.savexit));
|
||||
case 0:
|
||||
if(sh_isstate(SH_PROFILE) || shp->fn_depth==0 || !shp->st.cmdname)
|
||||
return(shp->shname);
|
||||
if(sh_isstate(SH_PROFILE) || sh.fn_depth==0 || !sh.st.cmdname)
|
||||
return(sh.shname);
|
||||
else
|
||||
return(shp->st.cmdname);
|
||||
return(sh.st.cmdname);
|
||||
}
|
||||
/* Handle 'set -u'/'set -o nounset' for special parameters */
|
||||
if(sh_isoption(SH_NOUNSET))
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
#endif /* _hdr_nc */
|
||||
|
||||
/* These routines are referenced by this module */
|
||||
static void exfile(Shell_t*, Sfio_t*,int);
|
||||
static void chkmail(Shell_t *shp, char*);
|
||||
static void exfile(Sfio_t*,int);
|
||||
static void chkmail(char*);
|
||||
#if !defined(_NEXT_SOURCE) && !defined(__sun)
|
||||
static void fixargs(char**,int);
|
||||
# undef fixargs_disabled
|
||||
|
@ -81,33 +81,27 @@ static char beenhere = 0;
|
|||
}
|
||||
#endif /* _lib_sigvec */
|
||||
|
||||
#ifdef PATH_BFPATH
|
||||
#define PATHCOMP NIL(Pathcomp_t*)
|
||||
#else
|
||||
#define PATHCOMP ""
|
||||
#endif
|
||||
|
||||
/*
|
||||
* search for file and exfile() it if it exists
|
||||
* 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* nid;
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
oid = error_info.id;
|
||||
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));
|
||||
exfile(shp, iop, fd);
|
||||
exfile(iop, fd);
|
||||
error_info.id = oid;
|
||||
free(nid);
|
||||
return 1;
|
||||
|
@ -124,7 +118,6 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
register char *name;
|
||||
register int fdin;
|
||||
register Sfio_t *iop;
|
||||
register Shell_t *shp;
|
||||
struct stat statb;
|
||||
int i, rshflag; /* set for restricted shell */
|
||||
char *command;
|
||||
|
@ -138,20 +131,20 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
_NutConf(_NC_SET_SUFFIXED_SEARCHING, 1);
|
||||
#endif /* _hdr_nc */
|
||||
fixargs(av,0);
|
||||
shp = sh_init(ac,av,userinit);
|
||||
sh_init(ac,av,userinit);
|
||||
time(&mailtime);
|
||||
if(rshflag=sh_isoption(SH_RESTRICTED))
|
||||
sh_offoption(SH_RESTRICTED);
|
||||
if(sigsetjmp(*((sigjmp_buf*)shp->jmpbuffer),0))
|
||||
if(sigsetjmp(*((sigjmp_buf*)sh.jmpbuffer),0))
|
||||
{
|
||||
/* begin script execution here */
|
||||
sh_reinit((char**)0);
|
||||
}
|
||||
shp->fn_depth = shp->dot_depth = 0;
|
||||
sh.fn_depth = sh.dot_depth = 0;
|
||||
command = error_info.id;
|
||||
if(nv_isnull(PS4NOD))
|
||||
nv_putval(PS4NOD,e_traceprompt,NV_RDONLY);
|
||||
path_pwd(shp,1);
|
||||
path_pwd();
|
||||
iop = (Sfio_t*)0;
|
||||
if(sh_isoption(SH_POSIX))
|
||||
sh_onoption(SH_LETOCTAL);
|
||||
|
@ -163,10 +156,10 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
{
|
||||
beenhere++;
|
||||
sh_onstate(SH_PROFILE);
|
||||
shp->sigflag[SIGTSTP] |= SH_SIGIGNORE;
|
||||
if(shp->gd->ppid==1)
|
||||
shp->login_sh++;
|
||||
if(shp->login_sh >= 2)
|
||||
sh.sigflag[SIGTSTP] |= SH_SIGIGNORE;
|
||||
if(sh.ppid==1)
|
||||
sh.login_sh++;
|
||||
if(sh.login_sh >= 2)
|
||||
sh_onoption(SH_LOGIN_SHELL);
|
||||
/* decide whether shell is interactive */
|
||||
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))
|
||||
{
|
||||
/* preset aliases for interactive non-POSIX ksh */
|
||||
dtclose(shp->alias_tree);
|
||||
shp->alias_tree = sh_inittree(shp,shtab_aliases);
|
||||
dtuserdata(shp->alias_tree,shp,1);
|
||||
dtclose(sh.alias_tree);
|
||||
sh.alias_tree = sh_inittree(shtab_aliases);
|
||||
dtuserdata(sh.alias_tree,&sh,1);
|
||||
}
|
||||
}
|
||||
#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))
|
||||
sh_onoption(SH_RC);
|
||||
#endif
|
||||
for(i=0; i<elementsof(shp->offoptions.v); i++)
|
||||
shp->options.v[i] &= ~shp->offoptions.v[i];
|
||||
for(i=0; i<elementsof(sh.offoptions.v); i++)
|
||||
sh.options.v[i] &= ~sh.offoptions.v[i];
|
||||
if(sh_isoption(SH_INTERACTIVE))
|
||||
{
|
||||
#ifdef SIGXCPU
|
||||
|
@ -204,53 +197,53 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
#endif /* SIGXFSZ */
|
||||
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))
|
||||
{
|
||||
/* system profile */
|
||||
sh_source(shp, iop, e_sysprofile);
|
||||
sh_source(iop, e_sysprofile);
|
||||
if(!sh_isoption(SH_NOUSRPROFILE) && !sh_isoption(SH_PRIVILEGED))
|
||||
{
|
||||
char **files = shp->gd->login_files;
|
||||
while ((name = *files++) && !sh_source(shp, iop, sh_mactry(shp,name)));
|
||||
char **files = sh.login_files;
|
||||
while ((name = *files++) && !sh_source(iop, sh_mactry(name)));
|
||||
}
|
||||
}
|
||||
/* make sure PWD is set up correctly */
|
||||
path_pwd(shp,1);
|
||||
path_pwd();
|
||||
if(!sh_isoption(SH_NOEXEC))
|
||||
{
|
||||
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;
|
||||
#if SHOPT_SYSRC
|
||||
if(!strmatch(name, "?(.)/./*"))
|
||||
sh_source(shp, iop, e_sysrc);
|
||||
sh_source(iop, e_sysrc);
|
||||
#endif
|
||||
if(name)
|
||||
{
|
||||
sh_source(shp, iop, name);
|
||||
sh_source(iop, name);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
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;
|
||||
shp->sigflag[SIGTSTP] &= ~(SH_SIGIGNORE);
|
||||
sh.st.cmdname = error_info.id = command;
|
||||
sh.sigflag[SIGTSTP] &= ~(SH_SIGIGNORE);
|
||||
sh_offstate(SH_PROFILE);
|
||||
if(rshflag)
|
||||
sh_onoption(SH_RESTRICTED);
|
||||
/* open input file if specified */
|
||||
if(shp->comdiv)
|
||||
if(sh.comdiv)
|
||||
{
|
||||
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
|
||||
{
|
||||
name = error_info.id;
|
||||
error_info.id = shp->shname;
|
||||
error_info.id = sh.shname;
|
||||
if(sh_isoption(SH_SFLAG))
|
||||
fdin = 0;
|
||||
else
|
||||
|
@ -274,16 +267,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
* try to undo effect of Solaris 2.5+
|
||||
* change for argv for setuid scripts
|
||||
*/
|
||||
if(shp->st.repl_index > 0)
|
||||
av[shp->st.repl_index] = shp->st.repl_arg;
|
||||
if(sh.st.repl_index > 0)
|
||||
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)))
|
||||
{
|
||||
av[0] = (type & SH_TYPE_LOGIN) ? cp : path_basename(cp);
|
||||
/* exec to change $0 for ps */
|
||||
execv(pathshell(),av);
|
||||
/* exec fails */
|
||||
shp->st.dolv[0] = av[0];
|
||||
fixargs(shp->st.dolv,1);
|
||||
sh.st.dolv[0] = av[0];
|
||||
fixargs(sh.st.dolv,1);
|
||||
}
|
||||
#endif
|
||||
name = av[0];
|
||||
|
@ -300,20 +293,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
fdin = -1;
|
||||
}
|
||||
else
|
||||
shp->st.filename = path_fullname(shp,name);
|
||||
sh.st.filename = path_fullname(name);
|
||||
sp = 0;
|
||||
if(fdin < 0 && !strchr(name,'/'))
|
||||
{
|
||||
#ifdef PATH_BFPATH
|
||||
if(path_absolute(shp,name,NIL(Pathcomp_t*),0))
|
||||
if(path_absolute(name,NIL(Pathcomp_t*),0))
|
||||
sp = stakptr(PATH_OFFSET);
|
||||
#else
|
||||
sp = path_absolute(shp,name,NIL(char*));
|
||||
#endif
|
||||
if(sp)
|
||||
{
|
||||
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)
|
||||
|
@ -328,16 +317,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
}
|
||||
/* try sh -c 'name "$@"' */
|
||||
sh_onoption(SH_CFLAG);
|
||||
shp->comdiv = (char*)sh_malloc(strlen(name)+7);
|
||||
name = strcopy(shp->comdiv,name);
|
||||
if(shp->st.dolc)
|
||||
sh.comdiv = (char*)sh_malloc(strlen(name)+7);
|
||||
name = strcopy(sh.comdiv,name);
|
||||
if(sh.st.dolc)
|
||||
strcopy(name," \"$@\"");
|
||||
goto shell_c;
|
||||
}
|
||||
if(fdin==0)
|
||||
fdin = sh_iomovefd(fdin);
|
||||
}
|
||||
shp->readscript = shp->shname;
|
||||
sh.readscript = sh.shname;
|
||||
}
|
||||
error_info.id = name;
|
||||
#if SHOPT_ACCT
|
||||
|
@ -354,14 +343,14 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
else
|
||||
{
|
||||
/* beenhere > 0: We're in a forked child, about to execute a script without a hashbang path. */
|
||||
fdin = shp->infd;
|
||||
fixargs(shp->st.dolv,1);
|
||||
fdin = sh.infd;
|
||||
fixargs(sh.st.dolv,1);
|
||||
}
|
||||
if(sh_isoption(SH_INTERACTIVE))
|
||||
sh_onstate(SH_INTERACTIVE);
|
||||
nv_putval(IFSNOD,(char*)e_sptbnl,NV_RDONLY);
|
||||
exfile(shp,iop,fdin);
|
||||
sh_done(shp,0);
|
||||
exfile(iop,fdin);
|
||||
sh_done(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -369,16 +358,16 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
|
|||
* 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;
|
||||
Shnode_t *t;
|
||||
int maxtry=IOMAXTRY, tdone=0, execflags;
|
||||
int states,jmpval;
|
||||
struct checkpt buff;
|
||||
sh_pushcontext(shp,&buff,SH_JMPERREXIT);
|
||||
sh_pushcontext(&sh,&buff,SH_JMPERREXIT);
|
||||
/* open input stream */
|
||||
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
|
||||
nv_putval(SH_PATHNAMENOD, sh.st.filename, NV_NOFREE);
|
||||
if(!iop)
|
||||
{
|
||||
if(fno > 0)
|
||||
|
@ -386,26 +375,26 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
|
|||
int r;
|
||||
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);
|
||||
fno = r;
|
||||
}
|
||||
fcntl(fno,F_SETFD,FD_CLOEXEC);
|
||||
shp->fdstatus[fno] |= IOCLEX;
|
||||
iop = sh_iostream((void*)shp,fno);
|
||||
sh.fdstatus[fno] |= IOCLEX;
|
||||
iop = sh_iostream(fno);
|
||||
}
|
||||
else
|
||||
iop = sfstdin;
|
||||
}
|
||||
else
|
||||
fno = -1;
|
||||
shp->infd = fno;
|
||||
sh.infd = fno;
|
||||
if(sh_isstate(SH_INTERACTIVE))
|
||||
{
|
||||
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();
|
||||
if(sh_histinit((void*)shp))
|
||||
if(sh_histinit())
|
||||
sh_onoption(SH_HISTORY);
|
||||
}
|
||||
else
|
||||
|
@ -425,17 +414,17 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
|
|||
if(jmpval)
|
||||
{
|
||||
Sfio_t *top;
|
||||
sh_iorestore((void*)shp,0,jmpval);
|
||||
hist_flush(shp->gd->hist_ptr);
|
||||
sfsync(shp->outpool);
|
||||
shp->st.execbrk = shp->st.breakcnt = 0;
|
||||
sh_iorestore(0,jmpval);
|
||||
hist_flush(sh.hist_ptr);
|
||||
sfsync(sh.outpool);
|
||||
sh.st.execbrk = sh.st.breakcnt = 0;
|
||||
/* check for return from profile or env file */
|
||||
if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
|
||||
{
|
||||
sh_setstate(states);
|
||||
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_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 */
|
||||
#ifdef SIGTSTP
|
||||
tcsetpgrp(job.fd,shp->gd->pid);
|
||||
tcsetpgrp(job.fd,sh.pid);
|
||||
#endif /* SIGTSTP */
|
||||
}
|
||||
/* error return here */
|
||||
sfclrerr(iop);
|
||||
sh_setstate(states);
|
||||
shp->st.optindex = 1;
|
||||
sh.st.optindex = 1;
|
||||
opt_info.offset = 0;
|
||||
shp->st.loopcnt = 0;
|
||||
shp->trapnote = 0;
|
||||
shp->intrap = 0;
|
||||
sh.st.loopcnt = 0;
|
||||
sh.trapnote = 0;
|
||||
sh.intrap = 0;
|
||||
error_info.line = 1;
|
||||
shp->inlineno = 1;
|
||||
shp->binscript = 0;
|
||||
shp->exittrap = 0;
|
||||
shp->errtrap = 0;
|
||||
shp->end_fn = 0;
|
||||
sh.inlineno = 1;
|
||||
sh.binscript = 0;
|
||||
sh.exittrap = 0;
|
||||
sh.errtrap = 0;
|
||||
sh.end_fn = 0;
|
||||
if(sfeof(iop))
|
||||
goto eof_or_error;
|
||||
/* command loop */
|
||||
while(1)
|
||||
{
|
||||
shp->nextprompt = 1;
|
||||
sh_freeup(shp);
|
||||
sh.nextprompt = 1;
|
||||
sh_freeup();
|
||||
stakset(NIL(char*),0);
|
||||
sh_offstate(SH_STOPOK);
|
||||
sh_offstate(SH_ERREXIT);
|
||||
|
@ -511,26 +500,26 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
|
|||
time(&curtime);
|
||||
if ((curtime - mailtime) >= sh_mailchk)
|
||||
{
|
||||
chkmail(shp,mail);
|
||||
chkmail(mail);
|
||||
mailtime = curtime;
|
||||
}
|
||||
}
|
||||
if(shp->gd->hist_ptr)
|
||||
hist_eof(shp->gd->hist_ptr);
|
||||
if(sh.hist_ptr)
|
||||
hist_eof(sh.hist_ptr);
|
||||
/* sets timeout for command entry */
|
||||
shp->timeout = shp->st.tmout;
|
||||
sh.timeout = sh.st.tmout;
|
||||
#if SHOPT_TIMEOUT
|
||||
if(shp->timeout <= 0 || shp->timeout > SHOPT_TIMEOUT)
|
||||
shp->timeout = SHOPT_TIMEOUT;
|
||||
if(sh.timeout <= 0 || sh.timeout > SHOPT_TIMEOUT)
|
||||
sh.timeout = SHOPT_TIMEOUT;
|
||||
#endif /* SHOPT_TIMEOUT */
|
||||
shp->inlineno = 1;
|
||||
sh.inlineno = 1;
|
||||
error_info.line = 1;
|
||||
shp->trapnote = 0;
|
||||
sh.trapnote = 0;
|
||||
if(buff.mode == SH_JMPEXIT)
|
||||
{
|
||||
buff.mode = SH_JMPERREXIT;
|
||||
#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
|
||||
}
|
||||
}
|
||||
|
@ -545,13 +534,13 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
|
|||
if(!sferr)
|
||||
{
|
||||
if(--maxtry>0 && sh_isoption(SH_IGNOREEOF)
|
||||
&& !sferror(sfstderr) && (shp->fdstatus[fno]&IOTTY))
|
||||
&& !sferror(sfstderr) && (sh.fdstatus[fno]&IOTTY))
|
||||
{
|
||||
sfclrerr(iop);
|
||||
errormsg(SH_DICT,0,e_logout);
|
||||
continue;
|
||||
}
|
||||
else if(job_close(shp)<0)
|
||||
else if(job_close()<0)
|
||||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
shp->exitval = sh.savexit;
|
||||
sh.exitval = sh.savexit;
|
||||
maxtry = IOMAXTRY;
|
||||
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr)
|
||||
if(sh_isstate(SH_INTERACTIVE) && sh.hist_ptr)
|
||||
{
|
||||
job_wait((pid_t)0);
|
||||
hist_eof(shp->gd->hist_ptr);
|
||||
hist_eof(sh.hist_ptr);
|
||||
sfsync(sfstderr);
|
||||
}
|
||||
if(sh_isoption(SH_HISTORY))
|
||||
sh_onstate(SH_HISTORY);
|
||||
job.waitall = job.curpgid = 0;
|
||||
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))
|
||||
error_info.flags &= ~ERROR_INTERACTIVE;
|
||||
shp->readscript = 0;
|
||||
if(sh_isstate(SH_INTERACTIVE) && shp->gd->hist_ptr)
|
||||
hist_flush(shp->gd->hist_ptr);
|
||||
sh.readscript = 0;
|
||||
if(sh_isstate(SH_INTERACTIVE) && sh.hist_ptr)
|
||||
hist_flush(sh.hist_ptr);
|
||||
sh_offstate(SH_HISTORY);
|
||||
if(t)
|
||||
{
|
||||
execflags = sh_state(SH_ERREXIT)|sh_state(SH_INTERACTIVE);
|
||||
/* The last command may not have to fork */
|
||||
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))
|
||||
{
|
||||
execflags |= sh_state(SH_NOFORK);
|
||||
}
|
||||
shp->st.execbrk = 0;
|
||||
sh.st.execbrk = 0;
|
||||
sh_exec(t,execflags);
|
||||
if(shp->forked)
|
||||
if(sh.forked)
|
||||
{
|
||||
sh_offstate(SH_INTERACTIVE);
|
||||
goto done;
|
||||
|
@ -611,27 +600,27 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
|
|||
}
|
||||
}
|
||||
done:
|
||||
sh_popcontext(shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
if(sh_isstate(SH_INTERACTIVE))
|
||||
{
|
||||
if(isatty(0) && !sh_isoption(SH_CFLAG))
|
||||
sfputc(sfstderr,'\n');
|
||||
job_close(shp);
|
||||
job_close();
|
||||
}
|
||||
if(jmpval == SH_JMPSCRIPT)
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
else if(jmpval == SH_JMPEXIT)
|
||||
sh_done(shp,0);
|
||||
sh_done(0);
|
||||
if(fno>0)
|
||||
sh_close(fno);
|
||||
if(shp->st.filename)
|
||||
free((void*)shp->st.filename);
|
||||
shp->st.filename = 0;
|
||||
if(sh.st.filename)
|
||||
free((void*)sh.st.filename);
|
||||
sh.st.filename = 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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 save;
|
||||
|
@ -665,7 +654,7 @@ static void chkmail(Shell_t *shp, char *files)
|
|||
if(!arglist && S_ISDIR(statb.st_mode))
|
||||
{
|
||||
/* generate list of directory entries */
|
||||
path_complete(shp,cp,"/*",&arglist);
|
||||
path_complete(cp,"/*",&arglist);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -680,10 +669,10 @@ static void chkmail(Shell_t *shp, char *files)
|
|||
|| statb.st_size > lastmail.st_size))
|
||||
{
|
||||
/* save and restore $_ */
|
||||
char *save = shp->lastarg;
|
||||
shp->lastarg = cp;
|
||||
errormsg(SH_DICT,0,sh_mactry(shp,qp?qp+1:(char*)e_mailmsg));
|
||||
shp->lastarg = save;
|
||||
char *save = sh.lastarg;
|
||||
sh.lastarg = cp;
|
||||
errormsg(SH_DICT,0,sh_mactry(qp?qp+1:(char*)e_mailmsg));
|
||||
sh.lastarg = save;
|
||||
}
|
||||
lastmail = statb;
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -78,7 +78,6 @@ Sfdouble_t nv_getn(Namval_t *np, register Namfun_t *nfp)
|
|||
{
|
||||
register Namfun_t *fp;
|
||||
register Sfdouble_t d=0;
|
||||
Shell_t *shp = sh_getinterp();
|
||||
char *str;
|
||||
if((fp = nfp) != NIL(Namfun_t*) && !nv_local)
|
||||
fp = nfp = nfp->next;
|
||||
|
@ -106,7 +105,7 @@ Sfdouble_t nv_getn(Namval_t *np, register Namfun_t *nfp)
|
|||
else
|
||||
str = nv_getv(np,fp?fp:nfp);
|
||||
if(str && *str)
|
||||
d = sh_arith(shp,str);
|
||||
d = sh_arith(str);
|
||||
}
|
||||
return(d);
|
||||
}
|
||||
|
@ -291,7 +290,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
|
|||
int bflag;
|
||||
/* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */
|
||||
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);
|
||||
if(bflag = (type==APPEND && !isblocked(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_popcontext(&sh, &checkpoint);
|
||||
if(sh.topfd != checkpoint.topfd)
|
||||
sh_iorestore(&sh, checkpoint.topfd, jmpval);
|
||||
sh_iorestore(checkpoint.topfd, jmpval);
|
||||
unblock(bp,type);
|
||||
if(bflag)
|
||||
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;
|
||||
/* disciplines like PS2 may run at parse time; save, reinit and restore the lexer state */
|
||||
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;
|
||||
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_popcontext(&sh, &checkpoint);
|
||||
if(sh.topfd != checkpoint.topfd)
|
||||
sh_iorestore(&sh, checkpoint.topfd, jmpval);
|
||||
sh_iorestore(checkpoint.topfd, jmpval);
|
||||
unblock(bp,type);
|
||||
if(!vp->disc[type])
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
int c,offset = staktell();
|
||||
register char *sp, *cp=0;
|
||||
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(nv_istable(nq))
|
||||
{
|
||||
Namval_t *nsp = shp->namespace;
|
||||
Namval_t *nsp = sh.namespace;
|
||||
if(last==0)
|
||||
return(nv_search(name,root,0));
|
||||
shp->namespace = 0;
|
||||
sh.namespace = 0;
|
||||
stakputs(nv_name(nq));
|
||||
shp->namespace = nsp;
|
||||
sh.namespace = nsp;
|
||||
stakputs(dname-1);
|
||||
stakputc(0);
|
||||
np = nv_search(stakptr(offset),root,0);
|
||||
|
@ -1300,7 +1298,6 @@ struct table
|
|||
{
|
||||
Namfun_t fun;
|
||||
Namval_t *parent;
|
||||
Shell_t *shp;
|
||||
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)
|
||||
{
|
||||
struct table *tp = (struct table *)fp;
|
||||
tp->shp->last_table = np;
|
||||
sh.last_table = np;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
Shell_t *sh;
|
||||
Namval_t *tp;
|
||||
char *mapname;
|
||||
char **argnam;
|
||||
|
@ -1351,8 +1351,7 @@ struct adata
|
|||
|
||||
static void delete_fun(Namval_t *np, void *data)
|
||||
{
|
||||
Shell_t *shp = ((struct adata*)data)->sh;
|
||||
nv_delete(np,shp->fun_tree,NV_NOFREE);
|
||||
nv_delete(np,sh.fun_tree,NV_NOFREE);
|
||||
}
|
||||
|
||||
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;
|
||||
memset(&data,0,sizeof(data));
|
||||
data.mapname = nv_name(np);
|
||||
data.sh = ((struct table*)fp)->shp;
|
||||
nv_scan(data.sh->fun_tree,delete_fun,(void*)&data,NV_FUNCTION,NV_FUNCTION|NV_NOSCOPE);
|
||||
nv_scan(sh.fun_tree,delete_fun,(void*)&data,NV_FUNCTION,NV_FUNCTION|NV_NOSCOPE);
|
||||
dtview(root,0);
|
||||
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)
|
||||
{
|
||||
Shell_t *shp=sh_getinterp();
|
||||
struct table *tp = (struct table*)nv_hasdisc(np,&table_disc);
|
||||
if(tp)
|
||||
return(tp->dict);
|
||||
np = shp->last_table;
|
||||
np = sh.last_table;
|
||||
if(np && (tp = (struct table*)nv_hasdisc(np,&table_disc)))
|
||||
return(tp->dict);
|
||||
return(shp->var_tree);
|
||||
return(sh.var_tree);
|
||||
}
|
||||
|
||||
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);
|
||||
if(!nv_isnull(mp))
|
||||
_nv_unset(mp,NV_RDONLY);
|
||||
tp->shp = sh_getinterp();
|
||||
tp->dict = dict;
|
||||
tp->parent = pp;
|
||||
tp->fun.disc = &table_disc;
|
||||
|
@ -1503,7 +1499,7 @@ const Namdisc_t *nv_discfun(int which)
|
|||
int nv_hasget(Namval_t *np)
|
||||
{
|
||||
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 */
|
||||
for(fp=np->nvfun; fp; fp=fp->next)
|
||||
{
|
||||
|
@ -1515,13 +1511,12 @@ int nv_hasget(Namval_t *np)
|
|||
}
|
||||
|
||||
#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(stkp);
|
||||
sfputr(stkp,nv_name(shp->namespace),'.');
|
||||
sfputr(stkp,fname,0);
|
||||
fname = stkptr(stkp,offset);
|
||||
int offset = stktell(sh.stk);
|
||||
sfputr(sh.stk,nv_name(sh.namespace),'.');
|
||||
sfputr(sh.stk,fname,0);
|
||||
fname = stkptr(sh.stk,offset);
|
||||
return(nv_search(fname,sh_subfuntree(add&NV_ADD),add));
|
||||
}
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
|
|
|
@ -538,7 +538,6 @@ void nv_attribute(register Namval_t *np,Sfio_t *out,char *prefix,int noname)
|
|||
|
||||
struct Walk
|
||||
{
|
||||
Shell_t *shp;
|
||||
Sfio_t *out;
|
||||
Dt_t *root;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
int isarray=0, special=0,mode=0;
|
||||
if(*name!='.' || vname[strlen(vname)-1]==']')
|
||||
mode = NV_ARRAY;
|
||||
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;
|
||||
}
|
||||
if(!wp->out)
|
||||
wp->shp->last_table = last_table;
|
||||
sh.last_table = last_table;
|
||||
fp = nv_hasdisc(np,&treedisc);
|
||||
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);
|
||||
Dt_t *save_tree = sh.var_tree;
|
||||
Namval_t *mp=0;
|
||||
Shell_t *shp = sh_getinterp();
|
||||
char *xpname = xp?stakcopy(nv_name(xp)):0;
|
||||
walk.shp = shp;
|
||||
if(xp)
|
||||
{
|
||||
shp->last_root = shp->prev_root;
|
||||
shp->last_table = shp->prev_table;
|
||||
sh.last_root = sh.prev_root;
|
||||
sh.last_table = sh.prev_table;
|
||||
}
|
||||
if(shp->last_table)
|
||||
shp->last_root = nv_dict(shp->last_table);
|
||||
if(shp->last_root)
|
||||
shp->var_tree = shp->last_root;
|
||||
if(sh.last_table)
|
||||
sh.last_root = nv_dict(sh.last_table);
|
||||
if(sh.last_root)
|
||||
sh.var_tree = sh.last_root;
|
||||
stakputs(nv_name(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;
|
||||
name = stakfreeze(1);
|
||||
len = strlen(name);
|
||||
shp->last_root = 0;
|
||||
sh.last_root = 0;
|
||||
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)
|
||||
name[strlen(name)-1] = 0;
|
||||
while(cp = nv_dirnext(dir))
|
||||
|
@ -988,7 +985,7 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
|
|||
continue;
|
||||
if(xp)
|
||||
{
|
||||
Dt_t *dp = shp->var_tree;
|
||||
Dt_t *dp = sh.var_tree;
|
||||
Namval_t *nq, *mq;
|
||||
if(strlen(cp)<=len)
|
||||
continue;
|
||||
|
@ -999,9 +996,9 @@ static char *walk_tree(register Namval_t *np, Namval_t *xp, int flags)
|
|||
stakputs(xpname);
|
||||
stakputs(cp+len);
|
||||
stakputc(0);
|
||||
shp->var_tree = save_tree;
|
||||
mq = nv_open(stakptr(0),shp->prev_root,NV_VARNAME|NV_NOASSIGN|NV_NOFAIL);
|
||||
shp->var_tree = dp;
|
||||
sh.var_tree = save_tree;
|
||||
mq = nv_open(stakptr(0),sh.prev_root,NV_VARNAME|NV_NOASSIGN|NV_NOFAIL);
|
||||
sh.var_tree = dp;
|
||||
if(nq && mq)
|
||||
{
|
||||
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);
|
||||
if(xp)
|
||||
{
|
||||
shp->var_tree = save_tree;
|
||||
sh.var_tree = save_tree;
|
||||
return((char*)0);
|
||||
}
|
||||
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;
|
||||
genvalue(argv,name,0,&walk);
|
||||
stakset(savptr,savtop);
|
||||
shp->var_tree = save_tree;
|
||||
sh.var_tree = save_tree;
|
||||
if(!outfile)
|
||||
return((char*)0);
|
||||
sfputc(out,0);
|
||||
|
@ -1095,16 +1092,15 @@ static void put_tree(register Namval_t *np, const char *val, int flags,Namfun_t
|
|||
return;
|
||||
if(!nv_isattr(np,(NV_INTEGER|NV_BINARY)))
|
||||
{
|
||||
Shell_t *shp = sh_getinterp();
|
||||
Namval_t *last_table = shp->last_table;
|
||||
Dt_t *last_root = shp->last_root;
|
||||
Namval_t *mp = val?nv_open(val,shp->var_tree,NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_ARRAY|NV_NOFAIL):0;
|
||||
Namval_t *last_table = sh.last_table;
|
||||
Dt_t *last_root = sh.last_root;
|
||||
Namval_t *mp = val?nv_open(val,sh.var_tree,NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_ARRAY|NV_NOFAIL):0;
|
||||
if(mp && nv_isvtree(mp))
|
||||
{
|
||||
shp->prev_table = shp->last_table;
|
||||
shp->prev_root = shp->last_root;
|
||||
shp->last_table = last_table;
|
||||
shp->last_root = last_root;
|
||||
sh.prev_table = sh.last_table;
|
||||
sh.prev_root = sh.last_root;
|
||||
sh.last_table = last_table;
|
||||
sh.last_root = last_root;
|
||||
if(!(flags&NV_APPEND))
|
||||
walk_tree(np,(Namval_t*)0,(flags&NV_NOSCOPE)|1);
|
||||
nv_clone(mp,np,NV_COMVAR);
|
||||
|
|
|
@ -79,7 +79,6 @@ typedef struct Namchld
|
|||
struct Namtype
|
||||
{
|
||||
Namfun_t fun;
|
||||
Shell_t *sh;
|
||||
Namval_t *np;
|
||||
Namval_t *parent;
|
||||
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);
|
||||
Optdisc_t *dp = (Optdisc_t*)(cp+1);
|
||||
Shell_t *shp = sh_getinterp();
|
||||
Namval_t *mp,*bp;
|
||||
char *name;
|
||||
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);
|
||||
cp->optinfof = (void*)dp;
|
||||
cp->tp = np;
|
||||
mp = nv_search("typeset",shp->bltin_tree,0);
|
||||
mp = nv_search("typeset",sh.bltin_tree,0);
|
||||
if(name=strrchr(np->nvname,'.'))
|
||||
name++;
|
||||
else
|
||||
name = np->nvname;
|
||||
#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);
|
||||
if(tp)
|
||||
tp->nsp = bp;
|
||||
if(!shp->strbuf2)
|
||||
shp->strbuf2 = sfstropen();
|
||||
sfprintf(shp->strbuf2,".%s.%s%c\n",nv_name(bp)+1,name,0);
|
||||
name = sfstruse(shp->strbuf2);
|
||||
if(!sh.strbuf2)
|
||||
sh.strbuf2 = sfstropen();
|
||||
sfprintf(sh.strbuf2,".%s.%s%c\n",nv_name(bp)+1,name,0);
|
||||
name = sfstruse(sh.strbuf2);
|
||||
}
|
||||
#endif /* SHOPT_NAMESPACE */
|
||||
if((bp=nv_search(name,shp->fun_tree,NV_NOSCOPE)) && !bp->nvalue.ip)
|
||||
nv_delete(bp,shp->fun_tree,0);
|
||||
if((bp=nv_search(name,sh.fun_tree,NV_NOSCOPE)) && !bp->nvalue.ip)
|
||||
nv_delete(bp,sh.fun_tree,0);
|
||||
bp = sh_addbuiltin(name, (Shbltin_f)mp->nvalue.bfp, (void*)cp);
|
||||
nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
|
||||
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);
|
||||
char *val=0;
|
||||
Namarr_t *ap=0;
|
||||
Shell_t *shp = sh_getinterp();
|
||||
int nelem = 0;
|
||||
unsigned int subshell = shp->subshell;
|
||||
unsigned int subshell = sh.subshell;
|
||||
#if SHOPT_TYPEDEF
|
||||
Namval_t *tq;
|
||||
if(nv_type(np)==tp)
|
||||
|
@ -1326,7 +1323,7 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags)
|
|||
if(subshell)
|
||||
{
|
||||
sh_assignok(np,1);
|
||||
shp->subshell = 0;
|
||||
sh.subshell = 0;
|
||||
}
|
||||
nv_putsub(np,"0",ARRAY_FILL);
|
||||
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_unset(np,NV_RDONLY|NV_TYPE);
|
||||
ap->nelem--;
|
||||
shp->subshell = subshell;
|
||||
sh.subshell = subshell;
|
||||
}
|
||||
}
|
||||
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;
|
||||
Dt_t *dp;
|
||||
char *cp,*sp,*xp,nvtype[sizeof(NV_CLASS)];
|
||||
Sfio_t *iop=0;
|
||||
int n=0,indent = 0;
|
||||
if(cp=shp->prefix)
|
||||
if(cp=sh.prefix)
|
||||
{
|
||||
indent=1;
|
||||
while(*cp)
|
||||
|
@ -1444,10 +1441,10 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
|
|||
if(*cp++ =='.')
|
||||
indent++;
|
||||
}
|
||||
n = cp-shp->prefix+1;
|
||||
n = cp-sh.prefix+1;
|
||||
}
|
||||
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);
|
||||
memcpy(&node,L_ARGNOD,sizeof(node));
|
||||
L_ARGNOD->nvfun = 0;
|
||||
|
@ -1459,7 +1456,7 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
|
|||
/* skip over enums */
|
||||
if(tp->nvfun && !nv_isvtree(tp))
|
||||
continue;
|
||||
if(!nv_search(tp->nvname,shp->bltin_tree,0))
|
||||
if(!nv_search(tp->nvname,sh.bltin_tree,0))
|
||||
continue;
|
||||
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))
|
||||
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;
|
||||
nv_settype(L_ARGNOD,tp,0);
|
||||
if(indent)
|
||||
sfnputc(out,'\t',indent);
|
||||
sfprintf(out,"typeset -T %s=",tp->nvname+n);
|
||||
shp->last_table = 0;
|
||||
sh.last_table = 0;
|
||||
cp = nv_getval(L_ARGNOD);
|
||||
if(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(nv_isattr(mp,NV_FTMP))
|
||||
iop = shp->heredocs;
|
||||
iop = sh.heredocs;
|
||||
else if(xp=mp->nvalue.rp->fname)
|
||||
iop = sfopen(iop,xp,"r");
|
||||
else if(shp->gd->hist_ptr)
|
||||
iop = (shp->gd->hist_ptr)->histfp;
|
||||
else if(sh.hist_ptr)
|
||||
iop = sh.hist_ptr->histfp;
|
||||
if(iop && sfseek(iop,(Sfoff_t)mp->nvalue.rp->hoffset,SEEK_SET)>=0)
|
||||
sfmove(iop,out, nv_size(mp), -1);
|
||||
else
|
||||
|
@ -1530,8 +1527,8 @@ int sh_outtype(Shell_t *shp,Sfio_t *out)
|
|||
sfnputc(out,'\t',indent);
|
||||
sfwrite(out,")\n",2);
|
||||
}
|
||||
dtdelete(shp->var_base,L_ARGNOD);
|
||||
dtdelete(sh.var_base,L_ARGNOD);
|
||||
memcpy(L_ARGNOD,&node,sizeof(node));
|
||||
dtinsert(shp->var_base,L_ARGNOD);
|
||||
dtinsert(sh.var_base,L_ARGNOD);
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ static unsigned long writedefs(Lex_t *lexp,struct argnod *arglist, int line, int
|
|||
n = cp-argp->argval;
|
||||
else
|
||||
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);
|
||||
sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline);
|
||||
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.arexpr = ap;
|
||||
if(ap->argflag&ARG_RAW)
|
||||
t->ar.arcomp = sh_arithcomp(lp->sh,ap->argval);
|
||||
t->ar.arcomp = sh_arithcomp(ap->argval);
|
||||
else
|
||||
{
|
||||
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++)
|
||||
;
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
|
||||
void *sh_parse(Sfio_t *iop, int flag)
|
||||
{
|
||||
register Shnode_t *t;
|
||||
Lex_t *lexp = (Lex_t*)shp->lex_context;
|
||||
Lex_t *lexp = (Lex_t*)sh.lex_context;
|
||||
Fcin_t sav_input;
|
||||
struct argnod *sav_arg = lexp->arg;
|
||||
int sav_prompt = shp->nextprompt;
|
||||
if(shp->binscript && (sffileno(iop)==shp->infd || (flag&SH_FUNEVAL)))
|
||||
return((void*)sh_trestore(shp,iop));
|
||||
int sav_prompt = sh.nextprompt;
|
||||
if(sh.binscript && (sffileno(iop)==sh.infd || (flag&SH_FUNEVAL)))
|
||||
return((void*)sh_trestore(iop));
|
||||
fcsave(&sav_input);
|
||||
shp->st.staklist = 0;
|
||||
sh.st.staklist = 0;
|
||||
lexp->noreserv = 0;
|
||||
lexp->heredoc = 0;
|
||||
lexp->inlineno = shp->inlineno;
|
||||
lexp->firstline = shp->st.firstline;
|
||||
shp->nextprompt = 1;
|
||||
lexp->inlineno = sh.inlineno;
|
||||
lexp->firstline = sh.st.firstline;
|
||||
sh.nextprompt = 1;
|
||||
loop_level = 0;
|
||||
label_list = label_last = 0;
|
||||
if(sh_isoption(SH_VERBOSE))
|
||||
sh_onstate(SH_VERBOSE);
|
||||
sh_lexopen(lexp,shp,0);
|
||||
sh_lexopen(lexp,0);
|
||||
if(fcfopen(iop) < 0)
|
||||
return(NIL(void*));
|
||||
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);
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(sffileno(iop)==shp->infd || (flag&SH_FUNEVAL))
|
||||
shp->binscript = 1;
|
||||
if(sffileno(iop)==sh.infd || (flag&SH_FUNEVAL))
|
||||
sh.binscript = 1;
|
||||
sfgetc(iop);
|
||||
t = sh_trestore(shp,iop);
|
||||
t = sh_trestore(iop);
|
||||
if(flag&SH_NL)
|
||||
{
|
||||
Shnode_t *tt;
|
||||
while(1)
|
||||
{
|
||||
if(!(tt = sh_trestore(shp,iop)))
|
||||
if(!(tt = sh_trestore(iop)))
|
||||
break;
|
||||
t =makelist(lexp,TLST, t, tt);
|
||||
}
|
||||
|
@ -423,9 +423,9 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
|
|||
}
|
||||
}
|
||||
flag &= ~SH_FUNEVAL;
|
||||
if((flag&SH_NL) && (shp->inlineno=error_info.line+shp->st.firstline)==0)
|
||||
shp->inlineno=1;
|
||||
shp->nextprompt = 2;
|
||||
if((flag&SH_NL) && (sh.inlineno=error_info.line+sh.st.firstline)==0)
|
||||
sh.inlineno=1;
|
||||
sh.nextprompt = 2;
|
||||
t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL));
|
||||
fcclose();
|
||||
fcrestore(&sav_input);
|
||||
|
@ -437,13 +437,13 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
|
|||
if(sp)
|
||||
sfclose(sp);
|
||||
}
|
||||
shp->nextprompt = sav_prompt;
|
||||
sh.nextprompt = sav_prompt;
|
||||
if(flag&SH_NL)
|
||||
{
|
||||
shp->st.firstline = lexp->firstline;
|
||||
shp->inlineno = lexp->inlineno;
|
||||
sh.st.firstline = lexp->firstline;
|
||||
sh.inlineno = lexp->inlineno;
|
||||
}
|
||||
stkseek(shp->stk,0);
|
||||
stkseek(sh.stk,0);
|
||||
return((void*)t);
|
||||
}
|
||||
|
||||
|
@ -455,9 +455,9 @@ Shnode_t *sh_dolparen(Lex_t* lp)
|
|||
{
|
||||
register Shnode_t *t=0;
|
||||
Sfio_t *sp = fcfile();
|
||||
int line = lp->sh->inlineno;
|
||||
lp->sh->inlineno = error_info.line+lp->sh->st.firstline;
|
||||
sh_lexopen(lp,lp->sh,1);
|
||||
int line = sh.inlineno;
|
||||
sh.inlineno = error_info.line+sh.st.firstline;
|
||||
sh_lexopen(lp,1);
|
||||
lp->comsub = 1;
|
||||
switch(sh_lex(lp))
|
||||
{
|
||||
|
@ -488,7 +488,7 @@ Shnode_t *sh_dolparen(Lex_t* lp)
|
|||
fcsopen(cp);
|
||||
sfclose(sp);
|
||||
}
|
||||
lp->sh->inlineno = line;
|
||||
sh.inlineno = line;
|
||||
return(t);
|
||||
}
|
||||
|
||||
|
@ -496,11 +496,11 @@ Shnode_t *sh_dolparen(Lex_t* lp)
|
|||
* remove temporary files and stacks
|
||||
*/
|
||||
|
||||
void sh_freeup(Shell_t *shp)
|
||||
void sh_freeup(void)
|
||||
{
|
||||
if(shp->st.staklist)
|
||||
sh_funstaks(shp->st.staklist,-1);
|
||||
shp->st.staklist = 0;
|
||||
if(sh.st.staklist)
|
||||
sh_funstaks(sh.st.staklist,-1);
|
||||
sh.st.staklist = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -705,7 +705,7 @@ static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
|
|||
register int offset;
|
||||
register struct argnod *argp;
|
||||
register int n;
|
||||
Stk_t *stkp = lexp->sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
int argflag = lexp->arg->argflag;
|
||||
/* save current input */
|
||||
Fcin_t sav_input;
|
||||
|
@ -761,7 +761,7 @@ static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
|
|||
}
|
||||
else
|
||||
tw->wh.whinc = 0;
|
||||
sh_lexopen(lexp, lexp->sh,1);
|
||||
sh_lexopen(lexp, 1);
|
||||
if((n=sh_lex(lexp))==NL)
|
||||
n = skipnl(lexp,0);
|
||||
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)
|
||||
{
|
||||
Shell_t *shp = lexp->sh;
|
||||
register Shnode_t *t;
|
||||
register int flag;
|
||||
struct slnod *volatile slp=0;
|
||||
|
@ -791,11 +790,11 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
struct argnod *savelabel = label_last;
|
||||
struct checkpt buff;
|
||||
int save_optget = opt_get;
|
||||
void *in_mktype = shp->mktype;
|
||||
shp->mktype = 0;
|
||||
void *in_mktype = sh.mktype;
|
||||
sh.mktype = 0;
|
||||
opt_get = 0;
|
||||
t = getnode(functnod);
|
||||
t->funct.functline = shp->inlineno;
|
||||
t->funct.functline = sh.inlineno;
|
||||
t->funct.functtyp=TFUN;
|
||||
t->funct.functargs = 0;
|
||||
if(!(flag = (lexp->token==FUNCTSYM)))
|
||||
|
@ -809,21 +808,21 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
fcfopen(iop);
|
||||
}
|
||||
t->funct.functloc = first = fctell();
|
||||
if(!shp->st.filename || sffileno(iop)<0)
|
||||
if(!sh.st.filename || sffileno(iop)<0)
|
||||
{
|
||||
if(fcfill() >= 0)
|
||||
fcseek(-1);
|
||||
if(sh_isstate(SH_HISTORY) && shp->gd->hist_ptr)
|
||||
t->funct.functloc = sfseek(shp->gd->hist_ptr->histfp,(off_t)0,SEEK_CUR);
|
||||
if(sh_isstate(SH_HISTORY) && sh.hist_ptr)
|
||||
t->funct.functloc = sfseek(sh.hist_ptr->histfp, (off_t)0, SEEK_CUR);
|
||||
else
|
||||
{
|
||||
/* copy source to temporary file */
|
||||
t->funct.functloc = 0;
|
||||
if(lexp->sh->heredocs)
|
||||
t->funct.functloc = sfseek(lexp->sh->heredocs,(Sfoff_t)0, SEEK_END);
|
||||
if(sh.heredocs)
|
||||
t->funct.functloc = sfseek(sh.heredocs,(Sfoff_t)0, SEEK_END);
|
||||
else
|
||||
lexp->sh->heredocs = sftmp(HERE_MEM);
|
||||
lexp->sh->funlog = lexp->sh->heredocs;
|
||||
sh.heredocs = sftmp(HERE_MEM);
|
||||
sh.funlog = sh.heredocs;
|
||||
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*));
|
||||
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();
|
||||
}
|
||||
argv0 = argv = ((struct dolnod*)ac->comarg)->dolval+ARG_SPARE;
|
||||
|
@ -858,15 +857,15 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
}
|
||||
if(c)
|
||||
{
|
||||
errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,lexp->sh->inlineno);
|
||||
errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,sh.inlineno);
|
||||
UNREACHABLE();
|
||||
}
|
||||
nargs = argv-argv0;
|
||||
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);
|
||||
np->nvalue.rp = new_of(struct Ufunction,shp->funload?sizeof(Dtlink_t):0);
|
||||
Namval_t *np= nv_open(t->funct.functnam,sh.fun_tree,NV_ADD|NV_VARNAME);
|
||||
np->nvalue.rp = new_of(struct Ufunction,sh.funload?sizeof(Dtlink_t):0);
|
||||
memset((void*)np->nvalue.rp,0,sizeof(struct Ufunction));
|
||||
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)
|
||||
sh_syntax(lexp);
|
||||
sh_pushcontext(shp,&buff,1);
|
||||
sh_pushcontext(&sh,&buff,1);
|
||||
jmpval = sigsetjmp(buff.buff,0);
|
||||
if(jmpval == 0)
|
||||
{
|
||||
|
@ -885,8 +884,8 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
savstak = stakinstall(savstak, 0);
|
||||
slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod));
|
||||
slp->slchild = 0;
|
||||
slp->slnext = shp->st.staklist;
|
||||
shp->st.staklist = 0;
|
||||
slp->slnext = sh.st.staklist;
|
||||
sh.st.staklist = 0;
|
||||
t->funct.functstak = (struct slnod*)slp;
|
||||
/*
|
||||
* store the pathname of function definition file on stack
|
||||
|
@ -897,8 +896,8 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
fp->functnam = 0;
|
||||
fp->functargs = 0;
|
||||
fp->functline = t->funct.functline;
|
||||
if(shp->st.filename)
|
||||
fp->functnam = stakcopy(shp->st.filename);
|
||||
if(sh.st.filename)
|
||||
fp->functnam = stakcopy(sh.st.filename);
|
||||
loop_level = 0;
|
||||
label_last = label_list;
|
||||
if(size)
|
||||
|
@ -926,16 +925,16 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
}
|
||||
t->funct.functtre = item(lexp,SH_NOIO);
|
||||
}
|
||||
else if(shp->shcomp)
|
||||
else if(sh.shcomp)
|
||||
exit(1);
|
||||
sh_popcontext(shp,&buff);
|
||||
sh_popcontext(&sh,&buff);
|
||||
loop_level = saveloop;
|
||||
label_last = savelabel;
|
||||
/* restore the old stack */
|
||||
if(slp)
|
||||
{
|
||||
slp->slptr = stakinstall(savstak,0);
|
||||
slp->slchild = shp->st.staklist;
|
||||
slp->slchild = sh.st.staklist;
|
||||
}
|
||||
#if SHOPT_KIA
|
||||
lexp->current = current;
|
||||
|
@ -944,25 +943,25 @@ static Shnode_t *funct(Lex_t *lexp)
|
|||
{
|
||||
if(slp && slp->slptr)
|
||||
{
|
||||
shp->st.staklist = slp->slnext;
|
||||
sh.st.staklist = slp->slnext;
|
||||
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();
|
||||
fp->functline = (last-first);
|
||||
fp->functtre = t;
|
||||
shp->mktype = in_mktype;
|
||||
if(lexp->sh->funlog)
|
||||
sh.mktype = in_mktype;
|
||||
if(sh.funlog)
|
||||
{
|
||||
if(fcfill()>0)
|
||||
fcseek(-1);
|
||||
lexp->sh->funlog = 0;
|
||||
sh.funlog = 0;
|
||||
}
|
||||
#if SHOPT_KIA
|
||||
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 */
|
||||
t->funct.functtyp |= opt_get;
|
||||
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 Shnode_t *t, **tp;
|
||||
register struct comnod *ac;
|
||||
Stk_t *stkp = lexp->sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
int array=0, index=0;
|
||||
Namval_t *np;
|
||||
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 &&
|
||||
n!=FUNCTSYM &&
|
||||
!(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)))
|
||||
{
|
||||
array=SH_ARRAY;
|
||||
|
@ -1088,10 +1087,10 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
|
|||
n = lexp->token;
|
||||
dcl_recursion = 1;
|
||||
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_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->arg = arg;
|
||||
|
@ -1128,7 +1127,7 @@ static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int type)
|
|||
}
|
||||
if((n!=FUNCTSYM) &&
|
||||
!(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)))
|
||||
{
|
||||
struct argnod *arg = lexp->arg;
|
||||
|
@ -1206,7 +1205,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
|
|||
t->sw.swtyp=TSW;
|
||||
t->sw.swio = 0;
|
||||
t->sw.swtyp |= FLINENO;
|
||||
t->sw.swline = lexp->sh->inlineno;
|
||||
t->sw.swline = sh.inlineno;
|
||||
if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE)
|
||||
sh_syntax(lexp);
|
||||
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->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT);
|
||||
t->for_.forlst=0;
|
||||
t->for_.forline = lexp->sh->inlineno;
|
||||
t->for_.forline = sh.inlineno;
|
||||
if(sh_lex(lexp))
|
||||
{
|
||||
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;
|
||||
#if SHOPT_KIA
|
||||
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 */
|
||||
while((tok=sh_lex(lexp))==NL);
|
||||
if(tok==INSYM)
|
||||
|
@ -1272,7 +1271,7 @@ static Shnode_t *item(Lex_t *lexp,int flag)
|
|||
sh_syntax(lexp);
|
||||
/* some Linux scripts assume this */
|
||||
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)->comarg = 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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
argp = argp->argnxt.ap;
|
||||
|
@ -1415,7 +1414,7 @@ static struct argnod *process_sub(Lex_t *lexp,int tok)
|
|||
Shnode_t *t;
|
||||
int mode = (tok==OPROCSYM);
|
||||
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->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t);
|
||||
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 argnod *argp;
|
||||
register int tok;
|
||||
Stk_t *stkp = lexp->sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
struct argnod **argtail;
|
||||
struct argnod **settail;
|
||||
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,'/')))
|
||||
{
|
||||
/* 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(cmdarg==0)
|
||||
|
@ -1667,11 +1666,11 @@ static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
|
|||
break;
|
||||
}
|
||||
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=='+') &&
|
||||
(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 */
|
||||
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 struct ionod *iop;
|
||||
Stk_t *stkp = lexp->sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
char *iovname=0;
|
||||
register int errout=0;
|
||||
if(token==IOVNAME)
|
||||
|
@ -1794,8 +1793,8 @@ static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!lexp->sh->heredocs)
|
||||
lexp->sh->heredocs = sftmp(HERE_MEM);
|
||||
if(!sh.heredocs)
|
||||
sh.heredocs = sftmp(HERE_MEM);
|
||||
iop->iolst=lexp->heredoc;
|
||||
lexp->heredoc=iop;
|
||||
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(lexp->kiafile)
|
||||
{
|
||||
int n = lexp->sh->inlineno-(lexp->token=='\n');
|
||||
int n = sh.inlineno-(lexp->token=='\n');
|
||||
if(!(iof&IOMOV))
|
||||
{
|
||||
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 '(':
|
||||
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;
|
||||
case '!':
|
||||
if(!(t = test_primary(lexp)))
|
||||
|
@ -1983,7 +1982,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
|
|||
#if SHOPT_KIA
|
||||
if(lexp->kiafile && !strchr("sntzoOG",num))
|
||||
{
|
||||
int line = lexp->sh->inlineno- (lexp->token==NL);
|
||||
int line = sh.inlineno- (lexp->token==NL);
|
||||
unsigned long r;
|
||||
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);
|
||||
|
@ -1991,7 +1990,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
|
|||
#endif /* SHOPT_KIA */
|
||||
t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT),
|
||||
(Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg);
|
||||
t->tst.tstline = lexp->sh->inlineno;
|
||||
t->tst.tstline = sh.inlineno;
|
||||
break;
|
||||
/* binary test operators */
|
||||
case 0:
|
||||
|
@ -2013,7 +2012,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
|
|||
{
|
||||
t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT),
|
||||
(Shnode_t*)arg,(Shnode_t*)arg);
|
||||
t->tst.tstline = lexp->sh->inlineno;
|
||||
t->tst.tstline = sh.inlineno;
|
||||
return(t);
|
||||
}
|
||||
else
|
||||
|
@ -2021,7 +2020,7 @@ static Shnode_t *test_primary(Lex_t *lexp)
|
|||
#if SHOPT_KIA
|
||||
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;
|
||||
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);
|
||||
|
@ -2039,11 +2038,11 @@ static Shnode_t *test_primary(Lex_t *lexp)
|
|||
t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT);
|
||||
t->lst.lstlef = (Shnode_t*)arg;
|
||||
t->lst.lstrit = (Shnode_t*)lexp->arg;
|
||||
t->tst.tstline = lexp->sh->inlineno;
|
||||
t->tst.tstline = sh.inlineno;
|
||||
#if SHOPT_KIA
|
||||
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;
|
||||
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);
|
||||
|
@ -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)
|
||||
{
|
||||
Stk_t *stkp = lexp->sh->stk;
|
||||
Stk_t *stkp = sh.stk;
|
||||
Namval_t *np;
|
||||
long offset = stktell(stkp);
|
||||
sfputc(stkp,type);
|
||||
|
@ -2119,9 +2118,9 @@ int kiaclose(Lex_t *lexp)
|
|||
register int n;
|
||||
if(lexp->kiafile)
|
||||
{
|
||||
unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,lexp->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,'f',1,lexp->sh->inlineno-1,r,'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,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);
|
||||
off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
|
||||
sfseek(lexp->kiatmp,(off_t)0,SEEK_SET);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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[])
|
||||
{
|
||||
Sfio_t *in, *out;
|
||||
Shell_t *shp;
|
||||
Namval_t *np;
|
||||
Shnode_t *t;
|
||||
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);
|
||||
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() */
|
||||
error_info.id = shcomp_id;
|
||||
shp->shcomp = 1;
|
||||
sh.shcomp = 1;
|
||||
argv += opt_info.index;
|
||||
argc -= opt_info.index;
|
||||
if(argc==0 && tty_check(0))
|
||||
|
@ -162,7 +161,7 @@ int main(int argc, char *argv[])
|
|||
if(!dflag)
|
||||
sfwrite(out,header,sizeof(header)); /* write binary shcomp header */
|
||||
sh_offoption(SH_MULTILINE);
|
||||
shp->inlineno = 1;
|
||||
sh.inlineno = 1;
|
||||
#if SHOPT_BRACEPAT
|
||||
sh_onoption(SH_BRACEEXPAND);
|
||||
#endif
|
||||
|
@ -170,7 +169,7 @@ int main(int argc, char *argv[])
|
|||
while(1)
|
||||
{
|
||||
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)
|
||||
/* Create aliases found in the script to prevent syntax errors */
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
|
||||
struct vars /* vars stacked per invocation */
|
||||
{
|
||||
Shell_t *shp;
|
||||
const char *expr; /* current expression */
|
||||
const char *nextchr; /* next char in current expression */
|
||||
const char *errchr; /* next char after error */
|
||||
|
@ -160,8 +159,6 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
int lastsub;
|
||||
Math_f fun;
|
||||
struct lval node;
|
||||
Shell_t *shp = ep->shp;
|
||||
node.shp = shp;
|
||||
node.emode = ep->emode;
|
||||
node.expr = ep->expr;
|
||||
node.elen = ep->elen;
|
||||
|
@ -170,7 +167,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
node.sub = 0;
|
||||
node.ptr = 0;
|
||||
node.eflag = 0;
|
||||
if(shp->arithrecursion++ >= MAXLEVEL)
|
||||
if(sh.arithrecursion++ >= MAXLEVEL)
|
||||
{
|
||||
arith_error(e_recursive,ep->expr,ep->emode);
|
||||
return(0);
|
||||
|
@ -242,7 +239,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
if(node.flag = c)
|
||||
lastval = 0;
|
||||
node.isfloat=0;
|
||||
node.level = shp->arithrecursion;
|
||||
node.level = sh.arithrecursion;
|
||||
node.nosub = 0;
|
||||
num = (*ep->fun)(&ptr,&node,VALUE,num);
|
||||
if(node.emode&ARITH_ASSIGNOP)
|
||||
|
@ -427,7 +424,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
c &= ~T_BINARY;
|
||||
arg[0] = num;
|
||||
arg[1] = 0;
|
||||
num = sh_mathfun(shp,(void*)fun,1,arg);
|
||||
num = sh_mathfun((void*)fun,1,arg);
|
||||
break;
|
||||
}
|
||||
num = (*((Math_1f_f)fun))(num);
|
||||
|
@ -448,7 +445,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
arg[0] = sp[1];
|
||||
arg[1] = num;
|
||||
arg[2] = 0;
|
||||
num = sh_mathfun(shp,(void*)fun,2,arg);
|
||||
num = sh_mathfun((void*)fun,2,arg);
|
||||
break;
|
||||
}
|
||||
if(c&T_NOFLOAT)
|
||||
|
@ -473,7 +470,7 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
arg[1] = sp[2];
|
||||
arg[2] = num;
|
||||
arg[3] = 0;
|
||||
num = sh_mathfun(shp,(void*)fun,3,arg);
|
||||
num = sh_mathfun((void*)fun,3,arg);
|
||||
break;
|
||||
}
|
||||
num = (*((Math_3f_f)fun))(sp[1],sp[2],num);
|
||||
|
@ -490,8 +487,8 @@ Sfdouble_t arith_exec(Arith_t *ep)
|
|||
*sp = num;
|
||||
*tp = type;
|
||||
}
|
||||
if(shp->arithrecursion>0)
|
||||
shp->arithrecursion--;
|
||||
if(sh.arithrecursion>0)
|
||||
sh.arithrecursion--;
|
||||
if(type==0 && !num)
|
||||
num = 0;
|
||||
return(num);
|
||||
|
@ -516,7 +513,7 @@ static int gettok(register struct vars *vp)
|
|||
vp->nextchr--;
|
||||
break;
|
||||
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;
|
||||
goto keep;
|
||||
|
@ -579,7 +576,6 @@ static int expr(register struct vars *vp,register int precedence)
|
|||
lvalue.value = 0;
|
||||
lvalue.nargs = 0;
|
||||
lvalue.fun = 0;
|
||||
lvalue.shp = vp->shp;
|
||||
again:
|
||||
op = gettok(vp);
|
||||
c = 2*MAXPREC+1;
|
||||
|
@ -897,13 +893,12 @@ again:
|
|||
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;
|
||||
register Arith_t *ep;
|
||||
int offset;
|
||||
memset((void*)&cur,0,sizeof(cur));
|
||||
cur.shp = shp;
|
||||
cur.expr = cur.nextchr = string;
|
||||
cur.convert = fun;
|
||||
cur.emode = emode;
|
||||
|
@ -925,7 +920,6 @@ Arith_t *arith_compile(Shell_t *shp,const char *string,char **last,Sfdouble_t(*f
|
|||
stakputc(0);
|
||||
offset = staktell();
|
||||
ep = (Arith_t*)stakfreeze(0);
|
||||
ep->shp = shp;
|
||||
ep->expr = string;
|
||||
ep->elen = strlen(string);
|
||||
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
|
||||
* 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;
|
||||
Sfdouble_t d;
|
||||
|
@ -959,7 +953,7 @@ Sfdouble_t strval(Shell_t *shp,const char *s,char **end,Sfdouble_t(*conv)(const
|
|||
int offset;
|
||||
if(offset=staktell())
|
||||
sp = stakfreeze(1);
|
||||
ep = arith_compile(shp,s,end,conv,emode);
|
||||
ep = arith_compile(s,end,convert,emode);
|
||||
ep->emode = emode;
|
||||
d = arith_exec(ep);
|
||||
stakset(sp?sp:(char*)ep,offset);
|
||||
|
|
|
@ -40,11 +40,6 @@
|
|||
# define iswprint(c) (((c)&~0377) || isprint(c))
|
||||
#endif
|
||||
|
||||
#ifndef isxdigit
|
||||
# define isxdigit(c) ((c)>='0'&&(c)<='9'||(c)>='a'&&(c)<='f'||(c)>='A'&&(c)<='F')
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Table lookup routine
|
||||
* <table> is searched for string <sp> and corresponding value is returned
|
||||
|
|
|
@ -69,7 +69,6 @@ struct Link
|
|||
*/
|
||||
static struct subshell
|
||||
{
|
||||
Shell_t *shp; /* shell interpreter */
|
||||
struct subshell *prev; /* previous subshell data */
|
||||
struct subshell *pipe; /* subshell where output goes to pipe on fork */
|
||||
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
|
||||
*/
|
||||
void sh_subtmpfile(Shell_t *shp)
|
||||
void sh_subtmpfile(void)
|
||||
{
|
||||
if(sfset(sfstdout,0,0)&SF_STRING)
|
||||
{
|
||||
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;
|
||||
/* save file descriptor 1 if open */
|
||||
if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0)
|
||||
{
|
||||
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
||||
shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
|
||||
sh.fdstatus[fd] = sh.fdstatus[1]|IOCLEX;
|
||||
close(1);
|
||||
}
|
||||
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");
|
||||
UNREACHABLE();
|
||||
}
|
||||
shp->fdstatus[fd] = IOREAD|IOWRITE;
|
||||
sh.fdstatus[fd] = IOREAD|IOWRITE;
|
||||
sfsync(sfstdout);
|
||||
if(fd==1)
|
||||
fcntl(1,F_SETFD,0);
|
||||
else
|
||||
{
|
||||
sfsetfd(sfstdout,1);
|
||||
shp->fdstatus[1] = shp->fdstatus[fd];
|
||||
shp->fdstatus[fd] = IOCLOSE;
|
||||
sh.fdstatus[1] = sh.fdstatus[fd];
|
||||
sh.fdstatus[fd] = IOCLOSE;
|
||||
}
|
||||
sh_iostream(shp,1);
|
||||
sh_iostream(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)
|
||||
pp->olist->strm = 0;
|
||||
}
|
||||
|
@ -167,27 +166,26 @@ void sh_subtmpfile(Shell_t *shp)
|
|||
void sh_subfork(void)
|
||||
{
|
||||
register struct subshell *sp = subshell_data;
|
||||
Shell_t *shp = sp->shp;
|
||||
unsigned int curenv = shp->curenv;
|
||||
char comsub = shp->comsub;
|
||||
unsigned int curenv = sh.curenv;
|
||||
char comsub = sh.comsub;
|
||||
pid_t pid;
|
||||
char *trap = shp->st.trapcom[0];
|
||||
char *trap = sh.st.trapcom[0];
|
||||
if(trap)
|
||||
trap = sh_strdup(trap);
|
||||
/* see whether inside $(...) */
|
||||
if(sp->pipe)
|
||||
sh_subtmpfile(shp);
|
||||
shp->curenv = 0;
|
||||
shp->savesig = -1;
|
||||
if(pid = sh_fork(shp,FSHOWME,NIL(int*)))
|
||||
sh_subtmpfile();
|
||||
sh.curenv = 0;
|
||||
sh.savesig = -1;
|
||||
if(pid = sh_fork(FSHOWME,NIL(int*)))
|
||||
{
|
||||
shp->curenv = curenv;
|
||||
sh.curenv = curenv;
|
||||
/* this is the parent part of the fork */
|
||||
if(sp->subpid==0)
|
||||
sp->subpid = pid;
|
||||
if(trap)
|
||||
free((void*)trap);
|
||||
siglongjmp(*shp->jmplist,SH_JMPSUB);
|
||||
siglongjmp(*sh.jmplist,SH_JMPSUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -205,13 +203,13 @@ void sh_subfork(void)
|
|||
rp->rand_last = -2;
|
||||
}
|
||||
subshell_data = 0;
|
||||
shp->subshell = 0;
|
||||
shp->comsub = 0;
|
||||
sh.subshell = 0;
|
||||
sh.comsub = 0;
|
||||
sp->subpid=0;
|
||||
shp->st.trapcom[0] = (comsub==2 ? NIL(char*) : trap);
|
||||
shp->savesig = 0;
|
||||
sh.st.trapcom[0] = (comsub==2 ? NIL(char*) : trap);
|
||||
sh.savesig = 0;
|
||||
/* 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 struct Link *lp;
|
||||
struct subshell *sp = subshell_data;
|
||||
Shell_t *shp = sp->shp;
|
||||
Dt_t *dp= shp->var_tree;
|
||||
Dt_t *dp= sh.var_tree;
|
||||
Namval_t *mpnext;
|
||||
Namarr_t *ap;
|
||||
unsigned int save;
|
||||
|
@ -288,7 +285,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
|
|||
return(np);
|
||||
if((ap=nv_arrayptr(np)) && (mp=nv_opensub(np)))
|
||||
{
|
||||
shp->last_root = ap->table;
|
||||
sh.last_root = ap->table;
|
||||
sh_assignok(mp,add);
|
||||
if(!add || array_assoc(ap))
|
||||
return(np);
|
||||
|
@ -305,7 +302,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
|
|||
if(!add && nv_isvtree(np))
|
||||
{
|
||||
Namval_t fake;
|
||||
Dt_t *walk, *root=shp->var_tree;
|
||||
Dt_t *walk, *root=sh.var_tree;
|
||||
char *name = nv_name(np);
|
||||
size_t len = strlen(name);
|
||||
fake.nvname = name;
|
||||
|
@ -327,13 +324,13 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
|
|||
mp = (Namval_t*)&lp->dict;
|
||||
lp->next = subshell_data->svar;
|
||||
subshell_data->svar = lp;
|
||||
save = shp->subshell;
|
||||
shp->subshell = 0;
|
||||
save = sh.subshell;
|
||||
sh.subshell = 0;
|
||||
mp->nvname = np->nvname;
|
||||
if(nv_isattr(np,NV_NOFREE))
|
||||
nv_onattr(mp,NV_IDENT);
|
||||
nv_clone(np,mp,(add?(nv_isnull(np)?0:NV_NOFREE)|NV_ARRAY:NV_MOVE));
|
||||
shp->subshell = save;
|
||||
sh.subshell = save;
|
||||
return(np);
|
||||
}
|
||||
|
||||
|
@ -388,12 +385,12 @@ static void nv_restore(struct subshell *sp)
|
|||
if(nv_isattr(mp,NV_EXPORT))
|
||||
{
|
||||
char *name = nv_name(mp);
|
||||
sh_envput(sp->shp->env,mp);
|
||||
sh_envput(sh.env,mp);
|
||||
if(*name=='_' && strcmp(name,"_AST_FEATURES")==0)
|
||||
astconf(NiL, NiL, NiL);
|
||||
}
|
||||
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);
|
||||
skip:
|
||||
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.
|
||||
*/
|
||||
|
||||
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;
|
||||
register struct subshell *sp = &sub_data;
|
||||
int jmpval,isig,nsig=0,fatalerror=0,saveerrno=0;
|
||||
unsigned int savecurenv = shp->curenv;
|
||||
unsigned int savecurenv = sh.curenv;
|
||||
int savejobpgid = job.curpgid;
|
||||
int *saveexitval = job.exitval;
|
||||
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;
|
||||
int argcnt;
|
||||
memset((char*)sp, 0, sizeof(*sp));
|
||||
sfsync(shp->outpool);
|
||||
sh_sigcheck(shp);
|
||||
shp->savesig = -1;
|
||||
if(argsav = sh_arguse(shp))
|
||||
sfsync(sh.outpool);
|
||||
sh_sigcheck();
|
||||
sh.savesig = -1;
|
||||
if(argsav = sh_arguse())
|
||||
argcnt = argsav->dolrefcnt;
|
||||
if(shp->curenv==0)
|
||||
if(sh.curenv==0)
|
||||
{
|
||||
subshell_data=0;
|
||||
subenv = 0;
|
||||
}
|
||||
shp->curenv = ++subenv;
|
||||
savst = shp->st;
|
||||
sh.curenv = ++subenv;
|
||||
savst = sh.st;
|
||||
sh_pushcontext(&sh,&checkpoint,SH_JMPSUB);
|
||||
shp->subshell++; /* increase level of virtual subshells */
|
||||
shgd->realsubshell++; /* increase ${.sh.subshell} */
|
||||
sh.subshell++; /* increase level of virtual subshells */
|
||||
sh.realsubshell++; /* increase ${.sh.subshell} */
|
||||
sp->prev = subshell_data;
|
||||
sp->shp = shp;
|
||||
sp->sig = 0;
|
||||
subshell_data = sp;
|
||||
sp->options = shp->options;
|
||||
sp->options = sh.options;
|
||||
sp->jobs = job_subsave();
|
||||
sp->subdup = shp->subdup;
|
||||
shp->subdup = 0;
|
||||
sp->subdup = sh.subdup;
|
||||
sh.subdup = 0;
|
||||
/* make sure initialization has occurred */
|
||||
if(!shp->pathlist)
|
||||
if(!sh.pathlist)
|
||||
{
|
||||
shp->pathinit = 1;
|
||||
path_get(shp,e_dot);
|
||||
shp->pathinit = 0;
|
||||
sh.pathinit = 1;
|
||||
path_get(e_dot);
|
||||
sh.pathinit = 0;
|
||||
}
|
||||
if(!shp->pwd)
|
||||
path_pwd(shp,0);
|
||||
sp->bckpid = shp->bckpid;
|
||||
if(!sh.pwd)
|
||||
path_pwd();
|
||||
sp->bckpid = sh.bckpid;
|
||||
if(comsub)
|
||||
sh_stats(STAT_COMSUB);
|
||||
else
|
||||
job.curpgid = 0;
|
||||
sp->subshare = shp->subshare;
|
||||
sp->comsub = shp->comsub;
|
||||
shp->subshare = comsub==2;
|
||||
if(!shp->subshare)
|
||||
sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist);
|
||||
sp->subshare = sh.subshare;
|
||||
sp->comsub = sh.comsub;
|
||||
sh.subshare = comsub==2;
|
||||
if(!sh.subshare)
|
||||
sp->pathlist = path_dup((Pathcomp_t*)sh.pathlist);
|
||||
if(comsub)
|
||||
shp->comsub = comsub;
|
||||
if(!shp->subshare)
|
||||
sh.comsub = comsub;
|
||||
if(!sh.subshare)
|
||||
{
|
||||
struct subshell *xp;
|
||||
#if _lib_fchdir
|
||||
sp->pwdfd = -1;
|
||||
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;
|
||||
break;
|
||||
|
@ -573,36 +569,36 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
|
|||
}
|
||||
}
|
||||
#endif /* _lib_fchdir */
|
||||
sp->pwd = (shp->pwd?sh_strdup(shp->pwd):0);
|
||||
sp->mask = shp->mask;
|
||||
sp->pwd = (sh.pwd?sh_strdup(sh.pwd):0);
|
||||
sp->mask = sh.mask;
|
||||
sh_stats(STAT_SUBSHELL);
|
||||
/* save trap table */
|
||||
shp->st.otrapcom = 0;
|
||||
shp->st.otrap = savst.trap;
|
||||
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
|
||||
sh.st.otrapcom = 0;
|
||||
sh.st.otrap = savst.trap;
|
||||
if((nsig=sh.st.trapmax)>0 || sh.st.trapcom[0])
|
||||
{
|
||||
savsig = sh_malloc(nsig * sizeof(char*));
|
||||
/*
|
||||
* the data is, usually, modified in code like:
|
||||
* 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)
|
||||
{
|
||||
if(shp->st.trapcom[isig] == Empty)
|
||||
if(sh.st.trapcom[isig] == Empty)
|
||||
savsig[isig] = Empty;
|
||||
else if(shp->st.trapcom[isig])
|
||||
savsig[isig] = sh_strdup(shp->st.trapcom[isig]);
|
||||
else if(sh.st.trapcom[isig])
|
||||
savsig[isig] = sh_strdup(sh.st.trapcom[isig]);
|
||||
else
|
||||
savsig[isig] = NIL(char*);
|
||||
}
|
||||
/* this is needed for var=$(trap) */
|
||||
shp->st.otrapcom = (char**)savsig;
|
||||
sh.st.otrapcom = (char**)savsig;
|
||||
}
|
||||
sp->cpid = shp->cpid;
|
||||
sp->coutpipe = shp->coutpipe;
|
||||
sp->cpipe = shp->cpipe[1];
|
||||
shp->cpid = 0;
|
||||
sp->cpid = sh.cpid;
|
||||
sp->coutpipe = sh.coutpipe;
|
||||
sp->cpipe = sh.cpipe[1];
|
||||
sh.cpid = 0;
|
||||
sh_sigreset(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)
|
||||
{
|
||||
/* disable job control */
|
||||
shp->spid = 0;
|
||||
sh.spid = 0;
|
||||
sp->jobcontrol = job.jobcontrol;
|
||||
sp->monitor = (sh_isstate(SH_MONITOR)!=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;
|
||||
/* save sfstdout and status */
|
||||
sp->saveout = sfswap(sfstdout,NIL(Sfio_t*));
|
||||
sp->fdstatus = shp->fdstatus[1];
|
||||
sp->fdstatus = sh.fdstatus[1];
|
||||
sp->tmpfd = -1;
|
||||
sp->pipefd = -1;
|
||||
/* 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);
|
||||
sfset(sfstdout,SF_READ,0);
|
||||
shp->fdstatus[1] = IOWRITE;
|
||||
sh.fdstatus[1] = IOWRITE;
|
||||
if(!(sp->nofork = sh_state(SH_NOFORK)))
|
||||
sh_onstate(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;
|
||||
flags &= ~sh_state(SH_NOFORK);
|
||||
}
|
||||
if(shp->savesig < 0)
|
||||
if(sh.savesig < 0)
|
||||
{
|
||||
shp->savesig = 0;
|
||||
sh.savesig = 0;
|
||||
#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. */
|
||||
#else
|
||||
if(!shp->subshare)
|
||||
if(!sh.subshare)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 */
|
||||
char *trap=shp->st.trapcom[0];
|
||||
shp->st.trapcom[0] = 0; /* prevent recursion */
|
||||
char *trap=sh.st.trapcom[0];
|
||||
sh.st.trapcom[0] = 0; /* prevent recursion */
|
||||
sh_trap(trap,0);
|
||||
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;
|
||||
sh_popcontext(&sh,&checkpoint);
|
||||
if(jmpval==SH_JMPSCRIPT)
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
shp->exitval &= SH_EXITMASK;
|
||||
sh_done(shp,0);
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
sh.exitval &= SH_EXITMASK;
|
||||
sh_done(0);
|
||||
}
|
||||
if(!shp->savesig)
|
||||
shp->savesig = -1;
|
||||
if(!sh.savesig)
|
||||
sh.savesig = -1;
|
||||
nv_restore(sp);
|
||||
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)
|
||||
{
|
||||
/* sftmp() file has been returned into pipe */
|
||||
iop = sh_iostream(shp,sp->pipefd);
|
||||
iop = sh_iostream(sp->pipefd);
|
||||
sfclose(sfstdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(shp->spid)
|
||||
if(sh.spid)
|
||||
{
|
||||
int e = shp->exitval;
|
||||
job_wait(shp->spid);
|
||||
shp->exitval = e;
|
||||
if(shp->pipepid==shp->spid)
|
||||
shp->spid = 0;
|
||||
shp->pipepid = 0;
|
||||
int e = sh.exitval;
|
||||
job_wait(sh.spid);
|
||||
sh.exitval = e;
|
||||
if(sh.pipepid==sh.spid)
|
||||
sh.spid = 0;
|
||||
sh.pipepid = 0;
|
||||
}
|
||||
/* move tmp file to iop and restore sfstdout */
|
||||
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)
|
||||
{
|
||||
int fd = sfsetfd(iop,sh_iosafefd(shp,3));
|
||||
int fd = sfsetfd(iop,sh_iosafefd(3));
|
||||
if(fd<0)
|
||||
{
|
||||
shp->toomany = 1;
|
||||
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
|
||||
sh.toomany = 1;
|
||||
((struct checkpt*)sh.jmplist)->mode = SH_JMPERREXIT;
|
||||
errormsg(SH_DICT,ERROR_system(1),e_toomany);
|
||||
UNREACHABLE();
|
||||
}
|
||||
if(fd >= shp->gd->lim.open_max)
|
||||
sh_iovalidfd(shp,fd);
|
||||
shp->sftable[fd] = iop;
|
||||
if(fd >= sh.lim.open_max)
|
||||
sh_iovalidfd(fd);
|
||||
sh.sftable[fd] = iop;
|
||||
fcntl(fd,F_SETFD,FD_CLOEXEC);
|
||||
shp->fdstatus[fd] = (shp->fdstatus[1]|IOCLEX);
|
||||
shp->fdstatus[1] = IOCLOSE;
|
||||
sh.fdstatus[fd] = (sh.fdstatus[1]|IOCLEX);
|
||||
sh.fdstatus[1] = IOCLOSE;
|
||||
}
|
||||
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);
|
||||
}
|
||||
shp->fdstatus[1] = sp->fdstatus;
|
||||
sh.fdstatus[1] = sp->fdstatus;
|
||||
}
|
||||
if(!shp->subshare)
|
||||
if(!sh.subshare)
|
||||
{
|
||||
path_delete((Pathcomp_t*)shp->pathlist);
|
||||
shp->pathlist = (void*)sp->pathlist;
|
||||
path_delete((Pathcomp_t*)sh.pathlist);
|
||||
sh.pathlist = (void*)sp->pathlist;
|
||||
}
|
||||
job_subrestore(sp->jobs);
|
||||
shp->curenv = shp->jobenv = savecurenv;
|
||||
sh.curenv = sh.jobenv = savecurenv;
|
||||
job.curpgid = savejobpgid;
|
||||
job.exitval = saveexitval;
|
||||
shp->bckpid = sp->bckpid;
|
||||
if(!shp->subshare) /* restore environment if saved */
|
||||
sh.bckpid = sp->bckpid;
|
||||
if(!sh.subshare) /* restore environment if saved */
|
||||
{
|
||||
int n;
|
||||
struct rand *rp;
|
||||
shp->options = sp->options;
|
||||
sh.options = sp->options;
|
||||
/* Clean up subshell hash table. */
|
||||
if(sp->strack)
|
||||
{
|
||||
Namval_t *np, *next_np;
|
||||
/* 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. */
|
||||
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;
|
||||
/* 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. */
|
||||
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;
|
||||
}
|
||||
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. */
|
||||
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);
|
||||
}
|
||||
n = shp->st.trapmax-savst.trapmax;
|
||||
n = sh.st.trapmax-savst.trapmax;
|
||||
sh_sigreset(1);
|
||||
if(n>0)
|
||||
memset(&shp->st.trapcom[savst.trapmax],0,n*sizeof(char*));
|
||||
shp->st = savst;
|
||||
shp->st.otrap = 0;
|
||||
memset(&sh.st.trapcom[savst.trapmax],0,n*sizeof(char*));
|
||||
sh.st = savst;
|
||||
sh.st.otrap = 0;
|
||||
if(nsig)
|
||||
{
|
||||
for (isig = 0; isig < nsig; ++isig)
|
||||
if (shp->st.trapcom[isig] && shp->st.trapcom[isig]!=Empty)
|
||||
free(shp->st.trapcom[isig]);
|
||||
memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*));
|
||||
if (sh.st.trapcom[isig] && sh.st.trapcom[isig]!=Empty)
|
||||
free(sh.st.trapcom[isig]);
|
||||
memcpy((char*)&sh.st.trapcom[0],savsig,nsig*sizeof(char*));
|
||||
free((void*)savsig);
|
||||
}
|
||||
shp->options = sp->options;
|
||||
sh.options = sp->options;
|
||||
/* restore the present working directory */
|
||||
#if _lib_fchdir
|
||||
if(sp->pwdfd > 0 && fchdir(sp->pwdfd) < 0)
|
||||
#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 */
|
||||
{
|
||||
saveerrno = errno;
|
||||
fatalerror = 2;
|
||||
}
|
||||
else if(sp->pwd && strcmp(sp->pwd,shp->pwd))
|
||||
path_newdir(shp,shp->pathlist);
|
||||
if(shp->pwd)
|
||||
free((void*)shp->pwd);
|
||||
shp->pwd = sp->pwd;
|
||||
else if(sp->pwd && strcmp(sp->pwd,sh.pwd))
|
||||
path_newdir(sh.pathlist);
|
||||
if(sh.pwd)
|
||||
free((void*)sh.pwd);
|
||||
sh.pwd = sp->pwd;
|
||||
#if _lib_fchdir
|
||||
if(sp->pwdclose)
|
||||
close(sp->pwdfd);
|
||||
#endif /* _lib_fchdir */
|
||||
if(sp->mask!=shp->mask)
|
||||
umask(shp->mask=sp->mask);
|
||||
if(shp->coutpipe!=sp->coutpipe)
|
||||
if(sp->mask!=sh.mask)
|
||||
umask(sh.mask=sp->mask);
|
||||
if(sh.coutpipe!=sp->coutpipe)
|
||||
{
|
||||
sh_close(shp->coutpipe);
|
||||
sh_close(shp->cpipe[1]);
|
||||
sh_close(sh.coutpipe);
|
||||
sh_close(sh.cpipe[1]);
|
||||
}
|
||||
shp->cpid = sp->cpid;
|
||||
shp->cpipe[1] = sp->cpipe;
|
||||
shp->coutpipe = sp->coutpipe;
|
||||
sh.cpid = sp->cpid;
|
||||
sh.cpipe[1] = sp->cpipe;
|
||||
sh.coutpipe = sp->coutpipe;
|
||||
/* restore $RANDOM seed and state */
|
||||
rp = (struct rand*)RANDNOD->nvfun;
|
||||
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. */
|
||||
sh.exitval &= SH_EXITMASK;
|
||||
}
|
||||
shp->subshare = sp->subshare;
|
||||
shp->subdup = sp->subdup;
|
||||
sh.subshare = sp->subshare;
|
||||
sh.subdup = sp->subdup;
|
||||
sh.subshell--; /* decrease level of virtual subshells */
|
||||
shgd->realsubshell--; /* decrease ${.sh.subshell} */
|
||||
sh.realsubshell--; /* decrease ${.sh.subshell} */
|
||||
subshell_data = sp->prev;
|
||||
sh_popcontext(&sh,&checkpoint);
|
||||
if(!argsav || argsav->dolrefcnt==argcnt)
|
||||
sh_argfree(shp,argsav,0);
|
||||
sh_argfree(argsav,0);
|
||||
if(sh.topfd != checkpoint.topfd)
|
||||
sh_iorestore(&sh,checkpoint.topfd|IOSUBSHELL,jmpval);
|
||||
sh_iorestore(checkpoint.topfd|IOSUBSHELL,jmpval);
|
||||
if(sp->sig)
|
||||
{
|
||||
if(sp->prev)
|
||||
sp->prev->sig = sp->sig;
|
||||
else
|
||||
{
|
||||
kill(shgd->current_pid,sp->sig);
|
||||
sh_chktrap(shp);
|
||||
kill(sh.current_pid,sp->sig);
|
||||
sh_chktrap();
|
||||
}
|
||||
}
|
||||
sh_sigcheck(shp);
|
||||
shp->trapnote = 0;
|
||||
nsig = shp->savesig;
|
||||
shp->savesig = 0;
|
||||
sh_sigcheck();
|
||||
sh.trapnote = 0;
|
||||
nsig = sh.savesig;
|
||||
sh.savesig = 0;
|
||||
if(nsig>0)
|
||||
kill(shgd->current_pid,nsig);
|
||||
kill(sh.current_pid,nsig);
|
||||
if(sp->subpid)
|
||||
{
|
||||
job_wait(sp->subpid);
|
||||
if(comsub)
|
||||
sh_iounpipe(shp);
|
||||
sh_iounpipe();
|
||||
}
|
||||
shp->comsub = sp->comsub;
|
||||
sh.comsub = sp->comsub;
|
||||
if(comsub && iop && sp->pipefd<0)
|
||||
sfseek(iop,(off_t)0,SEEK_SET);
|
||||
if(shp->trapnote)
|
||||
sh_chktrap(shp);
|
||||
if(shp->exitval > SH_EXITSIG)
|
||||
if(sh.trapnote)
|
||||
sh_chktrap();
|
||||
if(sh.exitval > SH_EXITSIG)
|
||||
{
|
||||
int sig = shp->exitval&SH_EXITMASK;
|
||||
int sig = sh.exitval&SH_EXITMASK;
|
||||
if(sig==SIGINT || sig== SIGQUIT)
|
||||
kill(shgd->current_pid,sig);
|
||||
kill(sh.current_pid,sig);
|
||||
}
|
||||
if(fatalerror)
|
||||
{
|
||||
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
|
||||
((struct checkpt*)sh.jmplist)->mode = SH_JMPERREXIT;
|
||||
switch(fatalerror)
|
||||
{
|
||||
case 1:
|
||||
shp->toomany = 1;
|
||||
sh.toomany = 1;
|
||||
errno = saveerrno;
|
||||
errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,e_redirect);
|
||||
UNREACHABLE();
|
||||
case 2:
|
||||
/* reinit PWD as it will be wrong */
|
||||
if(shp->pwd)
|
||||
free((void*)shp->pwd);
|
||||
shp->pwd = NIL(const char*);
|
||||
path_pwd(shp,0);
|
||||
if(sh.pwd)
|
||||
free((void*)sh.pwd);
|
||||
sh.pwd = NIL(const char*);
|
||||
path_pwd();
|
||||
errno = saveerrno;
|
||||
errormsg(SH_DICT,ERROR_SYSTEM|ERROR_PANIC,"Failed to restore PWD upon exiting subshell");
|
||||
UNREACHABLE();
|
||||
|
@ -951,11 +947,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
|
|||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if(shp->ignsig)
|
||||
kill(shgd->current_pid,shp->ignsig);
|
||||
if(jmpval==SH_JMPSUB && shp->lastsig)
|
||||
kill(shgd->current_pid,shp->lastsig);
|
||||
if(jmpval && shp->toomany)
|
||||
siglongjmp(*shp->jmplist,jmpval);
|
||||
if(sh.ignsig)
|
||||
kill(sh.current_pid,sh.ignsig);
|
||||
if(jmpval==SH_JMPSUB && sh.lastsig)
|
||||
kill(sh.current_pid,sh.lastsig);
|
||||
if(jmpval && sh.toomany)
|
||||
siglongjmp(*sh.jmplist,jmpval);
|
||||
return(iop);
|
||||
}
|
||||
|
|
|
@ -489,7 +489,7 @@ static void setids(int mode,uid_t owner,gid_t group)
|
|||
static void maketemp(char *template)
|
||||
{
|
||||
register char *cp = template;
|
||||
register pid_t n = shgd->current_pid;
|
||||
register pid_t n = getpid();
|
||||
/* skip to end of string */
|
||||
while(*++cp);
|
||||
/* convert process id to string */
|
||||
|
|
|
@ -97,7 +97,7 @@ static void sigalrm(int sig)
|
|||
if(time_state&SIGALRM_CALL)
|
||||
time_state &= ~SIGALRM_CALL;
|
||||
else if(alarm(0))
|
||||
kill(shgd->current_pid,SIGALRM|SH_TRAP);
|
||||
kill(sh.current_pid,SIGALRM|SH_TRAP);
|
||||
if(time_state)
|
||||
{
|
||||
if(time_state&IN_ADDTIMEOUT)
|
||||
|
|
|
@ -32,29 +32,27 @@
|
|||
#include "io.h"
|
||||
#include <ccode.h>
|
||||
|
||||
static struct dolnod *r_comlist(Shell_t*);
|
||||
static struct argnod *r_arg(Shell_t*);
|
||||
static struct ionod *r_redirect(Shell_t*);
|
||||
static struct regnod *r_switch(Shell_t*);
|
||||
static Shnode_t *r_tree(Shell_t*);
|
||||
static char *r_string(Stk_t*);
|
||||
static void r_comarg(Shell_t*,struct comnod*);
|
||||
static struct dolnod *r_comlist(void);
|
||||
static struct argnod *r_arg(void);
|
||||
static struct ionod *r_redirect(void);
|
||||
static struct regnod *r_switch(void);
|
||||
static Shnode_t *r_tree(void);
|
||||
static char *r_string(void);
|
||||
static void r_comarg(struct comnod*);
|
||||
|
||||
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;
|
||||
t = r_tree(shp);
|
||||
return(t);
|
||||
return(r_tree());
|
||||
}
|
||||
/*
|
||||
* read in a shell tree
|
||||
*/
|
||||
static Shnode_t *r_tree(Shell_t *shp)
|
||||
static Shnode_t *r_tree(void)
|
||||
{
|
||||
long l = sfgetl(infile);
|
||||
register int type;
|
||||
|
@ -66,107 +64,107 @@ static Shnode_t *r_tree(Shell_t *shp)
|
|||
{
|
||||
case TTIME:
|
||||
case TPAR:
|
||||
t = getnode(shp->stk,parnod);
|
||||
t->par.partre = r_tree(shp);
|
||||
t = getnode(parnod);
|
||||
t->par.partre = r_tree();
|
||||
break;
|
||||
case TCOM:
|
||||
t = getnode(shp->stk,comnod);
|
||||
t = getnode(comnod);
|
||||
t->tre.tretyp = type;
|
||||
r_comarg(shp,(struct comnod*)t);
|
||||
r_comarg((struct comnod*)t);
|
||||
break;
|
||||
case TSETIO:
|
||||
case TFORK:
|
||||
t = getnode(shp->stk,forknod);
|
||||
t = getnode(forknod);
|
||||
t->fork.forkline = sfgetu(infile);
|
||||
t->fork.forktre = r_tree(shp);
|
||||
t->fork.forkio = r_redirect(shp);
|
||||
t->fork.forktre = r_tree();
|
||||
t->fork.forkio = r_redirect();
|
||||
break;
|
||||
case TIF:
|
||||
t = getnode(shp->stk,ifnod);
|
||||
t->if_.iftre = r_tree(shp);
|
||||
t->if_.thtre = r_tree(shp);
|
||||
t->if_.eltre = r_tree(shp);
|
||||
t = getnode(ifnod);
|
||||
t->if_.iftre = r_tree();
|
||||
t->if_.thtre = r_tree();
|
||||
t->if_.eltre = r_tree();
|
||||
break;
|
||||
case TWH:
|
||||
t = getnode(shp->stk,whnod);
|
||||
t->wh.whinc = (struct arithnod*)r_tree(shp);
|
||||
t->wh.whtre = r_tree(shp);
|
||||
t->wh.dotre = r_tree(shp);
|
||||
t = getnode(whnod);
|
||||
t->wh.whinc = (struct arithnod*)r_tree();
|
||||
t->wh.whtre = r_tree();
|
||||
t->wh.dotre = r_tree();
|
||||
break;
|
||||
case TLST:
|
||||
case TAND:
|
||||
case TORF:
|
||||
case TFIL:
|
||||
t = getnode(shp->stk,lstnod);
|
||||
t->lst.lstlef = r_tree(shp);
|
||||
t->lst.lstrit = r_tree(shp);
|
||||
t = getnode(lstnod);
|
||||
t->lst.lstlef = r_tree();
|
||||
t->lst.lstrit = r_tree();
|
||||
break;
|
||||
case TARITH:
|
||||
t = getnode(shp->stk,arithnod);
|
||||
t = getnode(arithnod);
|
||||
t->ar.arline = sfgetu(infile);
|
||||
t->ar.arexpr = r_arg(shp);
|
||||
t->ar.arexpr = r_arg();
|
||||
t->ar.arcomp = 0;
|
||||
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;
|
||||
case TFOR:
|
||||
t = getnode(shp->stk,fornod);
|
||||
t = getnode(fornod);
|
||||
t->for_.forline = 0;
|
||||
if(type&FLINENO)
|
||||
t->for_.forline = sfgetu(infile);
|
||||
t->for_.fortre = r_tree(shp);
|
||||
t->for_.fornam = r_string(shp->stk);
|
||||
t->for_.forlst = (struct comnod*)r_tree(shp);
|
||||
t->for_.fortre = r_tree();
|
||||
t->for_.fornam = r_string();
|
||||
t->for_.forlst = (struct comnod*)r_tree();
|
||||
break;
|
||||
case TSW:
|
||||
t = getnode(shp->stk,swnod);
|
||||
t = getnode(swnod);
|
||||
t->sw.swline = 0;
|
||||
if(type&FLINENO)
|
||||
t->sw.swline = sfgetu(infile);
|
||||
t->sw.swarg = r_arg(shp);
|
||||
t->sw.swarg = r_arg();
|
||||
if(type&COMSCAN)
|
||||
t->sw.swio = r_redirect(shp);
|
||||
t->sw.swio = r_redirect();
|
||||
else
|
||||
t->sw.swio = 0;
|
||||
t->sw.swlst = r_switch(shp);
|
||||
t->sw.swlst = r_switch();
|
||||
break;
|
||||
case TFUN:
|
||||
{
|
||||
Stak_t *savstak;
|
||||
struct slnod *slp;
|
||||
struct functnod *fp;
|
||||
t = getnode(shp->stk,functnod);
|
||||
t = getnode(functnod);
|
||||
t->funct.functloc = -1;
|
||||
t->funct.functline = sfgetu(infile);
|
||||
t->funct.functnam = r_string(shp->stk);
|
||||
t->funct.functnam = r_string();
|
||||
savstak = stakcreate(STAK_SMALL);
|
||||
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->slnext = shp->st.staklist;
|
||||
shp->st.staklist = 0;
|
||||
slp->slnext = sh.st.staklist;
|
||||
sh.st.staklist = 0;
|
||||
fp = (struct functnod*)(slp+1);
|
||||
memset(fp, 0, sizeof(*fp));
|
||||
fp->functtyp = TFUN|FAMP;
|
||||
if(shp->st.filename)
|
||||
fp->functnam = stkcopy(shp->stk,shp->st.filename);
|
||||
t->funct.functtre = r_tree(shp);
|
||||
if(sh.st.filename)
|
||||
fp->functnam = stkcopy(sh.stk,sh.st.filename);
|
||||
t->funct.functtre = r_tree();
|
||||
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->slchild = shp->st.staklist;
|
||||
slp->slchild = sh.st.staklist;
|
||||
break;
|
||||
}
|
||||
case TTST:
|
||||
t = getnode(shp->stk,tstnod);
|
||||
t = getnode(tstnod);
|
||||
t->tst.tstline = sfgetu(infile);
|
||||
if((type&TPAREN)==TPAREN)
|
||||
t->lst.lstlef = r_tree(shp);
|
||||
t->lst.lstlef = r_tree();
|
||||
else
|
||||
{
|
||||
t->lst.lstlef = (Shnode_t*)r_arg(shp);
|
||||
t->lst.lstlef = (Shnode_t*)r_arg();
|
||||
if((type&TBINARY))
|
||||
t->lst.lstrit = (Shnode_t*)r_arg(shp);
|
||||
t->lst.lstrit = (Shnode_t*)r_arg();
|
||||
}
|
||||
}
|
||||
if(t)
|
||||
|
@ -174,11 +172,11 @@ static Shnode_t *r_tree(Shell_t *shp)
|
|||
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 long l;
|
||||
Stk_t *stkp=shp->stk;
|
||||
Stk_t *stkp=sh.stk;
|
||||
while((l=sfgetu(infile))>0)
|
||||
{
|
||||
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 = (struct argnod*)stkfreeze(stkp,0);
|
||||
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)
|
||||
{
|
||||
struct fornod *fp = (struct fornod*)getnode(shp->stk,fornod);
|
||||
struct fornod *fp = (struct fornod*)getnode(fornod);
|
||||
fp->fortyp = sfgetu(infile);
|
||||
fp->fortre = r_tree(shp);
|
||||
fp->fortre = r_tree();
|
||||
fp->fornam = ap->argval+1;
|
||||
ap->argchn.ap = (struct argnod*)fp;
|
||||
}
|
||||
|
@ -212,37 +210,37 @@ static struct argnod *r_arg(Shell_t *shp)
|
|||
return(aptop);
|
||||
}
|
||||
|
||||
static struct ionod *r_redirect(Shell_t* shp)
|
||||
static struct ionod *r_redirect(void)
|
||||
{
|
||||
register long l;
|
||||
register struct ionod *iop=0, *iopold, *ioptop=0;
|
||||
while((l=sfgetl(infile))>=0)
|
||||
{
|
||||
iop = (struct ionod*)getnode(shp->stk,ionod);
|
||||
iop = (struct ionod*)getnode(ionod);
|
||||
if(!ioptop)
|
||||
ioptop = iop;
|
||||
else
|
||||
iopold->ionxt = iop;
|
||||
iop->iofile = l;
|
||||
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
|
||||
iop->ioname = r_string(shp->stk); /* file name, descriptor, etc. */
|
||||
if(iop->iodelim = r_string(shp->stk))
|
||||
iop->ioname = r_string(); /* file name, descriptor, etc. */
|
||||
if(iop->iodelim = r_string())
|
||||
{
|
||||
iop->iosize = sfgetl(infile);
|
||||
if(shp->heredocs)
|
||||
iop->iooffset = sfseek(shp->heredocs,(off_t)0,SEEK_END);
|
||||
if(sh.heredocs)
|
||||
iop->iooffset = sfseek(sh.heredocs,(off_t)0,SEEK_END);
|
||||
else
|
||||
{
|
||||
shp->heredocs = sftmp(512);
|
||||
sh.heredocs = sftmp(512);
|
||||
iop->iooffset = 0;
|
||||
}
|
||||
sfmove(infile,shp->heredocs, iop->iosize, -1);
|
||||
sfmove(infile,sh.heredocs, iop->iosize, -1);
|
||||
}
|
||||
iopold = iop;
|
||||
if(iop->iofile&IOVNM)
|
||||
iop->iovname = r_string(shp->stk);
|
||||
iop->iovname = r_string();
|
||||
else
|
||||
iop->iovname = 0;
|
||||
iop->iofile &= ~IOVNM;
|
||||
|
@ -252,30 +250,30 @@ static struct ionod *r_redirect(Shell_t* shp)
|
|||
return(ioptop);
|
||||
}
|
||||
|
||||
static void r_comarg(Shell_t *shp,struct comnod *com)
|
||||
static void r_comarg(struct comnod *com)
|
||||
{
|
||||
char *cmdname=0;
|
||||
com->comio = r_redirect(shp);
|
||||
com->comset = r_arg(shp);
|
||||
com->comio = r_redirect();
|
||||
com->comset = r_arg();
|
||||
com->comstate = 0;
|
||||
if(com->comtyp&COMSCAN)
|
||||
{
|
||||
com->comarg = r_arg(shp);
|
||||
com->comarg = r_arg();
|
||||
if(com->comarg->argflag==ARG_RAW)
|
||||
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];
|
||||
com->comline = sfgetu(infile);
|
||||
com->comnamq = 0;
|
||||
if(cmdname)
|
||||
{
|
||||
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,'.')))
|
||||
{
|
||||
*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 = '.';
|
||||
}
|
||||
}
|
||||
|
@ -283,36 +281,36 @@ static void r_comarg(Shell_t *shp,struct comnod *com)
|
|||
com->comnamp = 0;
|
||||
}
|
||||
|
||||
static struct dolnod *r_comlist(Shell_t *shp)
|
||||
static struct dolnod *r_comlist(void)
|
||||
{
|
||||
register struct dolnod *dol=0;
|
||||
register long l;
|
||||
register char **argv;
|
||||
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->dolbot = ARG_SPARE;
|
||||
argv = dol->dolval+ARG_SPARE;
|
||||
while(*argv++ = r_string(shp->stk));
|
||||
while(*argv++ = r_string());
|
||||
}
|
||||
return(dol);
|
||||
}
|
||||
|
||||
static struct regnod *r_switch(Shell_t *shp)
|
||||
static struct regnod *r_switch(void)
|
||||
{
|
||||
register long l;
|
||||
struct regnod *reg=0,*regold,*regtop=0;
|
||||
while((l=sfgetl(infile))>=0)
|
||||
{
|
||||
reg = (struct regnod*)getnode(shp->stk,regnod);
|
||||
reg = (struct regnod*)getnode(regnod);
|
||||
if(!regtop)
|
||||
regtop = reg;
|
||||
else
|
||||
regold->regnxt = reg;
|
||||
reg->regflag = l;
|
||||
reg->regptr = r_arg(shp);
|
||||
reg->regcom = r_tree(shp);
|
||||
reg->regptr = r_arg();
|
||||
reg->regcom = r_tree();
|
||||
regold = reg;
|
||||
}
|
||||
if(reg)
|
||||
|
@ -320,14 +318,14 @@ static struct regnod *r_switch(Shell_t *shp)
|
|||
return(regtop);
|
||||
}
|
||||
|
||||
static char *r_string(Stk_t *stkp)
|
||||
static char *r_string(void)
|
||||
{
|
||||
register Sfio_t *in = infile;
|
||||
register unsigned long l = sfgetu(in);
|
||||
register char *ptr;
|
||||
if(l == 0)
|
||||
return(NIL(char*));
|
||||
ptr = stkalloc(stkp,(unsigned)l);
|
||||
ptr = stkalloc(sh.stk,(unsigned)l);
|
||||
if(--l > 0)
|
||||
{
|
||||
if(sfread(in,ptr,(size_t)l)!=(size_t)l)
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
void *sh_waitnotify(int(*newevent)(int,long,int))
|
||||
{
|
||||
int (*old)(int,long,int);
|
||||
old = shgd->waitevent;
|
||||
shgd->waitevent = newevent;
|
||||
old = sh.waitevent;
|
||||
sh.waitevent = newevent;
|
||||
return((void*)old);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,7 +36,7 @@ unsigned int sh_isoption(int \fIoption\fP);
|
|||
unsigned int sh_onoption(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_run(int \fIargc\fP, char *\fIargv\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.
|
||||
The arguments \fIargc\fP and \fIargv\fP are the number
|
||||
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
|
||||
.B 3
|
||||
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 *\fIfun_tree\fP; \fR/* shell function 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 *\fItrack_tree\fP; \fR/* shell hash table */\fP
|
||||
Dt_t *\fIbltin_tree\fP; \fR/* shell built-in command dictionary */\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
|
||||
char *\fIinfile_name\fP; \fR/* path name 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
|
||||
.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.
|
||||
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
|
||||
All built-in commands to the shell are invoked with
|
||||
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
|
||||
will be appended to the history file as a command.
|
||||
.PP
|
||||
The \f3sh_parse()\fP function takes a pointer to the
|
||||
shell interpreter \fIshp\fP, a pointer to a string or file stream
|
||||
The \f3sh_parse()\fP function takes
|
||||
a pointer to a string or file stream
|
||||
\fIsp\fP, and compilation flags, and returns a pointer
|
||||
to a parse tree of the compiled stream. This pointer can
|
||||
be used in subsequent calls to \f3sh_trap()\fP.
|
||||
|
|
|
@ -46,11 +46,7 @@
|
|||
struct Shbltin_s;
|
||||
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*);
|
||||
#endif /* _SHTABLE_H */
|
||||
|
||||
struct Shbltin_s
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue