[HN Gopher] TTY and Buffering
       ___________________________________________________________________
        
       TTY and Buffering
        
       Author : mattrighetti
       Score  : 36 points
       Date   : 2026-01-17 17:01 UTC (5 days ago)
        
 (HTM) web link (mattrighetti.com)
 (TXT) w3m dump (mattrighetti.com)
        
       | amelius wrote:
       | How would a modern OS implement this?
        
         | pocksuppet wrote:
         | Probably by not assuming terminals and byte streams any more.
         | Terminal-by-default is a 20th-century-ism. Now you have screens
         | with pixels. Without stdout, no need to know if stdout is a
         | terminal.
        
           | zbentley wrote:
           | This is an interesting idea--that in a reimagined OS,
           | programs could have their output connected to all sorts of
           | sinks (terminal, file, GUI, web content) without carrying
           | baggage related to those sinks' behaviors.
           | 
           | I think the core question is whether some middle layer of
           | output processing between program and sink/display could be
           | created that knows enough about (using terminals as an
           | example sink) raw mode/console dimensions/buffering to make
           | most programs display correctly enough for most users
           | _without_ knowing specifics about the program writing the
           | output 's internals. If that can be done, then programs that
           | need more specifics (e.g. complex animated/ncurses GUIs)
           | could either propose overrides/settings to the output
           | middleware or configure it directly, and programs that don't
           | wouldn't.
           | 
           | That's _possible_ to implement, sure, but can that be done
           | without just reinventing the POSIX terminal API, or any one
           | of the bad multiplatform-simple-GUI APIs, badly?
        
             | Joker_vD wrote:
             | > programs could have their output connected to all sorts
             | of sinks (terminal, file, GUI, web content) without
             | carrying baggage related to those sinks' behaviors.
             | 
             | We already have this. The TTY itself is not very special at
             | all. It's just that the applications, traditionally, decide
             | that they should special-case the writing to TTYs (because
             | those, presumably, are human-oriented and should have as
             | little batching as possible). But you, as an application
             | developer, can simply not do this, you know.
        
         | geocar wrote:
         | > How would a modern OS implement this?
         | 
         | fwrite only buffers because write is slow.
         | 
         | make it so write isn't slow and you don't need userspace
         | buffering!
        
         | Veserv wrote:
         | You do not need any OS changes, you just need a print library
         | that does buffering correctly.
         | 
         | Buffering should basically always be: "Work or Time" based,
         | either you buffered enough or enough time has passed. This is
         | because you buffer when per-element latency starts
         | bottlenecking your throughput.
         | 
         | If you have so little data that your throughput is not getting
         | limited, then you should be flushing.
        
       | nanolith wrote:
       | In libc, you can use setvbuf to change the buffering mode.
        
       | teddyh wrote:
       | > _Surprisingly, Rust, as of now, uses line buffering for both
       | TTYs and non-TTYs._
       | 
       | > _The FIXME comment shows the Rust team acknowledges that
       | ideally they should check if something is executed in TTYs or not
       | and use LineWriter or BufWriter accordingly, but I guess this was
       | not on their priority list._
       | 
       | This does not inspire confidence.
        
         | dwattttt wrote:
         | That's not forced behaviour. If you want to do something more
         | interesting, you'd use the raw/unsynchronised handles:
         | /// The returned handle has no external synchronization or
         | buffering layered on top.       const fn stdout_raw() ->
         | StdoutRaw;
        
       | lapsed_lisper wrote:
       | A while ago I stumbled across a technique for improving stream
       | buffering that I wish more I/O library implementors knew about.
       | Korn and Vo's sfio library (circa 1991) had a feature called
       | "pooling", whereby distinct streams could be linked together. Any
       | read or write operation to any stream in a pool implicitly
       | synchronized all the other streams in the pool first. This way,
       | when stdio and stderr were pooled, which was the default when
       | both went to ttys, a write on stderr implicitly flushed stdout.
       | I've implemented this feature for myself a couple times; it's
       | fairly easy to do and basically eliminates the need to explicitly
       | flush streams in client code.
       | 
       | Citation: https://archive.org/details/1991-proceedings-tech-
       | conference... but note that the explanation of stream pools there
       | is a little less precise and more general than really necessary.
       | I believe that later versions of sfio simplified things somewhat,
       | though I could be wrong. (I find their code fairly hard to read.)
       | 
       | Anyhow, ISTM a missed opportunity when new languages that don't
       | actually use libc's routines for something reinvent POSIX's
       | clunkier aspects.
        
       ___________________________________________________________________
       (page generated 2026-01-22 23:01 UTC)