diff --git a/NEWS b/NEWS index 996c4f059d4c..925cba40a59b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,10 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2020-08-11: + +- Fixed an intermittent crash upon running a large number of subshells. + 2020-08-10: - A number of fixes have been applied to the printf formatting directives diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h index 0f7651975061..a0645944b185 100644 --- a/src/cmd/ksh93/include/defs.h +++ b/src/cmd/ksh93/include/defs.h @@ -167,8 +167,8 @@ struct shared Namval_t *prev_table; /* previous table used in nv_open */ \ Sfio_t *outpool; /* output stream pool */ \ long timeout; /* read timeout */ \ - short curenv; /* current subshell number */ \ - short jobenv; /* subshell number for jobs */ \ + unsigned int curenv; /* current subshell number */ \ + unsigned int jobenv; /* subshell number for jobs */ \ int infd; /* input file descriptor */ \ short nextprompt; /* next prompt is PS */ \ short poolfiles; \ diff --git a/src/cmd/ksh93/include/jobs.h b/src/cmd/ksh93/include/jobs.h index 77a4fc5c8810..fd780c6acb4a 100644 --- a/src/cmd/ksh93/include/jobs.h +++ b/src/cmd/ksh93/include/jobs.h @@ -68,7 +68,7 @@ struct process unsigned short p_exit; /* exit value or signal number */ unsigned short p_exitmin; /* minimum exit value for xargs */ unsigned short p_flag; /* flags - see below */ - int p_env; /* subshell environment number */ + unsigned int p_env; /* subshell environment number */ #ifdef JOBS off_t p_name; /* history file offset for command */ struct termios p_stty; /* terminal state for job */ diff --git a/src/cmd/ksh93/include/nval.h b/src/cmd/ksh93/include/nval.h index b29d1057a6be..b68a87bdf623 100644 --- a/src/cmd/ksh93/include/nval.h +++ b/src/cmd/ksh93/include/nval.h @@ -75,7 +75,7 @@ struct Namfun { const Namdisc_t *disc; char nofree; - unsigned char subshell; + unsigned int subshell; uint32_t dsize; Namfun_t *next; char *last; diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h index b0b8d7666cf0..2a3c5acdcb90 100644 --- a/src/cmd/ksh93/include/shell.h +++ b/src/cmd/ksh93/include/shell.h @@ -143,7 +143,7 @@ struct Shell_s int exitval; /* most recent exit value */ unsigned char trapnote; /* set when trap/signal is pending */ char shcomp; /* set when running shcomp */ - short subshell; /* set for virtual subshell */ + unsigned int subshell; /* set for virtual subshell */ #ifdef _SH_PRIVATE _SH_PRIVATE #endif /* _SH_PRIVATE */ diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 1167568b9567..25f8f335c0e2 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-08-10" +#define SH_RELEASE "93u+m 2020-08-11" diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 6d3c8e8b8d4d..014427eeec75 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -748,7 +748,8 @@ void sh_setmatch(Shell_t *shp,const char *v, int vsize, int nmatch, regoff_t mat { struct match *mp = &ip->SH_MATCH_init; Namval_t *np = nv_namptr(mp->node,0); - register int i,n,x, savesub=shp->subshell; + register int i,n,x; + unsigned int savesub = shp->subshell; Namarr_t *ap = nv_arrayptr(SH_MATCHNOD); shp->subshell = 0; #ifndef SHOPT_2DMATCH diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c index 3170276e0b9f..ecbbb4c5567d 100644 --- a/src/cmd/ksh93/sh/jobs.c +++ b/src/cmd/ksh93/sh/jobs.c @@ -1647,7 +1647,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=%d\n",__LINE__,getpid(),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__,getpid(),job.in_critical,pwtop->p_pid,pwtop->p_env); sfsync(sfstderr); #endif /* DEBUG */ pwtop = pw = job_byjid((int)pwtop->p_job); diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index e5ad878f501b..b785435bf02e 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -2716,6 +2716,7 @@ static char *sh_tilde(Shell_t *shp,register const char *string) register int c; register struct passwd *pw; register Namval_t *np=0; + unsigned int save; static Dt_t *logins_tree; if(*string++!='~') return(NIL(char*)); @@ -2771,10 +2772,10 @@ static char *sh_tilde(Shell_t *shp,register const char *string) logins_tree = dtopen(&_Nvdisc,Dtbag); if(np=nv_search(string,logins_tree,NV_ADD)) { - c = shp->subshell; + save = shp->subshell; shp->subshell = 0; nv_putval(np, pw->pw_dir,0); - shp->subshell = c; + shp->subshell = save; } return(pw->pw_dir); } diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c index 6c6c2dd60aa6..341b6c228840 100644 --- a/src/cmd/ksh93/sh/name.c +++ b/src/cmd/ksh93/sh/name.c @@ -2464,7 +2464,7 @@ static void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroo { if(nv_cover(nq)) { - int subshell = shp->subshell; + unsigned int subshell = shp->subshell; shp->subshell = 0; if(nv_isattr(nq, NV_INTEGER)) { diff --git a/src/cmd/ksh93/sh/nvtype.c b/src/cmd/ksh93/sh/nvtype.c index 851ca380d97a..e54755ca1f2b 100644 --- a/src/cmd/ksh93/sh/nvtype.c +++ b/src/cmd/ksh93/sh/nvtype.c @@ -1318,7 +1318,8 @@ int nv_settype(Namval_t* np, Namval_t *tp, int flags) char *val=0; Namarr_t *ap=0; Shell_t *shp = sh_getinterp(); - int nelem=0,subshell=shp->subshell; + int nelem = 0; + unsigned int subshell = shp->subshell; #if SHOPT_TYPEDEF Namval_t *tq; if(nv_type(np)==tp) diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c index 5b12f922e3ee..b839a92c7bd4 100644 --- a/src/cmd/ksh93/sh/subshell.c +++ b/src/cmd/ksh93/sh/subshell.c @@ -103,7 +103,7 @@ static struct subshell char pwdclose; } *subshell_data; -static int subenv; +static unsigned int subenv; /* @@ -176,7 +176,7 @@ void sh_subfork(void) { register struct subshell *sp = subshell_data; Shell_t *shp = sp->shp; - int curenv = shp->curenv; + unsigned int curenv = shp->curenv; pid_t pid; char *trap = shp->st.trapcom[0]; if(trap) @@ -251,7 +251,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add) Dt_t *dp= shp->var_tree; Namval_t *mpnext; Namarr_t *ap; - int save; + unsigned int save; /* don't bother to save if in a ${ subshare; } */ if(sp->subshare) return(np); @@ -456,7 +456,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub) struct subshell sub_data; register struct subshell *sp = &sub_data; int jmpval,nsig=0,duped=0; - int savecurenv = shp->curenv; + unsigned int savecurenv = shp->curenv; int savejobpgid = job.curpgid; int *saveexitval = job.exitval; char *savsig; diff --git a/src/cmd/ksh93/tests/subshell.sh b/src/cmd/ksh93/tests/subshell.sh index 46800169741d..eee9c2087ed2 100755 --- a/src/cmd/ksh93/tests/subshell.sh +++ b/src/cmd/ksh93/tests/subshell.sh @@ -529,7 +529,8 @@ err() { return $1; } ( err 12 ) & pid=$! : $( $date) wait $pid -[[ $? == 12 ]] || err_exit 'exit status from subshells not being preserved' +exit_status=$? +[[ $exit_status == 12 ]] || err_exit "exit status from subshells not being preserved (expected 12, got $exit_status)" if cat /dev/fd/3 3/dev/null 2>&1 || whence mkfifo > /dev/null then x="$(sed 's/^/Hello /' <(print "Fred" | sort))"