
The TTY demystified (2008) - Ivoah
http://www.linusakesson.net/programming/tty/
======
CaliforniaKarl
One of the most important commands I learned was "reset", especially when I
was working with _anything_ that would want to do something special. From the
man page:

"When invoked as reset, tset sets cooked and echo modes, turns off and raw
modes, turns on newline translation and resets any unset characters to their
default values before doing the terminal described above. This is useful after
a program dies a terminal in an abnormal state."

Except, it is also useful when you exit something like a Serial-Over-LAN
session, after watching the BIOS do inappropriate things to your terminal
window.

~~~
jclulow
If the SOL client is leaving the terminal in that state, it's almost certainly
broken. The only time it's acceptable not to clean up after yourself is if you
literally can't, because you've been whacked with a signal you can't handle
(SIGKILL); or because you've _tried_ to clean up and for some reason the
correct sequence of restoration calls has failed for some unknown operational
reason.

~~~
MaulingMonkey
Some edge cases:

\- cat /dev/urandom (cat can't reasonably tell if you've piped to another
command that expects raw binary data or a terminal that expects to be left in
a sane state)

\- ssh remotehost cat /dev/urandom (ditto)

\- Emergency exit to avoid data loss when detecting e.g. memory corruption
(lesser evil)

\- Hardware bugs/failures erroneously emitting escape codes (memory bit flips,
loose RS-232 connections)

You're of course correct that the vastly preferred thing to do when practical
is to clean up when reasonable to do so - and it's probably reasonable to do
so.

~~~
sdkmvx
cat could tell but it probably wouldn't be a good design. Calling isatty is
easy, and I think GNU cat already does so and buffers differently. But how can
it tell what raw binary data did to your terminal? First you'd need to program
all the different terminal types into cat (probably by using termcap) which
isn't great simple "Unix" design to begin with. Then you can't just reset the
terminal after running cat. You need to see if the binary data screwed up the
terminal. That isn't in termcap and is probably intractable in the general
case.

While catting actual random data is contrived, using ssh is not. What if the
connection is broken while you're in vi. Vi switches to the alternate screen
and then scrolling stops working. If you don't know what happened it's not
clear why. How can ssh fix this other than acting like tmux and parsing every
terminal command sequence? I'm not convinced there is a simple fix.

This doesn't even get into encoding issues. Some UTF-8 sequences are terminal
commands. The UTF-8 encoding for U+00DF (the German eszett) contains a
sequence which will cause some terminals to wait for a termination byte you
wont ever send.

Plan 9 had the right idea: do away with terminal command sequences altogether.
But that only works there because you can take your "terminal" and turn it
into a GUI window.

------
skissane
> Beware, though: What you are about to see is not particularly elegant. In
> fact, the TTY subsystem — while quite functional from a user's point of view
> — is a twisty little mess of special cases.

I wonder if it is about time someone tried to build something more elegant. If
someone was inventing something like the TTY subsystem from scratch today,
with no requirements for backward compatibility, what would they do
differently?

~~~
rogual
I'd want to investigate not relying on in-band signalling for terminal
control. So, perhaps have two input streams: stdin and stdctrl?

Also, it'd be tempting to try and add more structure, but I honestly think
bare streams of bytes are the right abstraction at this level.

~~~
pjc50
Careful: when you have OOB signalling, how do you keep the control codes in
sync with the data, bearing in mind that both streams may be buffered
differently?

~~~
GrinningFool
That's a good point. I think ultimately it would still need to be pipelined as
if it were in-band. Perhaps synchronization codes with a timestamp/uuid that
corresponds to point-in-time against the data.

------
CJefferson
This isn't entirely relevant to the article, but I hope some shell/TTY expert
might read this, and know the answer :)

Hypothetically, could a TTY, in combination with the help of a shell, be able
to separate the stdin, stdout and stderr of every running program? By default
the shell could do what we normally see, but then easily (with some kind of
GUI control) let me pull a particular program's stdout/stderr out to a
seperate window, including (if I stored it) all it's previous output, and
redraw the current terminal removing that program's output.

I've always been tempted to do something like this, and I'm curious if there
is any massive reasons it's simply not possible.

~~~
EdiX
Are you trying to do mathematica notebooks for the shell? There's no easy way
to do this, you have to run each command into a separate pseudo-tty. You can
only do this with a combination of a special terminal emulator and a special
shell that only runs inside the special terminal emulator. You can't do this
and then just use bash.

~~~
CJefferson
Oh, I know it would be a serious undertaking (I'd probably try hacking it into
fish, because I've looked into it's code-base). I was just wondering if it's
hypothetically possible, and why no-one has done it :)

~~~
EdiX
I don't know. The reason I haven't done it is because it's too much work,
there is no pleasant way to do GUI programming and I don't have a clear design
for how the UI.

------
snhorne
If you're interested in the history surrounding the TTY, I just published a
newsletter about it on Friday which you can read (without signing up for
anything) here:
[http://www.rubyletter.com/newsletter/2017/02/03/terminal.htm...](http://www.rubyletter.com/newsletter/2017/02/03/terminal.html)

------
ZenoArrow
This one is a bit of a classic, for the last 8 years (apart from in 2015) it
has been on HN at least once a year:

[https://hn.algolia.com/?query=TTY%20demystified&sort=byDate&...](https://hn.algolia.com/?query=TTY%20demystified&sort=byDate&dateRange=all&type=all&storyText=false&prefix=false&page=0)

~~~
mkesper
Maybe worth another api entry (maybe 'frequent' or 'classic')?

------
ape4
Should add "(2008)" to this.

~~~
sonthonax
Why? The only reason to put a date on a title is when the content itself is of
historical interest, or may no longer be accurate.

------
laumars
Thanks for the submission, I've missed this previous times it has been posted.

I'm currently in the process of writing my own shell so if anyone has any
other good resources you'd recommend then I'd be hugely grateful :) (the
simpler the better too hehehe)

~~~
lutusp
When writing shells it's possible to invoke standard libraries on both ends of
the circuit to handle these communications/protocol issues without having to
rewrite them.

~~~
laumars
I've got file streams working, that's the easy part. However I'm having issues
with console applications that detect and require a PTY. Also handling ncurses
is causing me a bit of bother.

------
tejasmanohar
I stumbled across this a few months ago while implementing basic TTY resizing
and ended up learning way more than I needed to. Super impressive, thorough
article. :-)

------
birchb
ASCII was invented in 1963, so the author's statement that Telex was ASCII-
based is probably wrong. Is the rest of the article also as inaccurate?

~~~
kpil
According to Wikipedia, it seems that ASCII was first used by AT&T's TWX
teleprinter network, that previously used another encoding, ITA2.

The keyword is "evolved into" as a long chain of changes, from Morse code,
Murray code, a plethora of other variants of encodings and transmission
methods, eventually standardised into ASCII on top of a modem in 1963.

