Fixed a subtle bug in the macro for the << redirection: The port
opened by open-input-string could be closed by the GC before the exec(). Now << stores the port in a global variable. The test to reveal the bug was: (let lp () (run (head) (<< "a")) (lp)) printing a "closed channel" message after some a few hundred interations.
This commit is contained in:
parent
5e430feb5d
commit
64d35131f3
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
|
|
Loading…
Reference in New Issue