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:
mainzelm 2002-09-12 07:30:30 +00:00
parent 5e430feb5d
commit 64d35131f3
2 changed files with 13 additions and 1 deletions

View File

@ -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)

View File

@ -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)))