mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-08-05 20:33:24 +02:00
Extract reclaim_tty into reusable function
Move the inline TTY reclamation logic from build.func into a standalone reclaim_tty() function in core.func. This improves code reusability, as the function now needs to be called before each interactive prompt (not just after install) since pct exec/pull/enter can take the terminal away again. The function also includes better error handling with checks for perl availability and /dev/tty existence, and explicitly sets SIGTTOU to IGNORE in perl.
This commit is contained in:
+8
-9
@@ -5200,15 +5200,11 @@ EOF
|
||||
# TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop)
|
||||
trap '' TSTP TTIN TTOU
|
||||
|
||||
# lxc-attach takes the controlling terminal while the install runs and does
|
||||
# not hand it back, leaving us in a background process group. Reading from
|
||||
# the terminal then returns EIO instead of blocking, because SIGTTIN is
|
||||
# ignored above - so every recovery prompt fails before the user can answer.
|
||||
# Redirecting to /dev/tty does not help: the rule applies to the terminal,
|
||||
# not the file descriptor. Claim the foreground group back; SIGTTOU is
|
||||
# ignored too, so tcsetpgrp() succeeds instead of stopping us. No-op when we
|
||||
# already are in the foreground. perl is a hard dependency of Proxmox VE.
|
||||
perl -e 'use POSIX; open(my $t, "+<", "/dev/tty") or exit 1; POSIX::tcsetpgrp(fileno($t), getpgrp()) or exit 1;' 2>/dev/null || true
|
||||
# lxc-attach left us in a background process group - claim the terminal back
|
||||
# before we print anything. Note this does NOT hold: the log collection
|
||||
# below uses pct pull/exec, which take it away again, so every interactive
|
||||
# prompt has to reclaim it again right before its read.
|
||||
reclaim_tty
|
||||
|
||||
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
|
||||
|
||||
@@ -5338,6 +5334,7 @@ EOF
|
||||
pct enter "$CTID"
|
||||
echo ""
|
||||
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
|
||||
reclaim_tty
|
||||
if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then
|
||||
pct stop "$CTID" &>/dev/null || true
|
||||
pct destroy "$CTID" &>/dev/null || true
|
||||
@@ -5497,6 +5494,7 @@ EOF
|
||||
|
||||
local response=""
|
||||
local read_rc
|
||||
reclaim_tty
|
||||
read -t 60 -r response </dev/tty
|
||||
read_rc=$?
|
||||
if [[ $read_rc -eq 0 ]]; then
|
||||
@@ -5761,6 +5759,7 @@ destroy_lxc() {
|
||||
trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT
|
||||
|
||||
local prompt
|
||||
reclaim_tty
|
||||
if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then
|
||||
# read returns non-zero on Ctrl-D/ESC
|
||||
msg_error "Aborted input (Ctrl-D/ESC)"
|
||||
|
||||
@@ -1042,6 +1042,39 @@ ensure_tput() {
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# reclaim_tty()
|
||||
#
|
||||
# - Reclaims the controlling terminal's foreground process group
|
||||
# - lxc-attach takes the terminal and does not hand it back, leaving us in a
|
||||
# background process group. Reading from the terminal then returns EIO
|
||||
# instead of blocking, because SIGTTIN is ignored during recovery - so the
|
||||
# prompt fails before the user can answer and their keystroke leaks into the
|
||||
# parent shell. Redirecting to /dev/tty does not help: the rule applies to
|
||||
# the terminal, not to the file descriptor.
|
||||
# - pct exec/pull/enter use lxc-attach internally, so the terminal can be taken
|
||||
# away again at any point. Call this immediately before each interactive
|
||||
# read, not once after the install.
|
||||
# - SIGTTOU is ignored inside perl so tcsetpgrp() succeeds instead of stopping
|
||||
# us. No-op when we already are in the foreground or there is no terminal.
|
||||
# perl is a hard dependency of Proxmox VE.
|
||||
# ------------------------------------------------------------------------------
|
||||
reclaim_tty() {
|
||||
command -v perl >/dev/null 2>&1 || return 0
|
||||
[[ -e /dev/tty ]] || return 0
|
||||
|
||||
local pgid
|
||||
pgid=$(ps -o pgid= -p $$ 2>/dev/null | tr -d ' ') || true
|
||||
|
||||
perl -e '
|
||||
use POSIX;
|
||||
$SIG{TTOU} = "IGNORE";
|
||||
my $pgid = $ARGV[0] || POSIX::getpgrp();
|
||||
open(my $t, "+<", "/dev/tty") or exit 1;
|
||||
POSIX::tcsetpgrp(fileno($t), $pgid) or exit 1;
|
||||
' "${pgid:-0}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# is_alpine()
|
||||
#
|
||||
|
||||
@@ -499,6 +499,7 @@ error_handler() {
|
||||
|
||||
local response=""
|
||||
local read_rc
|
||||
declare -f reclaim_tty >/dev/null 2>&1 && reclaim_tty
|
||||
read -t 60 -r response </dev/tty
|
||||
read_rc=$?
|
||||
if [[ $read_rc -eq 0 ]]; then
|
||||
|
||||
Reference in New Issue
Block a user