From 3414bec6245100e809ce6a24a5a4095e8fcd51ef Mon Sep 17 00:00:00 2001 From: Arun Isaac Date: Thu, 14 May 2026 23:11:28 +0100 Subject: Read output from child in container before waiting for it to exit. --- kaagum/container.scm | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/kaagum/container.scm b/kaagum/container.scm index f0a0c04..ba90aa9 100644 --- a/kaagum/container.scm +++ b/kaagum/container.scm @@ -35,16 +35,21 @@ (lambda (root) (match (pipe) ((in . out) - (match (waitpid (run-container root mounts namespaces 1 - (lambda () - (close-port in) - (with-output-to-port out - ;; TODO: Capture stderr too. - thunk) - (close-port out)))) - ((_ . status) - (close-port out) - (let ((result (get-string-all in))) - (close-port in) - (container-result result - (status:exit-val status)))))))))) + (let ((child-pid (run-container root mounts namespaces 1 + (lambda () + (close-port in) + (with-output-to-port out + ;; TODO: Capture stderr too. + thunk) + (close-port out))))) + (close-port out) + ;; We read the child's output and then wait for the child to exit. It + ;; is important to do it in this order. If we first wait for the child + ;; to exit, the pipe buffer could fill up and the child's writes could + ;; be blocked; we'd have a deadlock. + (let ((result (get-string-all in))) + (close-port in) + (container-result result + (match (waitpid child-pid) + ((_ . status) + (status:exit-val status))))))))))) -- cgit 1.4.1