> This is not entirely true. flisten() checks the buffer of the FILE
> structure whenever possible. This is done at least in linux, *bsd and
> possibly other ports.
Yes, that's true.
> > More generally, the lack of non-blocking io with FILE *s may cause
> > problems for future coroutine or cooperative task based IO, etc.
> Hmm, could you elaborate a little bit more on this? Streams provide
> atomic read/write operations even in multithreaded environments.
Well, if you have coroutines, then you'd ideally want to be able to
decide to yield (to a scheduler, or your consumer coroutine, etc) when
you need to wait for an io operation to finish.
You can see CMUCL's serve-event mechanism as a primitive example of
this, without proper coroutine support.
Since FILE *'s don't have non-blocking io, you can't implement any of
this on top of them, either efficiently or portably.
> > So my question is: Is there significant value in using FILE * based io
> > rather than directly using file descriptors/handles/etc?
> Streams are rather portable, they provide buffering, they are available
> everywhere and the code was already there. Code reusing is a nice thing,
> specially if you want to keep ECL small. Besides that, ANSI CL does not
> provide non-blocking read/write operations.
It's true that FILE *'s are convenient in the simplest cases, but I'm
not sure that adding select at the read-char-no-hang level makes it
There are two non-blocking io operations in ANSI CL that I'm aware of:
read-char-no-hang, and listen.
These can be implemented with the current workaround, using select and
non-portable FILE inspection hack, but not very efficiently.
Once you start using :external-format in conjunction with these, it
becomes more difficult, since you can't guarantee that being able to
produce a single byte will allow you to produce a whole character.
Also, it would be nice to be able to have an efficient read-sequence-no-han=