Piping between Common Lisp and external command line

With the external-program package, I can code to call an external command line program easily. For example:

(external-program:run "ls" '("-l") :output *standard-output*)

What if I want to keep streaming (piping) input and reading output. (1) instead of run, I use start.

(setf *x* (external-program:start "cat" '() :output :stream :input :stream))

(2) I create a thread for reading the output and print it. Bordeaux-threads API looks quite similar to POSIX.

(setf *read-thread*
       (lambda ()
     (loop for line = (read-line (external-program:process-output-stream *x*) nil)
           while line
           do (format t "OUT: ~A~%" line)))
       :name "titi"))

(3) I get an output stream for passing data to the external program.

(setf *out* (external-program:process-input-stream *x*))

(4) I write something to out and flash it.

  (loop for i from 1 to 10
    do (format *out* "!!! ~A~%" i))
  (force-output *out*))

At this step, you should see some output from the (2) step, which are:

OUT: !!! 1
OUT: !!! 2
OUT: !!! 10

You can keep playing with it.

(5) And finally I clean everything up.

(close *out*)
(bordeaux-threads:join-thread *read-thread*)