[racket] fun with ports and (system ..) calls

From: David Vanderson (david.vanderson at gmail.com)
Date: Wed Oct 16 13:36:25 EDT 2013

On 10/16/2013 12:35 PM, Vlad Kozin wrote:
> assuming I have a number of .c files I expect "find" to write corresponding lines to (current-output-port). I want to collect them in a list. Here's a solution I thought would work:
> ------------------------------------
> (define-values (in out) (make-pipe))
> (parameterize ((current-output-port out))
>    (system (format "find . ~a ~a" "-name \"*.c\"" "-print"))
>    (for/list ((line (in-lines in)))
>      line))
>
> It doesn't. It blocks expecting input.
>
> Blocks again. Am I not getting EOF here?
>
I think you are on the right track here.  You need to close the output 
port on the pipe so "in-lines" stops reading:

(define-values (in out) (make-pipe))
(parameterize ((current-output-port out))
   (system (format "find . ~a ~a" "-name \"*.c\"" "-print"))
   (close-output-port (current-output-port))
   (for/list ((line (in-lines in)))
     line))

Does that make sense?

Alternatively you can rearrange your last example:

(define str (with-output-to-string
                (lambda ()
                  (system (format "find . ~a ~a" "-name \"*.c\"" 
"-print")))))
(for/list ((line (in-lines (open-input-string str))))
   line)

Thanks,
Dave

Posted on the users mailing list.