2024-11-19 00:05:42 +01:00
|
|
|
|
---
|
|
|
|
|
|
title: OSC 3008: Hierarchical Context Signalling
|
|
|
|
|
|
category: Interfaces
|
|
|
|
|
|
layout: default
|
|
|
|
|
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# OSC 3008: Hierarchical Context Signalling
|
|
|
|
|
|
|
|
|
|
|
|
A terminal connects a user with programs. Control of the program side of
|
|
|
|
|
|
terminals is typically passed around to various different components while the
|
|
|
|
|
|
user is active: a shell might pass control to a process it invokes. If that
|
|
|
|
|
|
process is `run0` then primary control is passed to the privileged session of
|
|
|
|
|
|
the target user. If `systemd-nspawn` is invoked to start a container, primary
|
|
|
|
|
|
control is passed to that container, and so on.
|
|
|
|
|
|
|
|
|
|
|
|
A terminal emulator might be interested to know which component is currently in
|
|
|
|
|
|
primary control of the program side of a terminal. OSC 3008 is a mechanism to
|
|
|
|
|
|
inform it about such contexts. Each component taking over control can inform
|
|
|
|
|
|
the terminal emulators that a new context begins now, and then use the terminal
|
|
|
|
|
|
or pass control down to further apps, which can introduce contexts. Each
|
|
|
|
|
|
context may carry various descriptive metadata fields.
|
|
|
|
|
|
|
|
|
|
|
|
## Status
|
|
|
|
|
|
|
|
|
|
|
|
This OSC sequence has been invented by the systemd project and is generated by
|
|
|
|
|
|
systemd. Currently, no terminal application is known that consumes these
|
|
|
|
|
|
sequences.
|
|
|
|
|
|
|
|
|
|
|
|
## Use Cases
|
|
|
|
|
|
|
|
|
|
|
|
Terminal emulators can use hierarchical context information:
|
|
|
|
|
|
|
|
|
|
|
|
1. To introduce markers/bookmarks in the output that the user can jump between.
|
|
|
|
|
|
|
|
|
|
|
|
2. To visually identify output from different contexts. For example the
|
|
|
|
|
|
background of the associated output can be tinted in a reddish tone when
|
|
|
|
|
|
privileges are acquired, and similar.
|
|
|
|
|
|
|
|
|
|
|
|
3. Meta information on specific output can be shown in a tooltip or similar
|
|
|
|
|
|
|
|
|
|
|
|
4. Programs (and all subcontexts) can be killed via a right-click menu on the
|
|
|
|
|
|
output they generate.
|
|
|
|
|
|
|
|
|
|
|
|
5. Similar, a right-click menu might offer an item to offer opening a new
|
|
|
|
|
|
interactive shell in the same working directory that was current on the
|
|
|
|
|
|
selected context.
|
|
|
|
|
|
|
|
|
|
|
|
6. Failed commands or aborted sessions can be marked requesting user attention.
|
|
|
|
|
|
|
|
|
|
|
|
## Context Types
|
|
|
|
|
|
|
|
|
|
|
|
There are various types of contexts defined by this specification:
|
|
|
|
|
|
|
|
|
|
|
|
1. `boot` → a booted system initiates this context early at boot. (systemd's
|
|
|
|
|
|
PID 1 generates this on `/dev/console`.)
|
|
|
|
|
|
|
|
|
|
|
|
2. `container` → a container manager initialized an interactive connection to a
|
|
|
|
|
|
container. (`systemd-nspawn` generates this when interactively invoking a
|
|
|
|
|
|
container. `machinectl login`, `machinectl shell` do this too.)
|
|
|
|
|
|
|
|
|
|
|
|
3. `vm` → a VM manager initialized a terminal connection to a
|
|
|
|
|
|
VM. (`systemd-vmspawn` generates this when interactively invoking a VM, as
|
|
|
|
|
|
one example.)
|
|
|
|
|
|
|
|
|
|
|
|
4. `elevate` → when the user interactively acquired higher privileges. (`run0`
|
|
|
|
|
|
initiates a context of this type whenever the user invokes it to acquire
|
|
|
|
|
|
root privileges.)
|
|
|
|
|
|
|
|
|
|
|
|
5. `chpriv` → similar, but when the user acquired *different* privileges, not
|
|
|
|
|
|
necessarily higher ones. (`run0` initiates a context of this type whenever
|
|
|
|
|
|
the user invokes it to acquire non-root privileges of another user.)
|
|
|
|
|
|
|
|
|
|
|
|
5. `subcontext` → similar, but the source and target privileges where
|
|
|
|
|
|
identical. (`run0` initiates a context of this type whenever the user
|
|
|
|
|
|
invokes it to acquire privileges of the user itself.)
|
|
|
|
|
|
|
|
|
|
|
|
6. `remote` → a user invoked a tool such as `ssh` to connect to a remote
|
|
|
|
|
|
system.
|
|
|
|
|
|
|
|
|
|
|
|
7. `shell` → an interactive terminal shell initiates this context
|
|
|
|
|
|
|
|
|
|
|
|
8. `command` → a shell interactively invokes a new program.
|
|
|
|
|
|
|
|
|
|
|
|
9. `app` → an interactive program may initiate this context.
|
|
|
|
|
|
|
|
|
|
|
|
10. `service` → the service manager invokes an interactive service on the terminal
|
|
|
|
|
|
|
|
|
|
|
|
11. `session` → a login session of the user is initialized.
|
|
|
|
|
|
|
|
|
|
|
|
## Semantics
|
|
|
|
|
|
|
|
|
|
|
|
Contexts in the sense of OSC 3008 are hierarchical, and describe a tree
|
|
|
|
|
|
structure: whenever a new context is opened it becomes the new active context,
|
|
|
|
|
|
and the previously active context becomes its parent (if there is one). Only
|
|
|
|
|
|
one context is currently active, but previously opened contexts remain valid in
|
|
|
|
|
|
the background. Any other data written or read should be considered associated
|
|
|
|
|
|
with the currently active context.
|
|
|
|
|
|
|
|
|
|
|
|
Each context carries an identifier, chosen by the component opening the
|
|
|
|
|
|
context. The identifier can chosen freely, but must not be longer than 64
|
|
|
|
|
|
characters. The characters may be in the 32…126 byte range. Identifiers should
|
|
|
|
|
|
be universally unique, for example randomly generated. A freshly generated UUID
|
|
|
|
|
|
would work well for this, but this could also be something like the Linux boot
|
|
|
|
|
|
ID combined with the 64bit inode number of Linux pidfds, or something hashed
|
|
|
|
|
|
from it.
|
|
|
|
|
|
|
|
|
|
|
|
Fundamentally, there are two OSC 3008 commands defined:
|
|
|
|
|
|
|
|
|
|
|
|
1. OSC "`3008;start=`" … (the *start sequence*) → this initiates, updates or
|
|
|
|
|
|
indicates a return to a context. It carries a context identifier, and
|
|
|
|
|
|
typically some metadata. This may be sent to first initiate a context. If
|
|
|
|
|
|
sent again for the same context ID that was initiated already this indicates
|
|
|
|
|
|
an update of the existing context. In this case, *any* previously set
|
|
|
|
|
|
metadata fields for the context are flushed out, reset to their defaults,
|
|
|
|
|
|
and then reinitialized from the newly supplied data. Also, in this case any
|
|
|
|
|
|
subcontexts of the contexts are implicitly terminated.
|
|
|
|
|
|
|
|
|
|
|
|
2. OSC "`3008;end=`" … (the *end sequence*) → this terminates a context. It
|
|
|
|
|
|
carries a context identifier to close, initiated before with OSC
|
|
|
|
|
|
"`3008;start=`". It may also carry additional metadata.
|
|
|
|
|
|
|
|
|
|
|
|
## General Syntax
|
|
|
|
|
|
|
|
|
|
|
|
This builds on ECMA-48, and reuses the OSC and ST concepts introduced there.
|
|
|
|
|
|
|
|
|
|
|
|
For sequences following this specification it is recommended to encode OSC as
|
|
|
|
|
|
0x1B 0x5D, and ST as 0x1B 0x5C.
|
|
|
|
|
|
|
|
|
|
|
|
ECMA-48 only allows characters from the range 0x20…0x7e (i.e. 32…126) inside
|
|
|
|
|
|
OSC sequences. However, most terminal emulators nowadays allow the ASCII byte
|
|
|
|
|
|
range > 0x7f in the OSC sequences they process, and so does this
|
|
|
|
|
|
specification. Control characters (< 0x20 and 0x7f) are not allowed. The
|
|
|
|
|
|
semicolon character ("`;`") – which is used as field separator by this
|
|
|
|
|
|
specification – shall be replaced by "`\x3b`" and the backslash character
|
|
|
|
|
|
("`\`") shall be replaced by "`\x5c`". All textual fields must be encoded in
|
|
|
|
|
|
UTF-8, and then escaped with these two replacements.
|
|
|
|
|
|
|
|
|
|
|
|
The start sequence begins with OSC, followed by the string `3008;start=`,
|
|
|
|
|
|
followed by the context ID. This is then followed by any number of metadata
|
|
|
|
|
|
fields, including none. Metadata fields begin with a semicolon (`;`) followed
|
|
|
|
|
|
by in a string identifying the type of field, followed by an equal sign (`=`),
|
|
|
|
|
|
and the field value. The sequence ends in ST.
|
|
|
|
|
|
|
|
|
|
|
|
The end sequence begins with OSC, followed by the string `3008;end=`, followed
|
|
|
|
|
|
by the context ID, and a series of metadata fields in the same syntax as for
|
|
|
|
|
|
the start sequence. The sequence ends in ST.
|
|
|
|
|
|
|
|
|
|
|
|
## Metadata Fields
|
|
|
|
|
|
|
|
|
|
|
|
The following fields are currently defined for the start sequence:
|
|
|
|
|
|
|
|
|
|
|
|
| Field | Context Types | Description |
|
|
|
|
|
|
|---------------|---------------|-------------------------------------------------------------------------------------------------------------|
|
|
|
|
|
|
| `type=` | *all* | Declares the context type, one of the types described above |
|
|
|
|
|
|
| `user=` | *all* | UNIX user name the process issuing the sequence runs as |
|
|
|
|
|
|
| `hostname=` | *all* | UNIX host name of the system the process issuing the sequence runs on |
|
|
|
|
|
|
| `machineid=` | *all* | The machine ID (i.e. `/etc/machine-id`) of the system the process issuing the sequence runs on |
|
|
|
|
|
|
| `bootid=` | *all* | The boot ID (i.e. `/proc/sys/kernel/random/boot_id`) of the system the process issuing the sequence runs on |
|
|
|
|
|
|
| `pid=` | *all* | The numeric PID of the process issuing the sequence, in decimal notation |
|
|
|
|
|
|
| `pidfdid=` | *all* | The 64bit inode number of the pidfd of the process issuing the sequence, in decimal notation |
|
|
|
|
|
|
| `comm=` | *all* | The process name (i.e. `/proc/$PID/comm`, `PR_GET_NAME`) of the process issuing the sequence |
|
|
|
|
|
|
| `cwd=` | `shell`, `command` | The current working directory |
|
|
|
|
|
|
| `cmdline=` | `command` | The full command line of the invoked command |
|
|
|
|
|
|
| `vm=` | `vm` | The name of the VM being invoked |
|
|
|
|
|
|
| `container=` | `container` | The name of the container being invoked |
|
|
|
|
|
|
| `targetuser=` | `elevate`, `chpriv`, `vm`, `container`, `remote`, `session` | Target UNIX user name |
|
|
|
|
|
|
| `targethost=` | `remote` | Target UNIX, DNS host name, or IP address |
|
|
|
|
|
|
| `sessionid=` | `session` | New allocated session ID |
|
|
|
|
|
|
|
|
|
|
|
|
The following fields are currently defined for the end sequence:
|
|
|
|
|
|
|
|
|
|
|
|
| Field | Context Types | Description |
|
|
|
|
|
|
|---------------|---------------|-------------------------------------------------------------------------------------------------------------|
|
|
|
|
|
|
| `exit=` | `command` | One of `success`, `failure`, `crash`, `interrupt`, indicating how the program terminated |
|
|
|
|
|
|
| `status=` | `command` | The command's numeric exit status, i.e. the 0…255 value a program returns |
|
|
|
|
|
|
| `signal=` | `command` | The termination signal of the command, if it died abnormally. A symbolic signal name. (`SIGKILL`, …) |
|
|
|
|
|
|
|
|
|
|
|
|
All fields are optional, including the context type. However, it is generally
|
|
|
|
|
|
recommended to always include the first 7 fields listed above, to make it easy
|
|
|
|
|
|
to pinpoint the origin of a context in a race-free fashion, without any
|
|
|
|
|
|
ambiguities.
|
|
|
|
|
|
|
|
|
|
|
|
The order of the metadata fields is undefined, they may appear in any order
|
|
|
|
|
|
(including that `type=` is specified at the very end or in the middle!). Note
|
|
|
|
|
|
that `start=` and `end=` are not considered metadata fields but part of the
|
|
|
|
|
|
start sequence, and hence must always appear right after OSC.
|
|
|
|
|
|
|
|
|
|
|
|
## Processing, Limits, Security
|
|
|
|
|
|
|
|
|
|
|
|
All context information provided like this should be considered auxiliary and –
|
|
|
|
|
|
to some degree – redundant information. Hence, it would be wise for a terminal
|
|
|
|
|
|
to enforce limits on various resources, dropping additional data once these
|
|
|
|
|
|
limits are hit. Most importantly, a maximum stacking depth should probably
|
|
|
|
|
|
enforced: any attempts to initiate further contexts should be ignored once the
|
|
|
|
|
|
stack limit is hit (i.e. the earlier contexts should be kept, the later
|
|
|
|
|
|
contexts be discarded, not the opposite). Overly long fields should be
|
|
|
|
|
|
discarded (or potentially truncated, depending on the field type). This
|
|
|
|
|
|
specification does not recommend any specific stack or string limits for now.
|
|
|
|
|
|
|
2025-04-27 10:35:52 +09:00
|
|
|
|
The usual terminal reset sequences should *not* affect the stack of contexts
|
2024-11-19 00:05:42 +01:00
|
|
|
|
(this is a safety feature: a program down the stack should not be able to
|
|
|
|
|
|
affect the stack further up, possibly hiding relevant information). A temporary
|
|
|
|
|
|
TTY hangup (`vhangup()`) should result in a full reset of the stack.
|
|
|
|
|
|
|
|
|
|
|
|
All provided data should be processed in a lenient, graceful fashion: if a
|
|
|
|
|
|
sequence contains invalid fields, those fields should be ignored, but the rest
|
|
|
|
|
|
of the fields should still be used. In particular, unknown fields should be
|
|
|
|
|
|
ignored.
|
|
|
|
|
|
|
|
|
|
|
|
The fields provided in these sequences should not contain sensitive
|
|
|
|
|
|
information. Context IDs should not be considered confidential, but it is
|
|
|
|
|
|
strongly recommended to generate them in a fashion that guarantees their
|
|
|
|
|
|
sufficient uniqueness and avoids accidental or intended clashes with other
|
|
|
|
|
|
contents.
|
|
|
|
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
|
|
|
|
1. A new container `foobar` has been invoked by user `lennart` on host `zeta`:
|
|
|
|
|
|
`OSC "3008;start=bed86fab93af4328bbed0a1224af6d40;type=container;user=lennart;hostname=zeta;machineid=3deb5353d3ba43d08201c136a47ead7b;bootid=d4a3d0fdf2e24fdea6d971ce73f4fbf2;pid=1062862;pidfdid=1063162;comm=systemd-nspawn;container=foobar" ST`
|
|
|
|
|
|
|
|
|
|
|
|
2. This context ends: `OSC "3008;end=bed86fab93af4328bbed0a1224af6d40" ST`
|
|
|
|
|
|
|
|
|
|
|
|
## Syntax in ABNF
|
|
|
|
|
|
|
|
|
|
|
|
```abnf
|
|
|
|
|
|
OSC = %x1B %x5D
|
|
|
|
|
|
ST = %x1B %x5C
|
|
|
|
|
|
|
|
|
|
|
|
DECIMAL = "0"-"9"
|
|
|
|
|
|
HEX = "0"-"9" / "A"-"F" / "a-f"
|
|
|
|
|
|
ID128 = 32*36(HEX / "-")
|
|
|
|
|
|
UINT64 = 1*20DECIMAL
|
|
|
|
|
|
ESCSEMICOLON = "\x3b"
|
|
|
|
|
|
ESCBACKSLASH = "\x5c"
|
|
|
|
|
|
SAFE = %x20-3a / %x3c-5b / %x5d-7e / ESCSEMICOLON / ESCBACKSLASH
|
|
|
|
|
|
|
|
|
|
|
|
CTXID = 1*64SAFE
|
|
|
|
|
|
TYPEENUM = "service" / "session" / "shell" / "command" / "vm" / "container" / "elevate" / "chpriv" / "subcontext" / "remote" / "boot" / "app"
|
|
|
|
|
|
|
|
|
|
|
|
TYPE = "type=" TYPEENUM
|
|
|
|
|
|
USER = "user=" 1*255SAFE
|
|
|
|
|
|
HOSTNAME = "hostname=" 1*255SAFE
|
|
|
|
|
|
MACHINEID = "machineid=" 1D128
|
|
|
|
|
|
BOOTID = "bootid=" ID128
|
|
|
|
|
|
PID = "pid=" UINT64
|
|
|
|
|
|
PIDFDID = "pidfdid=" UINT64
|
|
|
|
|
|
COMM = "comm=" 1*255SAFE
|
|
|
|
|
|
CWD = "cwd=" 1*255SAFE
|
|
|
|
|
|
CMDLINE = "cmdline=" *255SAFE
|
|
|
|
|
|
VM = "vm=" 1*255SAFE
|
|
|
|
|
|
CONTAINER = "container=" 1*255SAFE
|
|
|
|
|
|
TARGETUSER = "targetuser=" 1*255SAFE
|
|
|
|
|
|
TARGETHOST = "targethost=" 1*255SAFE
|
|
|
|
|
|
SESSIONID = "sessionid=" 1*255SAFE
|
|
|
|
|
|
|
|
|
|
|
|
STARTFIELD = TYPE / USER / HOSTNAME / MACHINEID / BOOTID / PID / PIDFDID / COMM / CWD / CMDLINE / VM / CONTAINER / TARGETUSER / TARGETHOST / SESSIONID
|
|
|
|
|
|
STARTSEQ = OSC "3008;start=" CTXID *(";" STARTFIELD) ST
|
|
|
|
|
|
|
|
|
|
|
|
EXITENUM = "success" / "failure" / "crash" / "interrupt"
|
|
|
|
|
|
SIGNALENUM = "SIGBUS" / "SIGTRAP" / "SIGABRT" / "SIGSEGV" / …
|
|
|
|
|
|
|
|
|
|
|
|
EXIT = "exit=" EXITENUM
|
|
|
|
|
|
STATUS = "status=" UINT64
|
|
|
|
|
|
SIGNAL = "signal=" SIGNALENUM
|
|
|
|
|
|
|
|
|
|
|
|
ENDFIELD = EXIT / STATUS / SIGNAL
|
|
|
|
|
|
ENDSEQ = OSC "3008;end=" CTXID *(";" ENDFIELD) ST
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Known OSC Prefixes
|
|
|
|
|
|
|
|
|
|
|
|
Here's a list of OSC prefixes used by the various sequences currently in public
|
|
|
|
|
|
use in various terminal emulators. It's not going to be complete, but I tried
|
|
|
|
|
|
to do some reasonably thorough research to avoid conflicts with the new OSC
|
|
|
|
|
|
sequence defined above.
|
|
|
|
|
|
|
|
|
|
|
|
| OSC Prefix | Purpose |
|
|
|
|
|
|
|----------------:|------------------------------------------------------------|
|
|
|
|
|
|
| `OSC "0;…"` | Icon name + window title |
|
|
|
|
|
|
| `OSC "1;…"` | Icon name |
|
|
|
|
|
|
| `OSC "2;…"` | Window title |
|
|
|
|
|
|
| `OSC "3;…"` | X11 property |
|
|
|
|
|
|
| `OSC "4;…"` | Palette |
|
|
|
|
|
|
| `OSC "5;…"` | Special palette |
|
|
|
|
|
|
| `OSC "6;…"` | Disable special color |
|
|
|
|
|
|
| `OSC "7;…"` | Report cwd |
|
|
|
|
|
|
| `OSC "8;…"` | Hyperlink |
|
|
|
|
|
|
| `OSC "9;…"` | Progress bar (conemu) [conflict: also growl notifications] |
|
|
|
|
|
|
| `OSC "10;…"` | Change colors |
|
|
|
|
|
|
| `OSC "11;…"` | " |
|
|
|
|
|
|
| `OSC "12;…"` | " |
|
|
|
|
|
|
| `OSC "13;…"` | " |
|
|
|
|
|
|
| `OSC "14;…"` | " |
|
|
|
|
|
|
| `OSC "15;…"` | " |
|
|
|
|
|
|
| `OSC "16;…"` | " |
|
|
|
|
|
|
| `OSC "17;…"` | " |
|
|
|
|
|
|
| `OSC "18;…"` | " |
|
|
|
|
|
|
| `OSC "19;…"` | " |
|
|
|
|
|
|
| `OSC "21;…"` | Query colors (kitty) |
|
|
|
|
|
|
| `OSC "22;…"` | Cursor shape |
|
|
|
|
|
|
| `OSC "46;…"` | Log file |
|
|
|
|
|
|
| `OSC "50;…"` | Set font |
|
|
|
|
|
|
| `OSC "51;…"` | Emacs shell |
|
|
|
|
|
|
| `OSC "52;…"` | Manipulate selection data (aka clipboard) |
|
|
|
|
|
|
| `OSC "60;…"` | Query allowed |
|
|
|
|
|
|
| `OSC "61;…"` | Query disallowed |
|
|
|
|
|
|
| `OSC "99;…"` | Notifications (kitty) |
|
|
|
|
|
|
| `OSC "104;…"` | Reset color |
|
|
|
|
|
|
| `OSC "105;…"` | Enable/disable special color |
|
|
|
|
|
|
| `OSC "110;…"` | Reset colors |
|
|
|
|
|
|
| `OSC "111;…"` | " |
|
|
|
|
|
|
| `OSC "112;…"` | " |
|
|
|
|
|
|
| `OSC "113;…"` | " |
|
|
|
|
|
|
| `OSC "114;…"` | " |
|
|
|
|
|
|
| `OSC "115;…"` | " |
|
|
|
|
|
|
| `OSC "116;…"` | " |
|
|
|
|
|
|
| `OSC "117;…"` | " |
|
|
|
|
|
|
| `OSC "118;…"` | " |
|
|
|
|
|
|
| `OSC "119;…"` | " |
|
|
|
|
|
|
| `OSC "133;…"` | Prompt/command begin/command end (finalterm/iterm2) |
|
|
|
|
|
|
| `OSC "440;…"` | Audio (mintty) |
|
|
|
|
|
|
| `OSC "633;…"` | vscode action (Windows Terminal) |
|
|
|
|
|
|
| `OSC "666;…"` | "termprop" (vte) |
|
|
|
|
|
|
| `OSC "701;…"` | Locale (mintty) |
|
|
|
|
|
|
| `OSC "777;…"` | Notification (rxvt) |
|
|
|
|
|
|
| `OSC "3008;…"` | This specification |
|
|
|
|
|
|
| `OSC "7704;…"` | ANSI colors (mintty) |
|
|
|
|
|
|
| `OSC "7750;…"` | Emoji style (mintty) |
|
|
|
|
|
|
| `OSC "7770;…"` | Font size (mintty) |
|
|
|
|
|
|
| `OSC "7771;…"` | Glyph coverage (mintty) |
|
|
|
|
|
|
| `OSC "7721:…"` | Copy window title (mintty) |
|
|
|
|
|
|
| `OSC "7777;…"` | Window size (mintty) |
|
|
|
|
|
|
| `OSC "9001;…"` | Action (Windows Terminal) |
|
|
|
|
|
|
| `OSC "1337;…"` | iterm2 multiplex seeuqnece |
|
|
|
|
|
|
| `OSC "5522;…"` | Clipboard (kitty) |
|
|
|
|
|
|
| `OSC "30001;…"` | Push color onto stack (kitty) |
|
|
|
|
|
|
| `OSC "30101;…"` | Pop color from stack (kitty) |
|
|
|
|
|
|
| `OSC "77119;…"` | Wide chars (mintty) |
|