anchor.diff: -#+xcvb (module (:depends-on ("macros" "process-spec")))
  +#+xcvb (module (:depends-on ("macros" "process-spec" "run-generic")))
   
   (in-package :inferior-shell)
  -
  -;; list of streams to close when finished
  -(defvar *streams-to-close* nil)
  -
  -(defun close-streams ()
  -  (mapcar #'close *streams-to-close*)
  -  (setq *streams-to-close* nil))
  -
  -;; interface to process a list of redirections and return redirected
  -;; input, output and error streams
  -(defun process-redirections (redirections input output error)
  -  (let ((r-input input)
  -        (r-output output)
  -        (r-error error))
  -    (loop :for r :in redirections
  -       :do (multiple-value-setq (r-input r-output r-error)
  -             (process-redirection r r-input r-output r-error)))
  -    (values r-input r-output r-error)))
  -
  -(defmethod process-redirection ((r file-redirection) input output error)
  -  (with-slots (fd pathname flags) r
  -    (let ((stream (apply #'open pathname :direction (car flags) (cdr flags))))
  -      (push stream *streams-to-close*)
  -      (ecase fd
  -        (0 (values stream output error))
  -        (1 (values input stream error))
  -        (2 (values input output stream))))))
  -
  -(defmethod process-redirection ((r fd-redirection) input output error)
  -  (with-slots (old-fd new-fd) r
  -    (ecase new-fd
  -      (1 (ecase old-fd
  -           (0 (values input input error))
  -           (2 (values input error :output))))
  -      (2 (ecase old-fd
  -           (0 (values input output input))
  -           (1 (values input output :output)))))))
  -
  -(defmethod process-redirection ((r close-redirection) input output error)
  -  (with-slots (old-fd) r
  -    (case old-fd
  -      (0 (values nil output error))
  -      (1 (values input nil error))
  -      (2 (values input output error))
  -      (otherwise (error "Can't close arbitrary fd: ~A" old-fd)))))
  -
  -(defclass result ()
  -  ((process
  -    :type sb-impl::process
  -    :initform nil :initarg :process :reader result-process)
  -   ;; thread slurping output
  -   (thread
  -    :type sb-thread:thread :initform nil
  -    :initarg :thread :reader result-thread)
  -   ;; predicate to determine whether to run the rest of the sequence
  -   ;; called with the process object, and expected to return t or nil
  -   (predicate
  -    :type (or function nil) :initform nil
  -    :initarg :predicate :accessor result-predicate)
  -   (rest
  -    :type list :initform nil
  -    :initarg :rest :accessor result-rest)
  -   (input
  -    :initform nil :initarg :input :accessor result-input)
  -   (output
  -    :initform nil :initarg :output :accessor result-output)
  -   (error
  -    :initform nil :initarg :error :accessor result-error)
  -   (resume
  -    :initform nil :initarg :resume :accessor result-resume)))
   
   (defmethod print-object ((result result) stream)
     (print-unreadable-object (result stream :type t)
       (with-slots (process predicate rest) result
         (format stream "~A ~A ~A" process predicate rest))))
   
  -(defun result-or (p)
  -  (not (zerop (sb-ext:process-exit-code p))))
  +(defmethod result-or ((r result))
  +  (not (zerop (sb-ext:process-exit-code (result-process r)))))
   
  -(defun result-and (p)
  -  (zerop (sb-ext:process-exit-code p)))
  +(defmethod result-and ((r result))
  +  (zerop (sb-ext:process-exit-code (result-process r))))
   
  -(defmethod sbcl-run-spec ((spec command-spec) input output error predicate rest resume)
  +(defmethod generic-run-spec ((spec command-spec) input output error predicate rest resume)
     (multiple-value-bind (r-input r-output r-error)
         (process-redirections (command-redirections spec) input output error)
       (labels ((run (out)
  
positive.code:              (let ((thread (result-thread r)))
                 (when thread
                   (sb-thread:join-thread thread)))))
      (let* ((first-results (sbcl-run-spec spec input output error nil nil nil))
             (full-results (alexandria:flatten (nconc first-results
                                                     (loop :for r :in first-results
                                                        :nconc (process-result-list r))))))
  
negative.code:       (if (or (not process)
                (eval-pred predicate rest))
            (let ((next (car rest)))
              (generic-run-spec next input output error predicate (cdr rest)
                                (if (typep next 'sequence-spec)
                                    r
                                    resume)))
            (when resume
              (with-slots (predicate rest resume input output error) resume
                (when (and (consp rest) (consp (cdr rest)))
                  (let ((remainder (cdr rest)))
                    (when (eval-pred predicate remainder)
                      (generic-run-spec (second rest) input output error
                                        predicate (cddr rest) resume))))))))))
  
  (defun process-result-list (rl)
    (if (listp rl)
  