User-space virtual terminals are one of the terminal management features of the nosh package. They allow one to run systems that still have virtual terminal system on the physical user stations, with all of the familiar accoutrements such as terminal login sessions and virtual terminal switching with hotkeys, but without that virtual terminal system being embedded into the operating system kernel. Conversely, they are X-less; they don't depend from any X11 tools or libraries.
The design comprises separate coöperating components.
A realizer talks to the devices comprising a physical user station communicates with a terminal emulator. There's a realizer that uses a framebuffer and input event devices, supplied with nosh. There's also a limited realizer, mainly useful for monitoring or debugging the console virtual terminals over something like SSH, that uses wide character ncurses for I/O. One could attach screen readers for the blind and partially sighted, since the protocol is close to what they already use. There's nothing stopping people coming up with other tools, with other forms of I/O such as (say) the Wayland display protocol.
A terminal emulator speaks a well-defined protocol to (one or more) realizers using FIFOs and plain old ordinary files in /run/dev
.
It runs the master side of a pseudo-terminal, on the slave side of which is a login session with getty
(or the nosh equivalent), login
, and friends.
In between the realizer and the terminal emulators can sit a multiplexor, which is a man in the middle that looks like a realizer from one side and like a terminal emulator from the other. It does hotkey switching amongst a set of terminal emulators, swallowing the hotkeys from the input stream and maintaining symbolic links that indicate which is the currently visible emulator.
Also in between can sit an input method, which is another man in the middle. It provides a so-called "front end processor" where the user can "pre-edit" input typed in ASCII and converted to other characters, swallowing pre-edit input and generating input of its own to send on when the user accepts conversions.
These components are loosely coupled. One can restart the multiplexor, the input method, or the realizer without affecting the terminal emulators that they attach to. One can attach multiple realizers to a single terminal emulator, or multiplexor, or input method.
And the system is designed to operate with reduced privileges. Not only are the programs not running in kernel mode as part of the operating system kernel, they don't even need superuser access. They can run under dedicated unprivileged accounts, with only the minimum file and device access that they individually need, secured even from one another by the POSIX user account system.
Several things are illustrated here.
The terminal dimensions in the first screen have been adjusted with the console-resize
(a.k.a. resizecons
) utility to 100 columns and 64 rows, the all-black right hand columns of which have been clipped from this screenshot for size reasons.
This utility simply emits the well-known DEC VT control sequences (DECSNLS, DECSLPP, DECCOLM, and DECSCPP) for this.
One could resize a terminal with printf
or echo
if one wanted.
The top part of the first screen is the remains of viewing a Linux manual page in Chinese, after exiting the manual page viewer without clearing the screen.
It illustrates the Unicode ability of nosh user-space virtual terminals.
The terminal emulator speaks UTF-8, by default and natively, and its display mechanism supports a full 24-bit UCS range that covers all of the existing Supplementary Planes.
The manual page is simply the Debian Linux Chinese language manual package and the -L zh_CN
option to the man
command.
The realizer part of a user-space virtual terminal can be given multiple fonts to use, and has a simple priority system giving one the ability to partially override large general fonts with small fonts for specific character repertoires.
Fonts themselves are in the vtfont format that is used by the FreeBSD 10 terminal subsystem.
The realizer pictured here has been set up with the GNU Unifont (converted to vtfont format), overridden by k16-1990
(a widely circulated 16×16 JISX0208.1990 font, converted from BDF with the BSD vtfontcvt
tool) and 9x16
(built from two widely circulated 9x16
and 9x16B
raster fonts) to improve the appearance of several characters over GNU Unifont.
The Guide contains a chapter that has pointers to various terminal resources, including several font collections, from which the aforementioned fonts can be obtained.
The shell prompt is an ordinary Z Shell prompt using termcap, that thinks that it is talking to a linux
type terminal.
This is the terminal type that is used by the kernel virtual terminals on Linux.
On FreeBSD/TrueOS, the nosh user-space virtual terminal emulator likewise emulates the same type as the FreeBSD/TrueOS kernel virtual terminals.
Not shown here, because it is rather difficult to show as a screenshot, is the function key and extended key emulation. As well as speaking "true DEC VT", the terminal emulator user-space virtual terminal speaks the various quirky keyboard input dialects that are spoken by the Linux, FreeBSD/TrueOS, NetBSD, and SCO Xenix kernel virtual terminals. As a bonus, user-space virtual terminals also add full DEC VT modifier support to those protocols, so that one can distinguish function and extended keys where modifiers are in effect.
The colour blocks indicate support for ISO 8613-6:1994/ITU T.416:1993 Set Graphic Rendition control sequences. Shown here are the effects of the SGR control sequences that select from the (conventional) 256-colour palette, the result of a fairly widely known Perl script. Not shown here, but also supported, is full 24-bit RGB SGR colour support.
The text at the bottom of the first screen shows ECMA-48 Set Graphic Rendition attribute support, including all of strikethrough, italics, reverse video, and hidden text. The blank area is actually a word written with the hidden text attribute turned on. Also available, but not shown here, is faint.
Attributes are maintained separately from colours. Boldface, faint, underline, and italics are not displayed using colour changes. The realizer displays them using appropriately weighted and italicized fonts, if they are supplied to it. (Here, italics and boldface are realized by obliquing and 1-pixel shifting an upright medium-weight font.) This makes life easier for such tasks as implementing screen readers.
Inspired by the mosh blurb the second screen illustrates how nosh user-space terminal emulators employ UTF-8 as standard and do not suffer from ISO 2022 problems.
No Unicode normalization is done on the DEC VT state machine's processed control sequences.
The combining caret has no effect on the H
in the CSI sequence.
"Mn" ("Mark, nonspacing") Unicode characters are simply not printed.
There is no ISO 2022 character set switching in the first place.
So the ISO 2022 control sequence has no effect, and does not render the prompt illegible.
cat
a binary file, and the subsequent prompt will still be legible and output still in a sane state.
The terminal line discipline is initialized with iutf8
mode on.
UTF-8 is standard.
The second screen also illustrates some input that can be directly typed. A full ISO/IEC 9995-3 keyboard is available, with the standard common secondary group always present whatever the primary group keyboard layout, and ⇨ Group 2 latch implemented as ⇧ Level 2+⇮ Level 3 — a.k.a. ⇧ Shift+⌥ Right Option on keyboards with Apple-style engravings, a.k.a. ⇧ Shift+⇮ Alt Gr on keyboards with 105/106/107/109-key Windows engravings, a.k.a. ⇧ Shift+⎇ Right Alt on keyboards with 104-key Windows engravings.
The characters typed here include:
⇨ Group 2 ⇧ Shift+S to yield §
⇨ Group 2 7 to yield ⅛
⇨ Group 2 ⇧ Shift+? to yield Ŀ
⇨ Group 2 ⇧ Shift+% to yield ↑
⇨ Group 2 ⇮ Alt Gr+P a to yield ả
⇨ Group 2 ⇮ Alt Gr+L C to yield Ȼ
⇨ Group 2 ⇮ Alt Gr+K H to yield Ħ
For more, see how to type the motto of Vietnam on an ISO 9995-3 keyboard.
Mentioned earlier are the ability to run the subsystems with unprivileged user accounts. Here are some more of the improvements upon kernel-space virtual terminals.
When it comes to resizing the display, kernel virtual terminals are complex.
Changing virtual terminal size has to be done with special programs that know how to reprogram display hardware, that need superuser privileges, and that can only run locally on the machine where the kernel virtual terminal is, because they operate directly on local character devices with ioctl()
calls and need to do things like re-program fonts into the hardware.
It also affects all virtual terminals in one go.
User-space virtual terminals behave like real terminals did: one just sends the well-known DEC VT control sequences to them.
Moreover, that control sequence only affects the individual virtual terminal to which it has been sent.
One can resize terminals with printf
or echo
; one can resize them whilst logged in remotely to another system with SSH (as long as one hasn't interposed another terminal emulator in the way, of course).
There's also an improvement on real terminals. The DEC VT protocol itself supports arbitrary heights and widths, but real terminals impose rules that the heights and widths requested are silently rounded up to the next hardware-supported size.
User-space virtual terminals allow arbitrary sizes, above a certain minimum. (A zero-sized terminal is disallowed, for obvious reasons. A 1×1 terminal is disallowed because the semantics of scrolling and cursor line wrap would be highly unhelpful to the user.) They can even be larger than the physical display size, the realizer automatically panning and scrolling to keep the cursor position always in view.
Linux and BSD kernel virtual terminals have a fixed association with the physical devices that underlie them.
One can have multiple user-space virtual terminals, of different sizes, multiplexed onto a single physical user station (a "head"). One can also have multiple heads, if one has multiple framebuffer and input event devices. The multiplexing is done with symbolic links and user-space multiplexor dæmons. Adjusting the plumbing is as simple as adjusting the links and restarting the affected dæmons.
Because of this design, one can migrate live terminal sessions from head to head, since one can adjust and restart the multiplexing layer without having to stop and restart the individual emulations that are being multiplexed or the login sessions that are running on those terminals.
Kernel virtual terminals are restricted by the fact that fonts occupy precious kernel memory space. There are tight limitations on the number of fonts that can be loaded.
Such limitations do not apply to user-space virtual terminals. Because its fonts are not kernel-resident, the realizer part of a user-space virtual terminal can be supplied with an arbitrary set of multiple fonts.