Skip to content

Commit 705c512

Browse files
committed
fix(_comp_finalize): work around INT
1 parent 40235a3 commit 705c512

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
@@ -971,6 +971,7 @@ _comp_variable_assignments()
971971
_comp_finalize__depth=()
972972
_comp_finalize__target=()
973973
_comp_finalize__original_return_trap=
974+
_comp_finalize__original_int_trap=
974975

975976
# This associative array contains the finalizer commands with the key
976977
# being the name of the completed command.
@@ -980,6 +981,28 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
980981
# executed for all the commands.
981982
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
982983

984+
# This array contains the finalizer commands that will be executed for the
985+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
986+
# these hooks are only called at the end of the top-level bash-completion.
987+
# These hooks are ensured to be called even when the completion is canceled by
988+
# SIGINT.
989+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
990+
991+
_comp_finalize__clear()
992+
{
993+
local _hook
994+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
995+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
996+
eval -- "$_hook"
997+
done
998+
fi
999+
_comp_finalize__depth=()
1000+
_comp_finalize__target=()
1001+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
1002+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1003+
_comp_finalize__original_int_trap=
1004+
_comp_finalize__original_return_trap=
1005+
}
9831006
_comp_finalize()
9841007
{
9851008
((${#_comp_finalize__depth[@]})) || return 0
@@ -1006,16 +1029,15 @@ _comp_finalize()
10061029
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
10071030
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
10081031
if ((${#_comp_finalize__depth[@]} == 0)); then
1009-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1010-
_comp_finalize__original_return_trap=
1032+
_comp_finalize__clear
10111033
break
10121034
fi
10131035
done
10141036
}
1015-
# Note: We need to set "trace" function attribute of _comp_finalize to
1016-
# make the trap restoration by "trap - RETURN" take effect in the
1017-
# upper level.
1018-
declare -ft _comp_finalize
1037+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
1038+
# to make the trap restoration by "trap - RETURN" take effect in the upper
1039+
# level.
1040+
declare -ft _comp_finalize__clear _comp_finalize
10191041

10201042
# Initialize completion and deal with various general things: do file
10211043
# and variable completion where appropriate, and adjust prev, words,
@@ -1055,6 +1077,7 @@ _comp_initialize()
10551077
# called for the top-level completion. [ Note: the completion function may
10561078
# be called recursively using "_command_offset", etc. ]
10571079
if ((${#_comp_finalize__depth[@]} == 0)); then
1080+
_comp_finalize__original_int_trap=$(trap -p INT)
10581081
if shopt -q extdebug || shopt -qo functrace; then
10591082
# If extdebug / functrace is set, we need to explicitly save and
10601083
# restore the original trap handler because the outer trap handlers
@@ -1067,7 +1090,15 @@ _comp_initialize()
10671090
# do not need to explicitly save the outer trap handler.
10681091
_comp_finalize__original_return_trap=
10691092
fi
1093+
1094+
# Note: Ignore the traps previously set by us to avoid infinite
1095+
# loop in case that the previously set traps remain by some
1096+
# accidents.
1097+
_comp_finalize__original_return_trap=${_comp_finalize__original_return_trap##"trap -- '_comp_finalize"*}
1098+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1099+
10701100
trap _comp_finalize RETURN
1101+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
10711102
fi
10721103
_comp_finalize__depth+=("${#FUNCNAME[@]}")
10731104
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)