From 1d888b45ae5f6a2b836c11a513dd021c9d583bbd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 18:20:54 +0000 Subject: [PATCH] Fix zombie process in canary-download by reaping signify-openbsd child process.kill() was called without process.wait() in both the TimeoutExpired and BaseException exception handlers, leaving the signify-openbsd child as a zombie. Also clean up the subprocess in the SIGTERM/SIGINT signal handler so it is reaped when the outer timeout command terminates canary-download. https://claude.ai/code/session_012TwkQYwRUwxpuNFPUdsZfd --- usr/libexec/systemcheck/canary-download | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/usr/libexec/systemcheck/canary-download b/usr/libexec/systemcheck/canary-download index 786cfad..2310af1 100755 --- a/usr/libexec/systemcheck/canary-download +++ b/usr/libexec/systemcheck/canary-download @@ -30,8 +30,16 @@ os.environ['TZ'] = 'UTC' time.tzset() +_signify_process = None + def canary_download_signal_handler(sig, frame): print("canary_download_signal_handler") + if _signify_process is not None: + try: + _signify_process.kill() + _signify_process.wait() + except OSError: + pass sys.exit(128 + sig) @@ -120,11 +128,14 @@ def main(): # Avoid Popen shell=True. signify_openbsd_cmd = shlex.split(signify_openbsd_cmd) + global _signify_process + process = subprocess.Popen( signify_openbsd_cmd, stdout=PIPE, stderr=PIPE ) + _signify_process = process try: process.wait(timeout_seconds) @@ -132,12 +143,14 @@ def main(): msg = "canary signify-openbsd verification timeout." print(msg, file=sys.stderr) process.kill() + process.wait() sys.exit(6) except BaseException: error_message = traceback.format_exc() msg = "canary signify-openbsd unknown error. Traceback:\n" + error_message print(msg, file=sys.stderr) process.kill() + process.wait() sys.exit(7) stdout, stderr = process.communicate(timeout=2)