Skip to content

Commit

Permalink
var/loop: cheat so bash in POSIX mode can use process substitution
Browse files Browse the repository at this point in the history
Modernish 0.16.x always enables POSIX mode for bash upon init.
Unfortunately, bash disables process substitution in POSIX mode,
so PROCSUBST is not detected. Therefore, let's cheat.

This cheat is important because Solaris and derivatives have a
nasty race condition with the named pipes (FIFOs) that the portable
version uses (ref.: https://www.illumos.org/issues/10179), which
may cause bash to hang when using modernish loops under high system
load. The "reset everything and retry" workaround in the portable
version is effective for dash and some other shells, but not bash.
Thus, by avoiding FIFOs, this cheat makes modernish loops work
reliably on bash on Solaris and illumos-based systems.

lib/modernish/mdl/var/loop.mm:
- If bash and POSIX mode are detected, redo the PROCSUBST feature
  test with POSIX mode disabled. If that detects process
  substitution, use a cheat version of _Msh_loopgen() that turns
  off POSIX mode just long enough to launch the iteration generator
  using process substitution. Of course POSIX mode is also turned
  back on for the iteration generator process.
  • Loading branch information
McDutchie committed Jan 16, 2020
1 parent 4e708a6 commit 92844ef
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/modernish/mdl/var/loop.mm
Expand Up @@ -154,6 +154,23 @@
_loopgen_${_loop_type} "$@"
)
}'
elif isset BASH_VERSION && isset -o posix && (
set +o posix; eval 'IFS= read -r _Msh_test < <(putln PROCSUBST)' && str eq "${_Msh_test}" PROCSUBST
) </dev/null 2>/dev/null; then
# Unfortunately, bash disables process substitution in POSIX mode, so PROCSUBST is not detected. Therefore, let's cheat.
eval '_Msh_loopgen() {
exec 8<&0 # save stdin
set +o posix
eval '\''exec 8< <(
set -o posix -fCu +ax
IFS=""
exec 0<&8 8>&1 1>&2
readonly _loop_type=$1
shift
_loopgen_${_loop_type} "$@"
)'\''
set -o posix
}'
elif thisshellhas PROCREDIR; then
# Process redirection (yash).
eval '_Msh_loopgen() {
Expand Down

0 comments on commit 92844ef

Please sign in to comment.