user-vt 5 file formats nosh
user-vt user-space virtual terminals

## Description

User-space virtual terminals comprise a set of normal and special files in an enclosing `directory/`.

Conventionally, `directory/` is a subdirectory of `/run/dev/`. This convention is understood by the console-input-method-control 1, console-multiplexor-control 1, and vc-get-terminal 1 commands when it comes to finding user-space virtual terminals from their basenames, and by login-process 1 when it comes to constructing fake terminal IDs for compatibility with obsolete systems.

See the user-space virtual terminals section of the nosh Guide for how various commands operate in tandem to run user-space VTs.

## Files

The files used are as follows:

`directory/tty`

  A stable and predictable name for the front end of the pseudo-terminal device. If `directory/` is `/run/dev/vc1`, for example, then the stable name for the terminal, for use in login services, will be `/run/dev/vc1/tty`. This is a link to the device, if possible, or a symbolic link if not.

  It is usually not. On Linux, the pseudo-terminal devices are on a filesystem of their own, which would make a link a cross-filesystem link; and on BSDs the `devfs` driver disallows the creation of directories under `/dev` forcing `directory/` to be on another filesystem anyway.
`directory/input`

  The input FIFO, through which realizer processes send keyboard and mouse events. Events are in a uniform packet format.

  Because realizers and other tools connect to and disconnect from the FIFO arbitrarily during the lifetime of a user-space VT, readers must ensure that they avoid the hangup signal behaviour that accompanies writers closing a FIFO.
`directory/display`

  The UTF-32, 24-bit colour, display buffer that output realizers realize onto some kind of output medium.

`directory/vcsa`

  An 8-bit character set, 3-bit colour, display buffer that is compatible with the Linux vcsa devices for kernel virtual terminals. This does not necessarily exist.

`directory/lock`

  A lock file of the form used by the setlock 1 command. This is used by console-terminal-emulator 1, console-input-method 1, and console-multiplexor 1 to ensure exclusive access.

## vcsa buffer

This file is structured as per the Linux character device file of that name, as a 4-byte header giving size and cursor position information followed by a series of 2-byte character and attribute pairs in IBM PC CGA format. It is implemented mainly as a compatibility mechanism for the benefits of terminal realizing softwares that expect Linux vcsa devices, such as screen readers for the blind or partially sighted.

The vcsa screen buffer is always ISO 8859-1; with Unicode code points outwith that range converted to code point 255. To handle a wider range of characters, terminal realizing softwares should use the Unicode screen buffer. Code points in the ranges 0x00 to 0x1F and 0x80 to 0x9F may appear, and terminal realizing softwares are expected to render these with some form of ordinary printing graphic.

The 24-bit RGB foreground and background colour values for character cells are mapped to 3-bit CGA by comparing the relative intensities of red, green, and blue. The "bright foreground" and "bright background" CGA attribute bits are taken from the boldface and blink terminal attributes, respectively. No attempt is made to provide MDA or VGA in monochrome mode attributes, such as underline. To handle the full range of attributes, terminal realizing softwares should use the Unicode screen buffer.

## Unicode buffer

This file begins with a 16-byte header:

1. 4-byte UCS-4 Byte Order Mark in host byte order.

2. 2-byte width in host byte order.

3. 2-byte height in host byte order.

4. 2-byte cursor X position in host byte order.

5. 2-byte cursor Y position in host byte order.

6. cursor glyph type byte (upper nybble reserved).

7. cursor attributes byte (upper nybble reserved).

8. screen flags and pointer attributes byte, upper and lower nybble.

9. Reserved byte.

That is followed by a series of 16-byte records, one per character cell, containing:

1. Foreground alpha value byte.

2. Foreground red value byte.

3. Foreground green value byte.

4. Foreground blue value byte.

5. Background alpha value byte.

6. Background red value byte.

7. Background green value byte.

8. Background blue value byte.

9. 4-byte UCS-4 value in host byte order.

10. 2-byte attributes.

11. Reserved bytes.

Unassigned code points, reserved code points, control code points, combining code points, and zero-width code points may appear, and terminal realizing softwares are expected to render these with some form of ordinary printing graphic. For forwards and backwards compatibility, reserved bits in records should be written as zeroes, ignored when read, and preserved when copied.

## FIFO input protocol

The input FIFO receives a sequence of 4-byte messages. To avoid message tearing, realizers must ensure that they do not write messages using multiple system calls. A message is a 32-bit word in host byte order. The most significant byte denotes the message type and the interpretation of the remainder of the message.

`0x00nnnnnn`

  A null message. This must be ignored.

`0x01cccccc`

  Unicode character. The UCS-4 code point is `cccccc`.

`0x02kkkkmm`

  A system keypad key. The key number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x04kkkkmm`

  The absolute horizontal (x axis) position of the mouse. The column number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x05kkkkmm`

  The absolute vertical (y axis) position of the mouse. The row number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x06kknnmm`

  The absolute depth (z axis) position of the mouse. The row number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x07kkbbmm`

  A mouse button. The button number is `kk`, its state is `bb`, and `mm` is a set of bitflags indicating the current state of modifier keys. The well-known buttons are numbered in DEC VT order: left, middle, right, side.

`0x08kknnmm`

  A mouse wheel motion. The wheel number is `kk`, the (signed) amount by which the wheel is scrolled is `nn`, and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x09cccccc`

  Pasted Unicode character. The UCS-4 code point is `cccccc`.

`0x0Annnnmm`

  A session switch request. The session number is `nnnn` and `mm` is a set of bitflags indicating the current state of modifier keys. Sessions are numbered from 0, as per the FreeBSD and NetBSD console conventions.

`0x0Ckkkkmm`

  A consumer device key. The key number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x0Ekkkkmm`

  An extended key. The key number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x0Fkkkkmm`

  A function key. The function key number is `kkkk` and `mm` is a set of bitflags indicating the current state of modifier keys.

`0x11cccccc`

  Unicode accelerator character. The UCS-4 code point is `cccccc`.

Input messages are intentionally similar to the action codes employed in keyboard maps (c.f. console-keyboard-map 5). Because of this, codes `0x03nnnnnn`, `0x1Ennnnnn`, and `0x1Fnnnnnn` are reserved in input messages, and must be ignored.

The modifier flags represent abstract level2, level3, control, group2, and super modifiers. (See ISO 9995 for the concepts of levels and groups; super is an abstract "Command" or "GUI" modifier.) The input protocol does not comprise standalone events for modifier keys or associated modifier lock keys.

The numbering of system, extended, and consumer keys largely follows the ID numbers used for keys in the USB HID protocol, with some exceptions, and a number of additions for keys that are not present in USB. Importantly, keys that generate ordinary Unicode characters are sent as a Unicode character message and not as an extended key with the USB keycode; with the exceptions of soft-switchable keys.

All mouse positioning is absolute, in cells; and there is no requirement that a positioning event be sent if the value on its particular axis has not changed. All positioning events must precede any button events at the eventual position.

## Security

No superuser privileges are required and user-space virtual terminals are designed to be managed entirely under the aegis of unprivileged user accounts.

### permissions and ownerships

The creator of a user-space virtual terminal only requires write and search access to `directory/` and need not have owner access to it. A program attaching to an existing user-space virtual terminal only requires search access to `directory/`.

All created display buffer files should have permissions rw- for the user or a group of any account that can modify the display (e.g. the effective UID of a process running console-terminal-emulator 1, console-multiplexor 1, or console-input-method 1) with r-- permission for the user or a group of any account that can realize the display output somewhere. All other users and groups should have --- permissions.

All created input FIFO files should have permissions rw- for the user or a group of any account that can process the input (same examples as aforegiven) with -w- permission for the user or a group of any account that can realize the input somewhere. All other users and groups should have --- permissions.

Usually `directory/` itself will be set-group-ID to a group different to any of the aforegiven groups, allowing group access to the display buffers and input FIFO, without (thereby) granting (group) access to anything else in `directory/`.

### privacy and non-persistence of display data

The display buffer files must be erased at (non-abend) process termination. This ensures that (absent system backups, log-structured filesystems, and low-level data recovery) old terminal display content cannot be read out of a display buffer. For best results, place these files on a temporary filesystem, set whatever options the temporary filesystem has (if any) for erasing backing storage at unmount, and exclude the temporary filesystem from backups.

### programmatic input message injection

Input method and multiplexor control under programmatic control with a command tool is done by injecting messages into the input stream. Permission to inject things into the input stream is implicitly permission to generate arbitrary keyboard and mouse input to a session. Usually the only accounts with such privileges are the superuser and the accounts used to run the dæmons that form the user-space virtual terminal subsystem.

Such input method and multiplexor switching can unexpectedly switch users away from password prompts and the like. Be careful about granting users the privilege of performing these actions. For best results, only the user physically at the user station(s) where the virtual terminal is being realized should be able to generate input method and multiplexor switching commands, with actual keyboard actions.

(The kernel virtual terminal system shares these caveats and risks. They are simply rarely discussed.)

## Author

Jonathan de Boyne Pollard