diff --git a/scsh/syntax-helpers.scm b/scsh/syntax-helpers.scm index 71efd6a..163aa25 100644 --- a/scsh/syntax-helpers.scm +++ b/scsh/syntax-helpers.scm @@ -167,6 +167,10 @@ (%q (lambda (x) (list (rename 'quote) x))) (%close (rename 'close)) (%move->fdes (rename 'move->fdes)) + (%set! (rename 'set!)) + (%<<-port-holder (rename '<<-port-holder)) + (%let (rename 'let)) + (%port (rename 'port)) (%stdports->stdio (rename 'stdports->stdio))) (cond ((pair? redir) (let ((args (cdr redir))) @@ -184,9 +188,13 @@ ; (receive (fdes epf) (parse-spec args 0) ; `(,%dup-port (,%run/port . ,epf) ,fdes))) ; Add a WITH-PORT. + ;; We save the port in the global variable <<-port-holder to prevent a + ;; GC from closing the port before the exec(). ((<<) (receive (fdes exp) (parse-spec args 0) - `(,%move->fdes (,%open-string-source ,exp) ,fdes))) + `(,%let ((,%port (,%open-string-source ,exp))) + (,%set! ,%<<-port-holder ,%port) + (,%move->fdes ,%port ,fdes)))) ((>>) (receive (fdes fname) (parse-spec args 1) diff --git a/scsh/syntax.scm b/scsh/syntax.scm index 8d2e0c5..4ff7ccc 100644 --- a/scsh/syntax.scm +++ b/scsh/syntax.scm @@ -10,6 +10,10 @@ ;;; The three basic forms for running an extended process form: ;;; EXEC-EPF, &, and RUN. EXEC-EPF is the foundation. +;; This is used by the macro for the << redirection to prevent the temporary +;; port from being closed by a GC before the process exec's +(define <<-port-holder) + (define-syntax exec-epf (lambda (form rename compare) (transcribe-extended-process-form (cdr form) rename compare)))