fix: end the bootstrap with 130 on ctrl+c

This commit is contained in:
Abdessamad Derraz committed 2026-11-05 19:25:33 +01:00
1 parent 73b82375d9
commit c54a68c6ca
2 files changed
+53 -1

No files matched your search

+7 -1
View File
@@ -34,7 +34,13 @@ cleanup() {
rmdir -- "$TEMP_DIRECTORY" 2>/dev/null || true
fi
}
trap cleanup EXIT HUP INT TERM
# A signal ends the run with the code a shell gives it, 130 for Ctrl+C:
# trapped by cleanup alone, the run went on, and Ctrl+C during the download
# was told as a network failure, with code 1.
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
if [ -z "$INSTALLER" ] || [ ! -f "$INSTALLER" ]; then
install_url=${RETROBIOS_INSTALL_URL:-$DEFAULT_INSTALL_URL}
+46
View File
@@ -14,6 +14,7 @@ import select
import shlex
import re
import shutil
import signal
import socket
import subprocess
import sys
@@ -2288,6 +2289,51 @@ class TestAvailablePlatforms(unittest.TestCase):
self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr)
self.assertIn("retroarch", proc.stdout)
@unittest.skipIf(os.name == "nt", "the sh bootstrap is POSIX")
def test_ctrl_c_during_the_download_ends_with_130(self):
"""Ctrl+C while install.py downloaded: the trap cleaned up and the
script went on to blame the network, with code 1."""
scratch = REPO_ROOT / "tmp" / "tests"
scratch.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory(dir=scratch) as directory:
root = Path(directory)
fake_bin = root / "bin"
fake_bin.mkdir()
started = root / "started"
(fake_bin / "curl").write_text(
f"#!/bin/sh\n: > '{started}'\nexec sleep 60\n", encoding="utf-8")
(fake_bin / "curl").chmod(0o755)
env = {**os.environ, "PATH": f"{fake_bin}{os.pathsep}{os.environ['PATH']}",
"TMPDIR": str(root),
"RETROBIOS_INSTALL_URL": "https://example.invalid/install.py"}
for shell in ("sh", "bash"):
if not shutil.which(shell):
continue
with self.subTest(shell=shell):
started.unlink(missing_ok=True)
proc = subprocess.Popen(
[shell, "-s", "--", "--check"], cwd=root, env=env,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, text=True, start_new_session=True)
proc.stdin.write((REPO_ROOT / "install.sh").read_text(encoding="utf-8"))
proc.stdin.close()
proc.stdin = None
try:
deadline = time.monotonic() + 30
while not started.exists() and time.monotonic() < deadline:
time.sleep(0.05)
self.assertTrue(started.exists(), "the download never started")
os.killpg(proc.pid, signal.SIGINT)
_out, err = proc.communicate(timeout=30)
finally:
if proc.poll() is None:
os.killpg(proc.pid, signal.SIGKILL)
proc.communicate()
self.assertEqual(proc.returncode, 130, err)
self.assertNotIn("could not be downloaded", err)
self.assertEqual(sorted(p.name for p in root.iterdir()),
["bin", "started"])
def test_a_failed_download_says_so_in_one_message(self):
"""Offline, the one-liner printed curl's progress table and
"curl: (6) ...", then exited 6, a code the table does not list."""