From d89afdc4a503767aeba3f4c25a202883b831e9ed Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sun, 16 Aug 2026 07:02:54 +0200 Subject: [PATCH] lib.ec.ssh.Paramiko: Avoid recv deadlock _run_ssh() waits for the remote process's exit status before reading stdout and stderr. When a command produces more output than the channel's flow-control window can hold, the server stops sending, the remote process blocks on its write and never exits, and recv_exit_status() blocks forever. Drain stdout and stderr to EOF first - the channels close when the process exits, so reading them also implies completion - and only then query the exit status. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2 Signed-off-by: Jan Lindemann --- src/python/jw/pkg/lib/ec/ssh/Paramiko.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/python/jw/pkg/lib/ec/ssh/Paramiko.py b/src/python/jw/pkg/lib/ec/ssh/Paramiko.py index b85b20f4..d1171d6f 100644 --- a/src/python/jw/pkg/lib/ec/ssh/Paramiko.py +++ b/src/python/jw/pkg/lib/ec/ssh/Paramiko.py @@ -95,5 +95,7 @@ class Paramiko(Base): if cmd_input is not None: stdin.write(cmd_input) stdin.channel.shutdown_write() + stdout_data = stdout.read() + stderr_data = stderr.read() exit_status = stdout.channel.recv_exit_status() - return Result(stdout.read(), stderr.read(), exit_status, cmd = cmd) + return Result(stdout_data, stderr_data, exit_status, cmd = cmd)