Skip to content

Commit 93c2a86

Browse files
committed
fix(_comp_finalize): work around INT
1 parent b6a67f6 commit 93c2a86

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

bash_completion

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,7 @@ _comp_variable_assignments()
977977
_comp_finalize__depth=()
978978
_comp_finalize__target=()
979979
_comp_finalize__original_return_trap=
980+
_comp_finalize__original_int_trap=
980981

981982
# This associative array contains the finalizer commands with the key
982983
# being the name of the completed command.
@@ -986,6 +987,27 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
986987
# executed for all the commands.
987988
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
988989

990+
# This array contains the finalizer commands that will be executed for the
991+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
992+
# these hooks are only called at the end of the top-level bash-completion.
993+
# These hooks are ensured to be called even when the completion is canceled by
994+
# SIGINT.
995+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
996+
997+
_comp_finalize__clear()
998+
{
999+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
1000+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
1001+
eval -- "$_hook"
1002+
done
1003+
fi
1004+
_comp_finalize__depth=()
1005+
_comp_finalize__target=()
1006+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
1007+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1008+
_comp_finalize__original_int_trap=
1009+
_comp_finalize__original_return_trap=
1010+
}
9891011
_comp_finalize()
9901012
{
9911013
((${#_comp_finalize__depth[@]})) || return 0
@@ -1012,16 +1034,15 @@ _comp_finalize()
10121034
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
10131035
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
10141036
if ((${#_comp_finalize__depth[@]} == 0)); then
1015-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1016-
_comp_finalize__original_return_trap=
1037+
_comp_finalize__clear
10171038
break
10181039
fi
10191040
done
10201041
}
1021-
# Note: We need to set "trace" function attribute of _comp_finalize to
1022-
# make the trap restoration by "trap - RETURN" take effect in the
1023-
# upper level.
1024-
declare -ft _comp_finalize
1042+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
1043+
# to make the trap restoration by "trap - RETURN" take effect in the upper
1044+
# level.
1045+
declare -ft _comp_finalize__clear _comp_finalize
10251046

10261047
# Initialize completion and deal with various general things: do file
10271048
# and variable completion where appropriate, and adjust prev, words,
@@ -1047,6 +1068,7 @@ _init_completion()
10471068
# called for the top-level completion. [ Note: the completion function may
10481069
# be called recursively using "_command_offset", etc. ]
10491070
if ((${#_comp_finalize__depth[@]} == 0)); then
1071+
_comp_finalize__original_int_trap=$(trap -p INT)
10501072
if shopt -q extdebug || shopt -qo functrace; then
10511073
# If extdebug / functrace is set, we need to explicitly save and
10521074
# restore the original trap handler because the outer trap handlers
@@ -1059,7 +1081,15 @@ _init_completion()
10591081
# do not need to explicitly save the outer trap handler.
10601082
_comp_finalize__original_return_trap=
10611083
fi
1084+
1085+
# Note: Ignore the traps previously set by us to avoid infinite
1086+
# loop in case that the previously set traps remain by some
1087+
# accidents.
1088+
_comp_finalize__original_return_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1089+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1090+
10621091
trap _comp_finalize RETURN
1092+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
10631093
fi
10641094
_comp_finalize__depth+=("${#FUNCNAME[@]}")
10651095
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)