sbclのrun-processで、process-outputが読めなくなる

(defun read-all (output-stream)
  (if (null output-stream) ""
      (with-output-to-string (lines)
        (awhile (read-line output-stream nil nil)
                (format lines "~a~%" it)))))

(defun execute (command &key (wait t))
  (destructuring-bind (program &rest args) (kmrcl:delimited-string-to-list command)
    (let ((process (run-program program args :output :stream :wait wait)))
      (if wait
          (let ((out (process-output process))
                (error (process-error process))
                (exit-code (process-exit-code process)))
            (values (read-all out) (read-all error) exit-code))
          process))))

(dotimes (i 1025)
  (princ (execute "/bin/date +DATE:%m/%d/%y%nTIME:%H:%M:%S"))
  (sleep 0.02))
  • たとえばこんな風にしてたらエラーになって落ちた。
The value 1025 is not of type (MOD 1025).
   [Condition of type TYPE-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [ABORT] Return to SLIME's top level.
 2: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: (SB-IMPL::SYSREAD-MAY-BLOCK-P #<SB-SYS:FD-STREAM for "descriptor 1024" {1002FEFE61}>)
  1: (SB-IMPL::REFILL-INPUT-BUFFER #<SB-SYS:FD-STREAM for "descriptor 1024" {1002FEFE61}>)
  2: (SB-IMPL::INPUT-CHAR/UTF-8 #<SB-SYS:FD-STREAM for "descriptor 1024" {1002FEFE61}> NIL NIL)
  3: (READ-LINE #<SB-SYS:FD-STREAM for "descriptor 1024" {1002FEFE61}> NIL NIL #<unused argument>)
  4: (READ-ALL #<SB-SYS:FD-STREAM for "descriptor 1024" {1002FEFE61}>)
  5: (EXECUTE "/bin/date +DATE:%m/%d/%y%nTIME:%H:%M:%S" :WAIT T)
  • ProcessはGCに回収されるときにcloseされるのかと思ったがされないみたい。
  • 参照が消えてしまったprocessをcloseするのは無理なので、sbcl再起動してexecuteを必ずcloseするようにして解決した。
(defun execute (command &key (wait t))
  (destructuring-bind (program &rest args) (kmrcl:delimited-string-to-list command)
    (let ((process (run-program program args :output :stream :wait wait)))
      (if wait
          (let ((out (process-output process))
                (error (process-error process))
                (exit-code (process-exit-code process)))
            (unwind-protect (values (read-all out) (read-all error) exit-code)
              (process-close process)))
          process))))
  • waitしない場合は、外で必ずcloseするよう気をつけてね!