Search code examples
ioschemeposixchicken-scheme

Connecting to interactive tools using Chicken Scheme's `process`?


I am trying to figure out Chicken Scheme's process procedure.

When I run it in the interpreter, this example code does what I expect (prints out "Hello, world!"):

(use posix)

(let-values (((in out pid) (process "echo \"Hello, world!\"")))
  (print (read-line in)))

Based on this, my expectation is that if I echo \"Hello, world!\" with bc I should see the first line of bc's usual preamble:

bc 1.06

Instead, I get a blank line, and I don't get the interpreter's prompt back again until I hit Ctrl-C.

Or, sometimes I get this error:

thread is registered for I/O on unknown file-descriptor: 33 (expected 31)
[]
...more...
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<syntax>
<eval>
<eval>
<eval>
<eval>
<eval>  <--

and I get kicked back out to my shell prompt.

Additionally, how do I get the process I have started to respond to input? I expect the following to print 4, but instead get a blank line again:

(let-values (((in out pid) (process "bc")))
  (begin
    (display "2 + 2" out)
    (print (read-line in))))

(How) can I use process to have an interactive dialog with a tool like bc?


Solution

  • There are several components to this question. The first you already figured out: bc will detect it's not running on a terminal so it won't print the banner.

    The second is simple line buffering: In UNIX, simply printing to a port will not actually send out any data, unless you explicitly flush or send a newline. In CHICKEN, this can be done either by calling flush-output on the desired port, or appending a newline to the display call. I think bc will read until it sees a newline anyway, so flushing is not likely to help here. So either call newline on the port, or use (display "2 + 2\n" out) instead of (display "2 + 2" out).

    The third is an actual bug: the error you get about an unexpected file descriptor. I've filed a bug report for that, thanks for pointing it out!