Skip to content

Commit 645cc1f

Browse files
committed
fix(_comp_finalize): work around INT
1 parent bdf3606 commit 645cc1f

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
@@ -890,6 +890,7 @@ _comp_variable_assignments()
890890
_comp_finalize__depth=()
891891
_comp_finalize__target=()
892892
_comp_finalize__original_return_trap=
893+
_comp_finalize__original_int_trap=
893894

894895
# This associative array contains the finalizer commands with the key
895896
# being the name of the completed command.
@@ -899,6 +900,28 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
899900
# executed for all the commands.
900901
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
901902

903+
# This array contains the finalizer commands that will be executed for the
904+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
905+
# these hooks are only called at the end of the top-level bash-completion.
906+
# These hooks are ensured to be called even when the completion is canceled by
907+
# SIGINT.
908+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
909+
910+
_comp_finalize__clear()
911+
{
912+
local _hook
913+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
914+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
915+
eval -- "$_hook"
916+
done
917+
fi
918+
_comp_finalize__depth=()
919+
_comp_finalize__target=()
920+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
921+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
922+
_comp_finalize__original_int_trap=
923+
_comp_finalize__original_return_trap=
924+
}
902925
_comp_finalize()
903926
{
904927
((${#_comp_finalize__depth[@]})) || return 0
@@ -925,16 +948,15 @@ _comp_finalize()
925948
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
926949
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
927950
if ((${#_comp_finalize__depth[@]} == 0)); then
928-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
929-
_comp_finalize__original_return_trap=
951+
_comp_finalize__clear
930952
break
931953
fi
932954
done
933955
}
934-
# Note: We need to set "trace" function attribute of _comp_finalize to
935-
# make the trap restoration by "trap - RETURN" take effect in the
936-
# upper level.
937-
declare -ft _comp_finalize
956+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
957+
# to make the trap restoration by "trap - RETURN" take effect in the upper
958+
# level.
959+
declare -ft _comp_finalize__clear _comp_finalize
938960

939961
# Initialize completion and deal with various general things: do file
940962
# and variable completion where appropriate, and adjust prev, words,
@@ -974,6 +996,7 @@ _comp_initialize()
974996
# called for the top-level completion. [ Note: the completion function may
975997
# be called recursively using "_command_offset", etc. ]
976998
if ((${#_comp_finalize__depth[@]} == 0)); then
999+
_comp_finalize__original_int_trap=$(trap -p INT)
9771000
if shopt -q extdebug || shopt -qo functrace; then
9781001
# If extdebug / functrace is set, we need to explicitly save and
9791002
# restore the original trap handler because the outer trap handlers
@@ -986,7 +1009,15 @@ _comp_initialize()
9861009
# do not need to explicitly save the outer trap handler.
9871010
_comp_finalize__original_return_trap=
9881011
fi
1012+
1013+
# Note: Ignore the traps previously set by us to avoid infinite
1014+
# loop in case that the previously set traps remain by some
1015+
# accidents.
1016+
_comp_finalize__original_return_trap=${_comp_finalize__original_return_trap##"trap -- '_comp_finalize"*}
1017+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1018+
9891019
trap _comp_finalize RETURN
1020+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
9901021
fi
9911022
_comp_finalize__depth+=("${#FUNCNAME[@]}")
9921023
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)