anchor.diff:    (with-slots (cmd-prefix cmd-word cmd-name cmd-suffix) sy
       (multiple-value-bind (assignments arguments redirects) (simple-command-parts sy)
         (format *standard-output* "EXEC: ~A ~A ~A~%" assignments arguments redirects)
  -      (shadow-fd-bindings
  +      (with-fd-scope ()
           (dolist (r redirects)
             (handle-redirect r))
  -        (let ((pid (fork-exec (coerce (mapcar 'token-value arguments) 'vector) :fd-map *fd-bindings* :managed-fds *managed-fds*)))
  +        (let ((pid (run (coerce (mapcar 'token-value arguments) 'vector) :fd-alist (reverse *fd-bindings*) :managed-fds (autoclosed-fds))))
             (process-from-pid pid))))))
   
   (define-condition not-a-thunk (warning)
  
positive.code:                              (open-args-for-redirect redirect)
                               *umask*)))
        (format *error-output* "OPEN ~A = ~A~%" fd filename)
        (fd-is-managed fd)
        (values fd t))))
  (defmethod fd-from-description ((fd fd-wrapper))
    (values (slot-value fd 'fd) nil))
  
  (defun bind-fd (fd description)
    (multiple-value-bind (from-fd needs-close) (fd-from-description description)
      (setf (gethash fd *fd-bindings*) from-fd)
      (when needs-close
        (push from-fd *fds-to-close-for-shadow*))))
  
  (define-condition invalid-fd (error)
    ((fd
  
negative.code: (defun process-from-pid (pid)
    (make-instance 'process :pid pid))
  
  (defclass pipeline-thunk (eval-thunk)
    ((processes
      :initarg :processes
      :initform (required)
      :accessor pipeline-thunk-processes
      :type vector)))
  
  (defun separator-par-p (separator)
    (check-type separator separator)
    (with-slots (separator-op) separator
      (when (slot-boundp separator 'separator-op)
        (typep separator-op 'par))))
  
  (defgeneric open-args-for-redirect (redirect))
  (defmethod open-args-for-redirect ((r less))
  