1. 23

  2. 5

    Echoing: The client sends l and then immediately receives an l sent back. I guess the idea here is that the client is really dumb – it doesn’t know that when I type an l, I want an l to be echoed back to the screen. It has to be told explicitly by the server process to display it.

    Not just that it’s dumb, but also that it’s on a pretty low-latency link :-). The article doesn’t discuss this topic but it’s actually a pretty interesting historical artefact.

    You can have serial terminals echo things locally, too. You press l and the local terminal immediately writes an l, without waiting for the other end to tell it “now show an l”. If you’re on a high-latency link this is pretty useful, because sometimes it can take a long time for all this to go back and forth. It’s even more useful if you’re on a slow link with variable latency.

    But it also complicates a bunch of things. E.g. what if you’re on a link that’s not only slow but also a lossy – if you locally echo :wq! at vi‘s prompt, but the w didn’t make it, what do you do about it? It’s also pretty important to be able to switch it on and off on demand for some things, like typing passwords.

    1. 1

      if you locally echo :wq! at vi‘s prompt, but the w didn’t make it, what do you do about it?

      Did these dumb terminals have a mechanism that performs these types of comparisons to ensure data integrity? I.e. that the user input matches what the server received?

      1. 1

        No, that’s the point: they only echoed what the server sent back, and the server echoes back every input too

    2. 4

      The behavior of many of those keys can vary with different terminals too - backspace might send the byte 8 (same as ctrl+h… which is why ^H is sometimes used to mean backspace) instead of 127, the alt+key might also send code + 128 or a bitfield encoded as an escape sequence (try it with arrow keys for example… and arrow keys can send a variety of things).

      tbh the linux terminal is a nasty thing I wish would die, it is such a mess.

      I believe the reason cat gets interrupted when we press Ctrl+C is that the Linux kernel on the server side receives this \x03 character, recognizes that it means “interrupt”, and then sends a SIGINT to the process that owns the pseudoterminal’s process group. So it’s handled in the kernel and not in userspace.

      Yeah, there’s a function called tcsetattr which takes an array of mapping of keys to various actions you can set and modify to tell the kernel what to do. A fun thing to do is to change those to confuse people :P

      I wrote a whole terminal emulator suite from scratch (terminal emulator core: https://github.com/adamdruppe/arsd/blob/master/terminalemulator.d terminal client api (think ncurses, getline, etc): https://github.com/adamdruppe/arsd/blob/master/terminal.d and ui suites: https://github.com/adamdruppe/terminal-emulator ) so i had to deep dive into it all from a bunch of angles.

      This page is super useful if you want to get into more of the xterm features too https://invisible-island.net/xterm/ctlseqs/ctlseqs.html

      1. 1

        This a great introduction to a widely-used but poorly-understood set of systems!

        If you’re interested in another take, focusing on the kernel behaviors and interfaces here, I’ve written a three-part series exploring a bunch of related interfaces.