Skip to content

Commit 912688e

Browse files
committed
fix(_comp_finalize): work around INT
1 parent 91c5f9d commit 912688e

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
@@ -905,6 +905,7 @@ _comp_variable_assignments()
905905
_comp_finalize__depth=()
906906
_comp_finalize__target=()
907907
_comp_finalize__original_return_trap=
908+
_comp_finalize__original_int_trap=
908909

909910
# This associative array contains the finalizer commands with the key
910911
# being the name of the completed command.
@@ -914,6 +915,28 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
914915
# executed for all the commands.
915916
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
916917

918+
# This array contains the finalizer commands that will be executed for the
919+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
920+
# these hooks are only called at the end of the top-level bash-completion.
921+
# These hooks are ensured to be called even when the completion is canceled by
922+
# SIGINT.
923+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
924+
925+
_comp_finalize__clear()
926+
{
927+
local _hook
928+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
929+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
930+
eval -- "$_hook"
931+
done
932+
fi
933+
_comp_finalize__depth=()
934+
_comp_finalize__target=()
935+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
936+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
937+
_comp_finalize__original_int_trap=
938+
_comp_finalize__original_return_trap=
939+
}
917940
_comp_finalize()
918941
{
919942
((${#_comp_finalize__depth[@]})) || return 0
@@ -940,16 +963,15 @@ _comp_finalize()
940963
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
941964
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
942965
if ((${#_comp_finalize__depth[@]} == 0)); then
943-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
944-
_comp_finalize__original_return_trap=
966+
_comp_finalize__clear
945967
break
946968
fi
947969
done
948970
}
949-
# Note: We need to set "trace" function attribute of _comp_finalize to
950-
# make the trap restoration by "trap - RETURN" take effect in the
951-
# upper level.
952-
declare -ft _comp_finalize
971+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
972+
# to make the trap restoration by "trap - RETURN" take effect in the upper
973+
# level.
974+
declare -ft _comp_finalize__clear _comp_finalize
953975

954976
# Initialize completion and deal with various general things: do file
955977
# and variable completion where appropriate, and adjust prev, words,
@@ -989,6 +1011,7 @@ _comp_initialize()
9891011
# called for the top-level completion. [ Note: the completion function may
9901012
# be called recursively using "_command_offset", etc. ]
9911013
if ((${#_comp_finalize__depth[@]} == 0)); then
1014+
_comp_finalize__original_int_trap=$(trap -p INT)
9921015
if shopt -q extdebug || shopt -qo functrace; then
9931016
# If extdebug / functrace is set, we need to explicitly save and
9941017
# restore the original trap handler because the outer trap handlers
@@ -1001,7 +1024,15 @@ _comp_initialize()
10011024
# do not need to explicitly save the outer trap handler.
10021025
_comp_finalize__original_return_trap=
10031026
fi
1027+
1028+
# Note: Ignore the traps previously set by us to avoid infinite
1029+
# loop in case that the previously set traps remain by some
1030+
# accidents.
1031+
_comp_finalize__original_return_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1032+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1033+
10041034
trap _comp_finalize RETURN
1035+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
10051036
fi
10061037
_comp_finalize__depth+=("${#FUNCNAME[@]}")
10071038
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)