Commits

Peter Bex committed 803b02c

Fix run/port* so it doesn't replace the input port when in the REPL. Unfortunately, no test for it

  • Participants
  • Parent commits a87bd2e

Comments (0)

Files changed (2)

File scsh-process.scm

    ;; macros
    run/collecting run/string run/strings run/port run/file run/sexp run/sexps
    || &&
-   (& maybe-symbol->string) (run maybe-symbol->string) (exec-epf maybe-symbol->string))
+   (& run-final-thunk maybe-symbol->string)
+   (run maybe-symbol->string) (exec-epf maybe-symbol->string))
 
 (import chicken scheme data-structures)
 
 (define (fork/pipe #!optional thunk)
   (fork/pipe+ '((1 2 0)) thunk))
 
+;; Run a thunk and exit 0 after the thunk returns.
+;; If an exception occurs, handle it and exit 1.
+(define (run-final-thunk thunk)
+  (handle-exceptions exn
+    ;; TODO: Figure out how SCSH does this.  It shows the error
+    ;; on stderr in the REPL, but then still quits it.
+    ;; If we just invoke current-handler, it'll get a second REPL
+    (begin (print-error-message exn) (exit 1))
+    (thunk)
+    (exit 0)))
+
 (define (fork/pipe+ conns #!optional thunk)
   ;; Blergh, this is silly overhead we don't really need
   (let* ((from-fds (map (lambda (x) (drop-right x 1)) conns))
                       ;; Not needed anymore after duplication is complete.
                       (file-close (cadr p)))
                     pipe-pairs from-fds)
-          (if thunk (begin (thunk) (exit 0)) pid))
+          (if thunk (run-final-thunk thunk) pid))
         (begin                          ; Parent
           (for-each (lambda (p to-fd)
                       ;; Close sending end in parent.
     (apply values (fork/pipe+ conns thunk) temp-files)))
 
 (define (run/port* thunk)
-  (fork/pipe (lambda ()
-               (with-output-to-port (open-output-file* 1)
-                 (lambda ()
-                   (with-error-output-to-port (open-output-file* 2) thunk)))))
-  (open-input-file* 0))
+  (receive (in out)
+    (create-pipe)
+    (process-fork
+     (lambda ()
+       (run-final-thunk
+        (lambda ()
+          (file-close in)
+          (duplicate-fileno out 1)
+          (duplicate-fileno out 2)
+          (with-output-to-port (open-output-file* out)
+            (lambda ()
+              (with-error-output-to-port (open-output-file* out) thunk)))))))
+    (file-close out)
+    (open-input-file* in)))
+
 (define (run/file* thunk)
   (let* ((temp-file (create-temporary-file)))
     (process-wait                       ; This is peculiar
                       (lambda ()
                         (with-error-output-to-port (open-output-file* 2) thunk)))))))
     temp-file))
+
 (define (run/string* thunk)
   (read-string #f (run/port* thunk)))
 (define (run/strings* thunk)
   (syntax-rules ()
     ((_ ?epf ...)
      (process-fork (lambda ()
-                     (handle-exceptions exn
-                       ;; TODO: Figure out how SCSH does this.  It shows the error
-                       ;; on stderr in the REPL, but then still quits it.
-                       ;; If we just invoke current-handler, it'll get a second REPL
-                       (begin (print-error-message exn) (exit 1))
-                       (exec-epf ?epf ...)))))))
+                     (run-final-thunk (lambda () (exec-epf ?epf ...))))))))
 
 (define-syntax run
   (syntax-rules ()

File tests/run.scm

           '(a b c)
           (read (run/port (echo "(a b c)"))))
 
-    (test "Simple run/file"
-          "blah\n"
-          (with-input-from-file (run/file (echo "blah")) read-all)))
+    (let ((tmpfile (run/file (echo "blah"))))
+      (test "Simple run/file"
+            "blah\n"
+            (with-input-from-file tmpfile read-all))))
 
   (test-group "Subprocesses"
     (let ((outfile "outfile"))
           #f
           (|| (false) (epf (sh -c "echo hi && false") (- 1))))))
 
+;; TODO: Find a way to test that the input port didn't get replaced by
+;;       one from a subshell.  This happened before, but not sure how
+;;       to detect this except running it manually from the REPL.
+
 (test-exit)