FWIW, for CMUCL whole story looks like this (from memory, so take this with a grain of salt) -- SBCL does the same, unsurprisingly.
There are streams *STDIN*, *STDOUT*, *STDERR*, and *TTY*. If /dev/tty cannot be opened, *TTY* is simply
(make-two-way-stream *stdin* *stdout*)
*STANDARD-INPUT*, *STANDARD-OUTPUT*, and *ERROR-OUTPUT* start out as synonym streams for *STDIN*, *STDOUT*, *STDERR*.
*TERMINAL-IO*, *QUERY-IO* and *DEBUG-IO* start out as synonym streams for *TTY*.
Neither two-way-streams nor synonym streams get buffering of their own: anything written to them is immediately written to the underlying stream.
It's not a perfect setup, but it's not half bad, IMO.
Cheers,
-- nikodemus