On 15 June 2012 01:10, Johan Hidding <johannes.hidd...@gmail.com> wrote:
> (use-modules (ice-9 popen))
>
> (display (with-output-to-string (lambda ()
>           (let ((P (open-pipe "cat" OPEN_WRITE)))
>             (display "Hello World!\n" P)
>             (close-pipe P)))))
>
> to output: Hello World!
> But it gives me nothing, using guile-2.0.5. What's going wrong? I
> would love to see some examples on how pipes are "supposed to be"
> used.
> Cheers, Johan
>

Hello

There is some difficulty using pipes in this way.  If you want to
capture the output to a string use an input-output pipe.  The trick is
to use force-output after writing to the port so that the program has
definitely received the input:

(use-modules (ice-9 popen))
(use-modules (ice-9 rdelim))
(let ((p (open-pipe "cat" OPEN_BOTH)))
  (display "Hello\n" p)
  (force-output p)
  (read-line p))
=> "Hello"

For some programs (such as sed, gzip) they buffer their input and
often wait until EOF.  In this case you must write all the data and
then close the port before you can read anything back.  The open-pipe
procedures are not good at this, because you can not close just one
side of the port object they return.

Instead, use run-with-pipe (from guile-lib's (os process) module).
The basic pattern is like this:

(use-modules (os process))
(let ((p (cdr (run-with-pipe "r+" "cat"))))
  (display "Hello\n" (cdr p))
  (force-output (cdr p))
  (close-port (cdr p)) ;; important if "cat" waits for EOF
  (read-line (car p))
  (close-port (car p)))
=> "Hello"

Note that p is a pair of pipes.  The procedure run-with-pipe also
returns the process id, but the above code discards it.

Regards

Reply via email to