There is an old paper[1] about using a malloc like interface
for stream IO. The idea is ReadAlloc(n) returns a buffer of
upto n bytes, filled with data from the underlying stream or
file. This allowed the implementation to use mmap for files
or buffer management for streams. On the next call the buffer
returned by the previous call was assumed to be no longer in
use by the client. There was even ReadRealloc() &
ReadAllocAt()! The latter to reposition the file or stream.
For writes, a buffer was returned. On the next WriteAlloc() it
would be accepted to be written out (this decoupled the client
from actual IO and yet avoided extra copying). Final blocking
close() would push out any remaining writes to the actual
connection or file.
What Ian proposes makes me think this is a similar model.
[1] I finally remembered one name + web search brought up this
paper: "Exploiting the Advantages of Mapped Files for Stream
I/O" by Krieger, Stumm & Unrau. I used it as a model to
implement some C++ classes at RealNetworks. I used nonblocking
io & a select loop underneath.