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
?
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!