Skip to content

Commit 1d5163b

Browse files
committed
fix(_comp_finalize): work around INT
1 parent 8c136ed commit 1d5163b

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
@@ -1338,6 +1338,7 @@ _comp_variable_assignments()
13381338
_comp_finalize__depth=()
13391339
_comp_finalize__target=()
13401340
_comp_finalize__original_return_trap=
1341+
_comp_finalize__original_int_trap=
13411342

13421343
# This associative array contains the finalizer commands with the key
13431344
# being the name of the completed command.
@@ -1347,6 +1348,28 @@ declare -gA BASH_COMPLETION_FINALIZE_CMD_HOOKS
13471348
# executed for all the commands.
13481349
declare -ga BASH_COMPLETION_FINALIZE_HOOKS
13491350

1351+
# This array contains the finalizer commands that will be executed for the
1352+
# top-level bash-completion functions. Unlike BASH_COMPLETION_FINALIZE_HOOKS,
1353+
# these hooks are only called at the end of the top-level bash-completion.
1354+
# These hooks are ensured to be called even when the completion is canceled by
1355+
# SIGINT.
1356+
declare -ga BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS
1357+
1358+
_comp_finalize__clear()
1359+
{
1360+
local _hook
1361+
if [[ ${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[*]+set} ]]; then
1362+
for _hook in "${BASH_COMPLETION_FINALIZE_TOPLEVEL_HOOKS[@]}"; do
1363+
eval -- "$_hook"
1364+
done
1365+
fi
1366+
_comp_finalize__depth=()
1367+
_comp_finalize__target=()
1368+
eval -- "${_comp_finalize__original_int_trap:-trap - INT}"
1369+
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1370+
_comp_finalize__original_int_trap=
1371+
_comp_finalize__original_return_trap=
1372+
}
13501373
_comp_finalize()
13511374
{
13521375
((${#_comp_finalize__depth[@]})) || return 0
@@ -1373,16 +1396,15 @@ _comp_finalize()
13731396
unset -v '_comp_finalize__depth[${#_comp_finalize__depth[@]}-1]'
13741397
unset -v '_comp_finalize__target[${#_comp_finalize__target[@]}-1]'
13751398
if ((${#_comp_finalize__depth[@]} == 0)); then
1376-
eval -- "${_comp_finalize__original_return_trap:-trap - RETURN}"
1377-
_comp_finalize__original_return_trap=
1399+
_comp_finalize__clear
13781400
break
13791401
fi
13801402
done
13811403
}
1382-
# Note: We need to set "trace" function attribute of _comp_finalize to
1383-
# make the trap restoration by "trap - RETURN" take effect in the
1384-
# upper level.
1385-
declare -ft _comp_finalize
1404+
# Note: We need to set "trace" function attribute of _comp_finalize{,__clear}
1405+
# to make the trap restoration by "trap - RETURN" take effect in the upper
1406+
# level.
1407+
declare -ft _comp_finalize__clear _comp_finalize
13861408

13871409
# Initialize completion and deal with various general things: do file
13881410
# and variable completion where appropriate, and adjust prev, words,
@@ -1426,6 +1448,7 @@ _comp_initialize()
14261448
# called for the top-level completion. [ Note: the completion function may
14271449
# be called recursively using "_command_offset", etc. ]
14281450
if ((${#_comp_finalize__depth[@]} == 0)); then
1451+
_comp_finalize__original_int_trap=$(trap -p INT)
14291452
if shopt -q extdebug || shopt -qo functrace; then
14301453
# If extdebug / functrace is set, we need to explicitly save and
14311454
# restore the original trap handler because the outer trap handlers
@@ -1438,7 +1461,15 @@ _comp_initialize()
14381461
# do not need to explicitly save the outer trap handler.
14391462
_comp_finalize__original_return_trap=
14401463
fi
1464+
1465+
# Note: Ignore the traps previously set by us to avoid infinite
1466+
# loop in case that the previously set traps remain by some
1467+
# accidents.
1468+
_comp_finalize__original_return_trap=${_comp_finalize__original_return_trap##"trap -- '_comp_finalize"*}
1469+
_comp_finalize__original_int_trap=${_comp_finalize__original_int_trap##"trap -- '_comp_finalize"*}
1470+
14411471
trap _comp_finalize RETURN
1472+
trap '_comp_finalize__clear; kill -INT "$BASHPID"' INT
14421473
fi
14431474
_comp_finalize__depth+=("${#FUNCNAME[@]}")
14441475
_comp_finalize__target+=("${FUNCNAME[1]-}")

0 commit comments

Comments
 (0)