Search code examples
unicodecontrol-characters

Do you know of documented uses of the APC (U+009F) control sequences?


I'm looking for documented examples of applications using the APC (APPLICATION PROGRAM COMMAND) control character. I've read ECMA-48, which defines it as follows:

APPLICATION PROGRAM COMMAND APC - APPLICATION PROGRAM COMMAND

Notation: (C1)

Representation: 09/15 or ESC 05/15

APC is used as the opening delimiter of a control string for application program use. The command string following may consist of bit combinations in the range 00/08 to 00/13 and 02/00 to 07/14. The control string is closed by the terminating delimiter STRING TERMINATOR (ST). The interpretation of the command string depends on the relevant application program.

I've found that many modern terminal emulator programs recognize this control enough to suppress the display of the APC thru the ST, which seems to match up with the ECMA intent... I'm looking for any examples using "namespaces" that might allow different apps to use different content in the command sequence. I would be particularly interested in examples where a terminal emulator does something with APC sequences.

Example

const APC = "\x9F"
const ST = "\x9C"

console.log(`Hello world${APC}hidden command${ST}!`)

As displayed on the terminal (Windows 10)

PS > node index.js
Hello world!

The "hidden command" is not displayed. This seems good, but if I pipe the output to another app, the command string is in there.

Some shells seem a bit confused by the C1 version of the control characters, I have some work to do to document that.

Background

I'm considering using APC sequences to allow embedded data, e.g., in JSON form, to be mixed into a stdout stream.


Solution

  • Known users of Application Program Command (APC):

    • Some Kermit implementations (in particular C-Kermit) support running Kermit commands sent as APC strings
    • Kitty uses APC sequences as part of its graphics protocol
    • The Terminal Support Control (TSC) component of the iRMX real-time operating system uses APC sequences. You send a request to the TSC as an OSC and it sends its reply as an APC. (See this PDF, pages numbered 242 and 285, PDF pages 256 and 299)
    • GNU Screen hardstatus is set via APC. (Thanks to Gerrit's answer for finding this.)
    • Similarly, tmux supports using APC to set the window title (see tmux source code input_exit_apc function
    • Perforce (formerly Rogue Wave) HostAccess terminal emulator supports using using APC sequences to build Windows GUIs (see this PDF page 12). This is so you can have a legacy terminal mode application (most commonly business software written in BASIC for the PICK platform) and give it a Windows GUI just by adding escape sequences to the code
    • In the 1980s US military "Integrated Information Support System" (IISS) program, APC sequences were used to send function keys (see ADA182580 PDF page 34, November 1985; ADA249197 PDF page 12, September 1990)
    • Some Beehive terminals supported using APC to send function keys, albeit using an incompatible encoding from IISS. (See for example ATL-008 Technical User's Manual, February 1984, PDF page 45) They also supported using APC (unusually, actually ESC APC, i.e. ESC ESC _) to configure keybindings and the terminal's built-in menu system (see page 104 of that PDF).

    You will notice the above are almost all completely incompatible with each other. The only standard for "namespaces" of which I am aware is DEC's internal standard DEC STD 070, which mandates the first character of the APC sequence identify its type/purpose – but DEC themselves never really used APC sequences, and there is no registry of those prefixes. However, Kitty's graphics protocol (approximately) follows that standard by prefixing all its APC messages with G. (I say "approximately", because DEC-STD-070 says only "private use" sequence characters should be used, and apparently G is not one of those.)

    The reality is, APC is very rarely implemented – most systems never generate APC sequences and silently ignore any received. No application should send or interpret APC sequences unless it knows the other end of the connection is using them in a particular way – such as through a configuration option to enable their use, or if it (somehow) knows which terminal emulator is being used and knows that terminal emulator assigns them a particular meaning – hence, there isn't much need for "namespaces" in practice. If you really feel the need for "namespaces", probably best option is to use the DEC-STD-070 approach of reserving an initial character.

    One of the reasons why APC is rarely used, is it is a potential security vulnerability – if your APC sequence does something potentially harmful, an attacker could put the APC sequence into a file and trick the user into viewing that file using cat/etc. Programs which display untrusted files should filter their output to remove escape sequences such as APC, but programs such as cat generally don't.