[plt-scheme] Examples of subprocess use, for expect-like dialogs?

From: Andrew Reilly (andrew-scheme at areilly.bpc-users.org)
Date: Wed Aug 5 21:03:14 EDT 2009

Hi Matthew,

Thanks for the feedback!

On Tue, Aug 04, 2009 at 03:29:17AM -0600, Matthew Flatt wrote:
> On my machine, `cat -n' doesn't respond immediately unless the output
> is a terminal. `cat -n -u' responds immediately (but then the example
> gets stuck in the loop, since no result line is ever "EOM").

Hmm.  So it does.  I had to write a script to cat -n to a file,
and watch that with tail -f to see it happening.  I doubt that
the command-line interface to the program that I'm using does
that kind of "special" processing, unless it's something in the
C library that defaults that way... (which it does: see below)

> Beware, also, that if the multi-line string is much larger, then your
> example can get stuck due to the buffers between the processes. If you
> send a lot of text to `cat' without reading its output, then eventually
> `cat' will block writing output until your program reads some of it. If
> your program keeps writing, meanwhile, then it will eventually get
> stuck for the same reason, since `cat' is stuck and not reading the
> data that you're sending it.

I figured that one out, by putting the send part of my
send/receive function into a thread:

(define/contract (send-receive cmd receiver)
  (-> string? (-> any/c) any/c)
  (erlog "> " cmd)
  (let ((thr (thread (lambda () (display cmd) (newline) (flush-output)))))
      (thread-wait thr))))

That's pretty cool, I think.  The least effort I've ever
expended to make something useful happen in a thread!

Your comment about "cat -n" having different behaviour reminded
me that I'd read something along those lines as part of the
normal C stdio library.  On the Unix systems that I use, it does
a similar thing by default: line buffered to console, but block
buffered otherwise.  Since I have the source for the application
I'm talking to, I inserted a fflush(stdout) at the end of the
while(fgets(...)) loop and now everything works beautifully!



Posted on the users mailing list.