Skip to content

Commit 275a84a

Browse files
committed
fix(_comp_finalize): work around INT
1 parent 7da801c commit 275a84a

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

bash_completion

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ _comp_variable_assignments()
990990
_comp_finalize__depth=()
991991
_comp_finalize__target=()
992992
_comp_finalize__original_return_trap=
993+
_comp_finalize__original_int_trap=
993994

994995
# This associative array contains the finalizer commands with the key
995996
# being the name of the completed command.
@@ -999,6 +1000,28 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
9991000
# executed for all the commands.
10001001
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
10011002

1003+
# This array contains the finalizer commands that will be executed for the
1004+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
1005+
# these hooks are only called at the end of the top-level bash-completion.
1006+
# These hooks are ensured to be called even when the completion is canceled by
1007+
# SIGINT.
1008+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
1009+
1010+
_comp_finalize__clear()
1011+
{
1012+
local _hook
1013+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
1014+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
1015+
eval -- "$_hook"
1016+
done
1017+
fi
1018+
_comp_finalize__depth=()
1019+
_comp_finalize__target=()
1020+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
1021+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1022+
_comp_finalize__original_int_trap=
1023+
_comp_finalize__original_return_trap=
1024+
}
10021025
_comp_finalize()
10031026
{
10041027
((${#_comp_finalize__depth[@]})) || return 0
@@ -1025,16 +1048,15 @@ _comp_finalize()
10251048
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
10261049
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
10271050
if ((${#_comp_finalize__depth[@]} == 0)); then
1028-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1029-
_comp_finalize__original_return_trap=
1051+
_comp_finalize__clear
10301052
break
10311053
fi
10321054
done
10331055
}
1034-
# Note: We need to set "trace" function attribute of _comp_finalize to
1035-
# make the trap restoration by "trap - RETURN" take effect in the
1036-
# upper level.
1037-
declare -ft _comp_finalize
1056+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
1057+
# to make the trap restoration by "trap - RETURN" take effect in the upper
1058+
# level.
1059+
declare -ft _comp_finalize__clear _comp_finalize
10381060

10391061
# Initialize completion and deal with various general things: do file
10401062
# and variable completion where appropriate, and adjust prev, words,
@@ -1074,6 +1096,7 @@ _comp_initialize()
10741096
# called for the top-level completion. [ Note: the completion function may
10751097
# be called recursively using "_command_offset", etc. ]
10761098
if ((${#_comp_finalize__depth[@]} == 0)); then
1099+
_comp_finalize__original_int_trap=$(trap -p INT)
10771100
if shopt -q extdebug || shopt -qo functrace; then
10781101
# If extdebug / functrace is set, we need to explicitly save and
10791102
# restore the original trap handler because the outer trap handlers
@@ -1086,7 +1109,15 @@ _comp_initialize()
10861109
# do not need to explicitly save the outer trap handler.
10871110
_comp_finalize__original_return_trap=
10881111
fi
1112+
1113+
# Note: Ignore the traps previously set by us to avoid infinite
1114+
# loop in case that the previously set traps remain by some
1115+
# accidents.
1116+
_comp_finalize__original_return_trap=${_comp_finalize__original_return_trap##"trap -- '_comp_finalize"*}
1117+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1118+
10891119
trap _comp_finalize RETURN
1120+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
10901121
fi
10911122
_comp_finalize__depth+=("${#FUNCNAME[@]}")
10921123
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)