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.
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?
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
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.
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 anl
, without waiting for the other end to tell it “now show anl
”. 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!
atvi
‘s prompt, but thew
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.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?
No, that’s the point: they only echoed what the server sent back, and the server echoes back every input too
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.
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 :PI 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
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.