diff --git a/NEWS b/NEWS index add28c93b..8747205a7 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,25 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0 Any uppercase BUG_* names are modernish shell bug IDs. +2022-02-15: + +- A bug was fixed in fast filescan loops (like 'while , then ESC TAB). Experimental. SHOPT ESH=1 # emacs/gmacs edit mode -SHOPT FILESCAN=1 # fast file scan +SHOPT FILESCAN=1 # fast file scan: while 2 to be left open when invoking another program; .IP \[bu] disables the \fB&>\fR redirection shorthand; .IP \[bu] +disables fast filescan loops of type +\f3while\fP \f2inputredirection\^\fP \f3;do\fP \f2list\^\fP \f3;done\fP; +.IP \[bu] makes the \fB<>\fR redirection operator default to redirecting standard input if no file descriptor number precedes it; .IP \[bu] diff --git a/src/cmd/ksh93/sh/macro.c b/src/cmd/ksh93/sh/macro.c index 744269203..458ed8113 100644 --- a/src/cmd/ksh93/sh/macro.c +++ b/src/cmd/ksh93/sh/macro.c @@ -1156,8 +1156,13 @@ retry1: #if SHOPT_FILESCAN if(sh.cur_line) { - v = getdolarg(1,(int*)0); dolmax = MAX_ARGN; + v = getdolarg(1,&vsize); + if(c=='*' || !mp->quoted) + { + dolmax = 1; + vsize = -1; + } } else #endif /* SHOPT_FILESCAN */ @@ -1914,8 +1919,6 @@ retry2: #if SHOPT_FILESCAN if(sh.cur_line) { - if(dolmax==MAX_ARGN && isastchar(mode)) - break; if(!(v=getdolarg(dolg,&vsize))) { dolmax = dolg; diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index ec90cee5a..7d5c7c74d 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -835,13 +835,14 @@ static void unset_instance(Namval_t *nq, Namval_t *node, struct Namref *nr,long #if SHOPT_FILESCAN static Sfio_t *openstream(struct ionod *iop, int *save) { - int savein, fd = sh_redirect(iop,3); + int err = errno, savein, fd = sh_redirect(iop,3); Sfio_t *sp; savein = dup(0); if(fd==0) fd = savein; sp = sfnew(NULL,NULL,SF_UNBOUND,fd,SF_READ); - close(0); + while(close(0)<0 && errno==EINTR) + errno = err; open(e_devnull,O_RDONLY); sh.offsets[0] = -1; sh.offsets[1] = 0; @@ -2242,11 +2243,17 @@ int sh_exec(register const Shnode_t *t, int flags) goto endwhile; #endif /* SHOPT_OPTIMIZE */ #if SHOPT_FILESCAN - if(type==TWH && tt->tre.tretyp==TCOM && !tt->com.comarg && tt->com.comio) + /* Recognize filescan loop for a lone input redirection following 'while' */ + if(type==TWH /* 'while' (not 'until') */ + && tt->tre.tretyp==TCOM /* one simple command follows 'while'... */ + && !tt->com.comarg /* ...with no command name or arguments... */ + && !tt->com.comset /* ...and no variable assignments list... */ + && tt->com.comio /* ...and one I/O redirection... */ + && !tt->com.comio->ionxt /* ...but not more than one... */ + && !(tt->com.comio->iofile & (IOPUT|IOAPP)) /* ...and not > or >> */ + && !sh_isoption(SH_POSIX)) /* not in POSIX compilance mode */ { iop = openstream(tt->com.comio,&savein); - if(tt->com.comset) - nv_setlist(tt->com.comset,NV_IDENT|NV_ASSIGN,0); } #endif /* SHOPT_FILESCAN */ sh.st.loopcnt++; @@ -2291,8 +2298,10 @@ int sh_exec(register const Shnode_t *t, int flags) #if SHOPT_FILESCAN if(iop) { + int err=errno; sfclose(iop); - close(0); + while(close(0)<0 && errno==EINTR) + errno = err; dup(savein); sh.cur_line = 0; } diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh index 53248948b..a77f11742 100755 --- a/src/cmd/ksh93/tests/io.sh +++ b/src/cmd/ksh93/tests/io.sh @@ -961,5 +961,17 @@ got=$( [[ $got == 'test' ]] || err_exit "File descriptor is unexpectedly closed after exec in shared-state command substitution" \ "(expected 'test', got $(printf %q "$got"))" +# ====== +# Test positional parameters in filescan loop +# In 93u+, "$@" wrongly acted like "$*"; fix was backported from 93v- beta +if ((SHOPT_FILESCAN)) +then + echo 'one/two/three' >foo + got=$(IFS=/; while