[HN Gopher] The history of Unix's ioctl and signal about window ...
       ___________________________________________________________________
        
       The history of Unix's ioctl and signal about window sizes
        
       Author : ingve
       Score  : 103 points
       Date   : 2024-11-04 07:39 UTC (15 hours ago)
        
 (HTM) web link (utcc.utoronto.ca)
 (TXT) w3m dump (utcc.utoronto.ca)
        
       | clausecker wrote:
       | I submitted the proposal for `tcgetwinsize` to POSIX a few years
       | ago. I originally wrote it because I was sick of having to turn
       | off _POSIX_C_SOURCE for just a single file to get glibc to expose
       | TIOCGWINSZ.
       | 
       | SIGWINCH and the TIOCGWINSZ ioctl() were originally omitted from
       | POSIX as they were considered relevant for windowing systems only
       | and GUI-stuff was considered out of scope for POSIX. Furthermore,
       | POSIX only specifies ioctl() for STREAMS; other interfaces that
       | traditionally use ioctl() calls are specified in POSIX using
       | wrapper functions (which is what the new interface is; it is
       | specified such that you can implement it just by wrapping the
       | traditional TIOCGWINSZ/TIOCSWINSZ ioctl calls).
       | 
       | My original proposal had functions tcgetsize() and tcsetsize(),
       | but it turns out that QNX already uses these identifiers with an
       | incompatible signature, so a last minute change was made to name
       | these tcgetwinsize() and tcsetwinsize().
       | 
       | Furthermore, the winsize structure traditionally also has
       | ws_xpixel and ws_ypixel members indicating the resolution of the
       | terminal. This existed primarily becaus on some historical
       | virtual terminals, a client could change the video mode by
       | calling the TIOCSWINSZ ioctl, providing resolution and row/column
       | count for the desired video mode. While no current virtual
       | terminal known to me supports this, the POSIX spec mandates that
       | if a slave PTY calls tcsetwinsize(), the window size update is
       | propagated to the master, allowing terminal emulators to
       | implement this feature if desired. Another objection raised was
       | that the traditional unsigned short type may be insufficient for
       | future high-definition screens and a resolution may not be well
       | defined for some types of terminals like hardcopy or braille
       | terminals.
       | 
       | I maintain that submitting a feature to POSIX and waiting for a
       | new version of the standard to be released is probably the
       | easiest way to get glibc to implement a feature you want.
        
         | aumerle wrote:
         | Lots of modern terminals support ws_xpixel and ws_ypixel. Hell
         | even the venerable xterm supports it. It is used primarily for
         | displaying raster graphics in modern terminals, see for
         | example: https://sw.kovidgoyal.net/kitty/graphics-
         | protocol/#getting-t...
         | 
         | And nowadays modern terminals even support in-band resize
         | notification so there is no need for SIGWINCH:
         | https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3...
        
           | clausecker wrote:
           | My point was not that the terminals don't report ws_xpixel
           | and ws_ypixel, but rather that none support the application
           | setting the resolution using tcsetwinsize() with the terminal
           | subsequently changing its video mode / resizing itself to the
           | requested size.
        
             | aumerle wrote:
             | Ah yes, in that case there no terminals that implement it
             | indeed. Though there are a few that implement changing
             | window size via escape code, though in units of cells not
             | pixels. Generally speaking I dont see how applications can
             | use tcsetwinsize() robustly, given that the size in pixels
             | of a cell is determined by font properties and applications
             | runing in the terminal have no knowledge of these,
             | therefore cannot set both the pixel and cell sizes at the
             | same time.
        
               | clausecker wrote:
               | Correct, that was one of the concerns. Note that
               | tcsetwinsize() is mainly provided so that the pty master
               | (i.e. the terminal emulator) can set the window size to
               | be seen by the slave (i.e. the application running in the
               | emulated terminal). The other direction is not explicitly
               | banned though.
        
               | j4_james wrote:
               | FYI, there are a few terminals that can set the window
               | size in pixels (with `CSI 4 t`). And it's also worth
               | mentioning that there were already terminal emulators
               | back in the 1980s that supported in-band resize
               | notifications (lookup `VTEEWR` - Enable Window Event
               | Reports).
        
         | high_na_euv wrote:
         | >tcgetwinsize
         | 
         | >_POSIX_C_SOURCE
         | 
         | >TIOCGWINSZ
         | 
         | >SIGWINCH
         | 
         | >TIOCSWINSZ
         | 
         | Jesus christ, this whole fashion among the C and linux people
         | focused on writing shorter, but unreadable names is really
         | terrible habbit
        
           | wwalexander wrote:
           | I believe this stems from C originally only having 8
           | significant characters for identifiers.
        
             | cesarb wrote:
             | Not only that, but screen space was really limited back
             | then; it was not uncommon to develop on terminals with as
             | low as 80 columns and 24 lines. Having shorter names meant
             | more of the code could fit on the screen at the same time.
        
               | rbanffy wrote:
               | The limited size helps with keeping the code short and
               | simple. ;-)
        
               | kps wrote:
               | Historically there was a bifurcation between
               | scientific/technical computing and business computing.
               | The former wanted to write something close to _E_ = _mc_
               | 2, while the latter wanted `MULTIPLY MASS-IN-GRAMS TIMES
               | SPEED-OF-LIGHT-IN-A-VACUUM-IN-METERS-PER-SECOND TIMES
               | SPEED-OF-LIGHT-IN-A-VACUUM-IN-METERS-PER-SECOND GIVING
               | ENERGY-IN-JOULES`. With the dotcom boom, the last
               | vestiges of the old republic were finally swept away, and
               | now even C programmers get slapped for writing `c`.
        
               | marssaxman wrote:
               | I still develop on a terminal with 80 columns, to this
               | day!
               | 
               | ...but it has 96 rows, and there are five of them, side
               | by side across my monitor. Definitely an improvement! -
               | but I still prefer not to have long rambling Java-style
               | identifiers.
        
             | high_na_euv wrote:
             | Majority of those above are above 8 char length.
        
             | winocm wrote:
             | Here's a fun link:
             | https://stackoverflow.com/questions/38035628/c-why-did-
             | ansi-...
        
             | layer8 wrote:
             | That's only for external identifiers (the one the linker
             | sees), and it's only six characters. This limit comes from
             | FORTRAN, and in turn comes from the world of 36-bit word
             | mainframes. Those machines didn't have bytes, only words.
             | Words could represent numbers, or up to 6 characters (in a
             | 6-bit character set, no lowercase letters).
             | 
             | Internal identifiers and macro names had a lower limit of
             | 31 significant characters in C.
             | 
             | The more relevant original reason for short identifiers is
             | that code completion wasn't a thing, and to a lesser extent
             | that screens were at most 80 characters wide.
        
       | ape4 wrote:
       | I like this old Unix history stuff
        
       | TOGoS wrote:
       | Okay, but why is it a signal at all? In the end, isn't it just
       | escape sequences sent back and forth in-band? Wouldn't it be
       | simpler to just let the program read and write those rather than
       | involving a separate system call?
        
         | clausecker wrote:
         | A signal means that the application can immediately redraw its
         | UI to the new dimension even if it is not currently reading
         | input.
         | 
         | Also, if the size was reported in-band, it would mess up
         | applications that are not aware of that in-band signalling.
        
         | thatcks wrote:
         | My understanding is that the original SunOS windowing system
         | was deeply connected to the kernel (for instance, windows were
         | devices). The original purpose of the signal (in SunOS) appears
         | to have been telling graphical programs that their window had
         | 'changed' and needed to be repainted (I don't know if this was
         | simply from resizing or if it was any damage), which makes a
         | certain amount of sense for a kernel based windowing system
         | (the kernel is right there and you need some way to notify
         | programs). The use of the signal for telling programs in
         | terminal windows that the window had resized appears to have
         | been distinctly secondary, and only the latter can interact
         | with their window through in-band escape sequences.
         | 
         | (I'm the author of the linked-to article.)
        
         | rockorager wrote:
         | Exactly - these should be reported along with any other input
         | event as an escape sequence. There are other comments on this
         | post that link to how this is done.
        
       | kevin_thibedeau wrote:
       | You don't have to use the ioctl. The xterm escape code to query
       | window size is widely supported across terminal emulators. It has
       | the distinct advantage of working remotely and from non-unix
       | systems.
        
         | rockorager wrote:
         | The single downside being you can get signals for SIGWINCH,
         | while the (legacy) xterm escape sequence requires polling.
         | 
         | I wrote a proposal[0] to have terminals send these updates in-
         | band, instead of requiring polling a-la xterm. So far, foot,
         | ghostty, iterm2, and kitty have implemented this feature on the
         | terminal side. Neovim, notably, also supports this on the
         | client side.
         | 
         | [0]:
         | https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3...
        
           | clausecker wrote:
           | This stuff sucks because if the application forgets to turn
           | it back off, the terminal pukes random control characters
           | into your shell every time the window is resized.
        
             | mrlonglong wrote:
             | That's what `reset` is so useful for.
        
       | klysm wrote:
       | Terminals, ttys, etc. have some of the most arcane and outdated
       | APIs I am aware of. It's like a window back into the 1970s
        
         | ggm wrote:
         | The window part is 1980s. the window back is deeper than the
         | 70s, because the termcap/terminfo specs go into Teletype ASR33
         | territory which is 70s implementations of a core technology
         | from the Baudot code era.
        
           | rbanffy wrote:
           | I believe terminals in the late 70 already could change their
           | geometries. The VT100 could go from 80 to 132 columns.
        
             | samatman wrote:
             | Controlled with DECCOLM, mode ?3. Curious how many
             | terminals besides xterm choose to support that one.
        
               | kps wrote:
               | Most 'xterm-compatible' or 'vt102-compatible' terminals
               | do, though at least one handles it wrong.
        
               | rbanffy wrote:
               | I have an IBM 3151 (the late model, made by ADDS - pretty
               | much all late-gen terminals are ADDS) that does.
               | 
               | Reminds me I need to bring it here.
        
         | wpm wrote:
         | It's one of the reasons I love them. A ball of insane,
         | esoteric, baffling, confusing cruft, layered in a century long
         | onion, with connections to the very basics of
         | telecommunications. At any moment, both the simplest interface
         | and the most complex, both the beautiful speckled black void of
         | the night sky, and the horrific gaping maw of a Lovecraftian
         | beast.
        
       | amelius wrote:
       | How do you constrain the window size of a terminal?
        
       | ggm wrote:
       | Signal handling demands constraints in how much you do. I never
       | enjoyed coding to unix signals, I always wound up finding a new
       | way to trample on that state you assume is clean, but inside the
       | sig handler it turns out things are not what you think sometimes.
       | The manual page used to be pretty explicit: do as little as
       | humanly possible inside this execution context.
       | 
       | I am probably mis-remembering but my memory is getting a signal
       | while handling another signal was a point of pain.
        
       | amiga386 wrote:
       | For anybody wondering "why couldn't they just...", there is a lot
       | of complexity in TTYs and PTYs. The kernel is even involved in
       | line discipline and job control. Those Ctrl+Z or Ctrl+C keys you
       | press? The kernel gets involved.
       | 
       | It may seem strange that there's a process signal for window-size
       | changes, but that's what was needed back in 1985. There's a
       | similar dance with the Amiga's console.device, but both Unix and
       | Amiga TTYs are better than Windows' terminals where there was no
       | such thing as a PTY until Windows 10, you had to make direct API
       | calls, and even now it's still pretty slow:
       | https://devblogs.microsoft.com/commandline/windows-command-l...
       | 
       | This page is a great overview pf the Unix TTY/PTY subsystem:
       | https://www.linusakesson.net/programming/tty/
        
       | rbanffy wrote:
       | I have conflicting feelings abou This. The OS should not be
       | concerned by this kind of thing. This is completely in the realm
       | of the shell and many physical could change the number of rows or
       | columns either on user command via its settings or through the
       | host sending an equivalent command.
       | 
       | This does not belong into a kernel.
        
         | akira2501 wrote:
         | It's just a driver. Do you feel the same about pipe(4)? As
         | effectively that's mostly what PTYs have become.
        
           | rbanffy wrote:
           | The kernel should never need to concern itself with the
           | nature of what is sending or receiving a stream of bytes.
        
       ___________________________________________________________________
       (page generated 2024-11-04 23:01 UTC)