about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2026-05-14 23:11:28 +0100
committerArun Isaac2026-05-17 23:10:17 +0100
commit3414bec6245100e809ce6a24a5a4095e8fcd51ef (patch)
treeea212ef5bd4c8061192a4ded1b5dfa21a0277384
parent0fbe115e3236b9263b8b714f2183e856ae6ae2f9 (diff)
downloadkaagum-3414bec6245100e809ce6a24a5a4095e8fcd51ef.tar.gz
kaagum-3414bec6245100e809ce6a24a5a4095e8fcd51ef.tar.lz
kaagum-3414bec6245100e809ce6a24a5a4095e8fcd51ef.zip
Read output from child in container before waiting for it to exit.
-rw-r--r--kaagum/container.scm31
1 files 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)))))))))))