5

Racket has the nice read-bytes-async! function, which I believe exists in every other programming language in the world. It reads what it can from an input stream, without blocking, into a buffer, returning the number of bytes written.

Said function seems like an absolutely essential function for efficiently implementing, say, the Unix cat tool, yet Chicken Scheme seems to lack any such function. Of course, I can use (read-byte) and (write-byte), but that is slow and eats up all my CPU.

Even (copy-port) seems to not have any such implementation. Instead, before the stream is closed, the data is copied buffer-by-buffer only when the buffers fill. This means that (copy-port (current-input-port) (current-output-port)) does not behave like cat at all.

Am I just suffering from a terrible blind spot in reading the documentation, or does Chicken shockingly actually lack such a function? So cat can't even be written efficiently in Chicken?

ithisa
  • 752
  • 1
  • 8
  • 25
  • It could well be outdated, but [this mailing list post from 2005](http://comments.gmane.org/gmane.lisp.scheme.chicken/2075) mentions that "currently I/O from stdio and files is fully blocking." – Joshua Taylor Nov 01 '13 at 00:45
  • Anyways, I am deleting this question. The `posix` library has a low-level function that does what I want. The mailing list post indeed seems to be very outdated! – ithisa Nov 01 '13 at 01:06

2 Answers2

5

I fixed my problem. The posix library has the file-read function that does what I want, albeit on a file descriptor. Fortunately, ports in Chicken are just thin wrappers around file descriptors; there is a port to file descriptor converter in the posix library as well.

Interestingly, these functions work on Windows as well. posix seems to not be limited to POSIX systems.

ithisa
  • 752
  • 1
  • 8
  • 25
  • So this can be used to, for example, do a non-blocking read on STDIN? – Alexej Magura Apr 04 '14 at 02:35
  • 1
    It behaves like the Unix/most-other-langs read(). That is, wait until there is data available, and read the available data into the buffer, returning the length of data read. Chicken's default I/O does something bizarre: it waits until the entire buffer is full before returning. This makes implementing most `cat`-like programs impossible. – ithisa Apr 05 '14 at 22:58
  • I _recently_ figured out a way to do what you're describing using external C functions for file i/o: via Chicken's amazing C-interfacing abilities. – Alexej Magura Apr 23 '14 at 05:51
2

as you said the posix unit is the key ,but to your question what seems more relevant is set-buffering-mode!

this applies to any port.

ramrunner
  • 1,362
  • 10
  • 20
  • No, that is not related to what I want. I was meaning using my own buffer, not the port buffers. Even when the ports are buffered, doing the copy char-by-char is really slow. – ithisa Nov 02 '13 at 01:42
  • what if you used byte-blob-read from http://wiki.call-cc.org/eggref/4/byte-blob ? – ramrunner Nov 02 '13 at 07:10