From 4984570756db8553813ad17c1f8a6851999c3735 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sat, 24 Aug 2024 11:47:44 +0900 Subject: [PATCH] main: fix attach failure with "--attach=prompt" in Bash 5.3 POSIX mode --- ble.pp | 51 ++++++++++++++++++++++++++++++++++++++++---- docs/ChangeLog.md | 3 ++- lib/test-bash.sh | 2 +- note.txt | 54 +++++++++++++++++++++++++++++++++++++++++++++++ src/util.sh | 6 +++++- 5 files changed, 109 insertions(+), 7 deletions(-) diff --git a/ble.pp b/ble.pp index 44638e1f..d236dbb2 100644 --- a/ble.pp +++ b/ble.pp @@ -273,6 +273,18 @@ function ble/util/print { printf '%s\n' "$1"; } \builtin unset -v FUNCNEST fi fi 2>/dev/null' + _ble_bash_FUNCNEST_local_adjust=' + \local _ble_local_FUNCNEST _ble_local_FUNCNEST_set + _ble_local_FUNCNEST_set=${FUNCNEST+set} + _ble_local_FUNCNEST=${FUNCNEST-} + if [[ $_ble_local_FUNCNEST_set ]]; then + \local FUNCNEST + \builtin unset -v FUNCNEST + fi' + _ble_bash_FUNCNEST_local_leave=' + if [[ $_ble_local_FUNCNEST_set ]]; then + FUNCNEST=$_ble_local_FUNCNEST + fi' \builtin eval -- "$_ble_bash_FUNCNEST_adjust" \builtin unset -v POSIXLY_CORRECT @@ -2693,7 +2705,17 @@ function ble/base/install-prompt-attach { _ble_base_attach_from_prompt=1 if ((_ble_bash>=50100)); then ((${#PROMPT_COMMAND[@]})) || PROMPT_COMMAND[0]= - ble/array#push PROMPT_COMMAND ble/base/attach-from-PROMPT_COMMAND + + local prompt_command=ble/base/attach-from-PROMPT_COMMAND + if ((_ble_bash>=50300)); then + ble/function#lambda prompt_command ' + builtin eval -- "$_ble_bash_FUNCNEST_adjust" + builtin eval -- "$_ble_bash_POSIXLY_CORRECT_adjust" + ble/base/attach-from-PROMPT_COMMAND' + ble/function#trace "$prompt_command" + fi + ble/array#push PROMPT_COMMAND "$prompt_command" + if [[ $_ble_edit_detach_flag == reload ]]; then _ble_edit_detach_flag=prompt-attach blehook internal_PRECMD!=ble/base/attach-from-PROMPT_COMMAND @@ -2701,8 +2723,14 @@ function ble/base/install-prompt-attach { else local save_index=${#_ble_base_attach_PROMPT_COMMAND[@]} _ble_base_attach_PROMPT_COMMAND[save_index]=${PROMPT_COMMAND-} - ble/function#lambda PROMPT_COMMAND \ - "ble/base/attach-from-PROMPT_COMMAND $save_index \"\$FUNCNAME\"" + # Note: We adjust FUNCNEST and POSIXLY_CORRECT but do not need to be + # restore them here because "ble/base/attach-from-PROMPT_COMMAND" fails + # only when "ble-attach" fails, in such a case "ble-attach" already restore + # them. + ble/function#lambda PROMPT_COMMAND ' + builtin eval -- "$_ble_bash_FUNCNEST_adjust" + builtin eval -- "$_ble_bash_POSIXLY_CORRECT_adjust" + ble/base/attach-from-PROMPT_COMMAND '"$save_index"' "'"$FUNCNAME"'"' ble/function#trace "$PROMPT_COMMAND" if [[ $_ble_edit_detach_flag == reload ]]; then _ble_edit_detach_flag=prompt-attach @@ -2721,6 +2749,9 @@ function ble/base/attach-from-PROMPT_COMMAND { _ble_base_attach_from_prompt_lastexit=$? \ _ble_base_attach_from_prompt_lastarg=$_ \ _ble_base_attach_from_prompt_PIPESTATUS=("${PIPESTATUS[@]}") + + builtin eval -- "$_ble_bash_FUNCNEST_adjust" + #%if measure_load_time ble/util/print "ble.sh: $EPOCHREALTIME start prompt-attach" >&2 #%end @@ -2786,7 +2817,15 @@ function ble/base/attach-from-PROMPT_COMMAND { fi } 2>/dev/null # set -x 対策 #D0930 - ble-attach force + ble-attach force; local ext=$? + +#FUNCNEST? + # Note: When POSIXLY_CORRECT is adjusted outside this function, and when + # "ble-attach force" fails, the adjusted POSIXLY_CORRECT may be restored. + # For such a case, we need to locally adjust POSIXLY_CORRECT to work around + # 5.3 function names with a slash. + builtin eval -- "$_ble_bash_FUNCNEST_local_adjust" + builtin eval -- "$_ble_bash_POSIXLY_CORRECT_local_adjust" # Note: 何故か分からないが PROMPT_COMMAND から ble-attach すると # ble/bin/stty や ble/bin/mkfifo や tty 2>/dev/null などが @@ -2797,6 +2836,10 @@ function ble/base/attach-from-PROMPT_COMMAND { #%if measure_load_time ble/util/print "ble.sh: $EPOCHREALTIME end prompt-attach" >&2 #%end + + builtin eval -- "$_ble_bash_POSIXLY_CORRECT_local_leave" + builtin eval -- "$_ble_bash_FUNCNEST_local_leave" + return "$?" } function ble/base/process-blesh-arguments { diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index bcb6c06c..ea42244e 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -15,7 +15,8 @@ - main: update the startup message for debug versions of Bash `#D2222` afb29073 - main: shorten the startup message for debug versions `#D2241` 0bc8610a - decode(read-user-settings): read the colonless form of `bind -x` of Bash 5.3 `#D2233` 62b23b69 - - progcomp: use Bash 5.3 "compgen -V" for completions with newlines (motivated by RBT22) `#D2253` 0e8c388a + - progcomp: use Bash 5.3 `compgen -V` for completions with newlines (motivated by RBT22) `#D2253` 0e8c388a + - main: fix attach failure with `--attach=prompt` in Bash 5.3 POSIX mode `#D2267` xxxxxxxx - bgproc: support opts `kill9-timeout=TIMEOUT` `#D2034` 3ab41652 - progcomp(cd): change display name and support mandb desc (requested by EmilySeville7cfg) `#D2039` 74402098 - cmdspec: add completion options for builtins (motivated by EmilySeville7cfg) `#D2040` 9bd24691 diff --git a/lib/test-bash.sh b/lib/test-bash.sh index 51cf37e9..2d5e556a 100644 --- a/lib/test-bash.sh +++ b/lib/test-bash.sh @@ -125,7 +125,7 @@ ble/test/start-section 'bash' 69 if ((_ble_bash<50300)); then ble/test 'set -o posix; f1/sub; ret=$?; set +o posix' ret=0 else - ble/test 'set -o posix; f1/sub; ret=$?; set +o posix' ret=0 + ble/test 'set -o posix; f1/sub; ret=$?; set +o posix' ret=127 fi # BUG bash-3.0 diff --git a/note.txt b/note.txt index cae0d5a1..6b176f8b 100644 --- a/note.txt +++ b/note.txt @@ -7373,6 +7373,60 @@ bash_tips 2024-08-25 + * main: bash-5.3 -o posix で --atatch=prompt に失敗する [#D2267] + + prompt-attach に失敗する。ble-attach を明示的に呼び出した時は問題ない。set + -o posix の状態管理を再確認する。 + + 取り敢えず修正した。テストする。 + + * fixed: 実は FUNCNEST の方もちゃんと調整が必要なのでは? 修正した。試して見 + るとちゃんと動いている。FUNCNEST=0 でも FUNCNEST=1 でもちゃんと動く。 + + そもそも修正が必要だったのか? よく考えたら動かないという事を確認した訳で + もない → 試してみたら修正前は FUNCNEST=1 などと指定したら動かなかった。 + なのでやはり修正は必要で、実際に今回の修正で動く様になっている。 + + ? ok: POSIXLY_CORRECT 及び FUNCNEST の処理では普通に unset -v + POSIXLY_CORRECT や unset -v FUNCNEST を呼び出しているが、途中でローカル変 + 数として定義されている場合はどうなるのか。変数を消去してしまって問題にな + るのでは? と思ったが、基本的には ble.sh の内部処理は ble.sh 自身の関数呼 + び出しツリーの中で実行されるので POSIXLY_CORRECT 及び FUNCNEST が local + に設定されている事はない。 + + 然し様々の ble-face 等のユーザーから呼び出す事を想定している関数について + は下手をするとユーザーの設定した local POSIXLY_CORRECT を消去する事になる + のでは? shopt -s localvar_unset を一時的に設定する等して対処した方が良い + だろうか。然し、それはそれで処理が長くなるし最近の bash でしかできない対 + 策になる。気にしない事にする。或いは Limitations にその事を記述する? 然し、 + 或る程度は動く様に対策しているという事も含めて書かなければならないので面 + 倒である。 + + * set -o posix のテストが失敗している @ bash-5.3 → これは単にテストケース + 自体が間違っていた。5.3 以上とそれ以外で分岐しているのにも拘らず、両方と + も全く同じテスト要件になっていた。期待する終了ステータスが同じになってい + た。修正した。 + + * [OK] canvas: Cygwin 上で char_width_mode test の [xx] の表示が最新版でも見える。何故? [#D2266] + + _ble_term_invis で見えない様にした筈なのに。term_synchronized_update_mode + は無効になっているので強制的に描画が発生している訳ではない → どうやら + screen は invis に対応していない様だ。 + + またテストが発生する位置は右端にしたのではなかったか? と思ったが右側でテス + トを行うのは、画面の右上であって更に ble.sh の初期化が終わった後に使われる + 方法だった。そもそも初期化時点では COLUMNS が正しく設定されているかも分から + ないので右端を使うのは避けていたという事の気がする。 + + ? ok: 所で COLUMNS が空の時に 80 と想定して画面の「右上」で処理を行っている + がこれは問題では。実際にはもっと画面を広くしている可能性もあるし、その時 + に画面の最初の行の途中の文字が消えてしまう事になる。 + + % COLUMNS が空なら現在行を用いるべきでは? と思ったが、逆に現在行を用いる + % と ble.sh の表示している UI と干渉する可能性がある。つまり、最初の行を + % 使っていたのは、現在行を安全に使えないこと、また、その行が vbell によっ + % て予約されている行だったから自由に使える事ができたというだけの事である。 + * edit: bash-3.2 がまた動かなくなっている [#D2265] Ref: #D2228, #D2217 diff --git a/src/util.sh b/src/util.sh index 8a5c3c7c..3c4e524d 100644 --- a/src/util.sh +++ b/src/util.sh @@ -2669,7 +2669,11 @@ function ble/function#push/call-top { ## 無名関数を定義しその実際の名前を変数 var に格納します。 function ble/function#lambda { local _ble_local_q=\' _ble_local_Q="'\''" - ble/util/set "$1" ble/function#lambda/$((_ble_util_lambda_count++)) + if ((_ble_bash>=50300)); then + ble/util/set "$1" ".ble::function#lambda::$((_ble_util_lambda_count++))" # WA #D2221 + else + ble/util/set "$1" "ble/function#lambda/$((_ble_util_lambda_count++))" + fi builtin eval -- "function ${!1} { builtin eval -- '${2//$_ble_local_q/$_ble_local_Q}'; }" }