fix is attached test code: (use-modules (ice-9 ftw)) (use-modules (ice-9 popen)) (define (print-open) (format #t "~a\n" (length (scandir "/proc/self/fd")))) (let ((p (%make-void-port "rw"))) (print-open) (parameterize ((current-output-port p) (current-input-port p) (current-error-port p)) (system* "ls")) (close-port p) (print-open)) (parameterize ((current-error-port (%make-void-port OPEN_BOTH))) (while #t (close-pipe (open-pipe* OPEN_READ "free")) (print-open) (sleep 1))) there's still a one-time increase in the file descriptors, but it seems unrelated. or at least much harder to find. (by the way, ignoring current-output-port and using /dev/null is bad. it would be nice to open a pipe in that case and forward whatever the child writes to the scheme port. but that would require a separate thread, and it may be impossible to do something like that for current-input-port)