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

Improve and document fast filescan loops (SHOPT_FILESCAN)

From README:

FILESCAN on  Experimental option that allows fast reading of files
             using while < file;do ...; done and allowing fields in
             each line to be accessed as positional parameters.

As SHOPT_FILESCAN has been enabled by default since ksh 93l
2001-06-01, the filescan loop is now documented in the manual page
and the compile-time option is no longer considered experimental.

We must disable this at runtime if --posix is active because it
breaks a portable use case: POSIXly, 'while <file; do stuff; done'
repeatedly excutes 'stuff' while 'file' can successfully be opened
for reading, without actually reading from 'file'.

This also backports a bugfix from the 93v- beta. Reproducer:

$ echo 'one two three' >foo
$ while <foo; do printf '[%s] ' "$@"; echo; done
[one two three]

Expected output:
[one] [two] [three]

The bug is that "$@" acts like "$*", joining all the positional
parameters into one word though it should be generating one word
for each.

src/cmd/ksh93/sh/macro.c: varsub():
- Backport fix for the bug described above. I do not understand the
  opaque macro.c code well enough yet to usefully describe the fix.

src/cmd/ksh93/sh/xec.c: sh_exec():
- Improved sanity check for filescan loop: do not recognise it if
  the simple command includes variable assignments, more than one
  redirection, or an output or append redirection.
- Disable filescan loops if --posix is active.
- Another 93v- fix: handle interrupts (errno==EINTR) when closing
  the input file.
This commit is contained in:
Martijn Dekker 2022-02-15 17:54:45 +00:00
parent 82ff91e9d9
commit 95d695cb5a
9 changed files with 102 additions and 15 deletions

View file

@ -357,7 +357,6 @@ struct Shell_s
Shinit_f userinit;
Shbltin_f bltinfun;
Shbltin_t bltindata;
char *cur_line;
int offsets[10];
Sfio_t **sftable;
unsigned char *fdstatus;
@ -384,6 +383,9 @@ struct Shell_s
char exittrap;
char errtrap;
char end_fn;
#if SHOPT_FILESCAN
char *cur_line;
#endif
#if !SHOPT_DEVFD
char *fifo; /* FIFO name for current process substitution */
Dt_t *fifo_tree; /* for cleaning up process substitution FIFOs */