|
Takashi Iwai |
dd6e2e |
From f59fcad27535c7efd8017e084cf215ece392a85f Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
dd6e2e |
From: nick black <dankamongmen@gmail.com>
|
|
Takashi Iwai |
dd6e2e |
Date: Mon, 30 Aug 2021 04:56:15 -0400
|
|
Takashi Iwai |
dd6e2e |
Subject: [PATCH] console: consume APC, DM, DCS
|
|
Takashi Iwai |
dd6e2e |
Git-commit: 3a2b2eb55681158d3e3ef464fbf47574cf0c517c
|
|
Takashi Iwai |
dd6e2e |
Patch-mainline: v5.15-rc1
|
|
Takashi Iwai |
dd6e2e |
References: stable-5.14.8
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
commit 3a2b2eb55681158d3e3ef464fbf47574cf0c517c upstream.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
The Linux console's VT102 implementation already consumes OSC
|
|
Takashi Iwai |
dd6e2e |
("Operating System Command") sequences, probably because that's how
|
|
Takashi Iwai |
dd6e2e |
palette changes are transmitted.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
In addition to OSC, there are three other major clases of ANSI control
|
|
Takashi Iwai |
dd6e2e |
Strings: APC ("Application Program Command"), PM ("Privacy Message"),
|
|
Takashi Iwai |
dd6e2e |
and DCS ("Device Control String"). They are handled similarly to OSC in
|
|
Takashi Iwai |
dd6e2e |
terms of termination.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
Source: vt100.net
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
Add three new enumerated states, one for each of these types. All three
|
|
Takashi Iwai |
dd6e2e |
are handled the same way right now--they simply consume input until
|
|
Takashi Iwai |
dd6e2e |
terminated. I hope to expand upon this firmament in the future. Add
|
|
Takashi Iwai |
dd6e2e |
new predicate ansi_control_string(), returning true for any of these
|
|
Takashi Iwai |
dd6e2e |
states. Replace explicit checks against ESosc with calls to this
|
|
Takashi Iwai |
dd6e2e |
function. Transition to these states appropriately from the escape
|
|
Takashi Iwai |
dd6e2e |
initiation (ESesc) state.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
This was motivated by the following Notcurses bugs:
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
https://github.com/dankamongmen/notcurses/issues/2050
|
|
Takashi Iwai |
dd6e2e |
https://github.com/dankamongmen/notcurses/issues/1828
|
|
Takashi Iwai |
dd6e2e |
https://github.com/dankamongmen/notcurses/issues/2069
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
where standard VT sequences are not consumed by the Linux console. It's
|
|
Takashi Iwai |
dd6e2e |
not necessary that the Linux console *support* these sequences, but it
|
|
Takashi Iwai |
dd6e2e |
ought *consume* these well-specified classes of sequences.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
Tested by sending a variety of escape sequences to the console, and
|
|
Takashi Iwai |
dd6e2e |
verifying that they still worked, or were now properly consumed.
|
|
Takashi Iwai |
dd6e2e |
Verified that the escapes were properly terminated at a generic level.
|
|
Takashi Iwai |
dd6e2e |
Verified that the Notcurses tools continued to show expected output on
|
|
Takashi Iwai |
dd6e2e |
the Linux console, except now without escape bleedthrough.
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
Link: https://lore.kernel.org/lkml/YSydL0q8iaUfkphg@schwarzgerat.orthanc/
|
|
Takashi Iwai |
dd6e2e |
Signed-off-by: nick black <dankamongmen@gmail.com>
|
|
Takashi Iwai |
dd6e2e |
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Takashi Iwai |
dd6e2e |
Cc: Jiri Slaby <jirislaby@kernel.org>
|
|
Takashi Iwai |
dd6e2e |
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
|
|
Takashi Iwai |
dd6e2e |
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
Takashi Iwai |
dd6e2e |
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Takashi Iwai |
dd6e2e |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Takashi Iwai |
dd6e2e |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
---
|
|
Takashi Iwai |
dd6e2e |
drivers/tty/vt/vt.c | 31 +++++++++++++++++++++++++++----
|
|
Takashi Iwai |
dd6e2e |
1 file changed, 27 insertions(+), 4 deletions(-)
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
|
|
Takashi Iwai |
dd6e2e |
index ef981d3b7bb4..cb72393f92d3 100644
|
|
Takashi Iwai |
dd6e2e |
--- a/drivers/tty/vt/vt.c
|
|
Takashi Iwai |
dd6e2e |
+++ b/drivers/tty/vt/vt.c
|
|
Takashi Iwai |
dd6e2e |
@@ -2059,7 +2059,7 @@ static void restore_cur(struct vc_data *vc)
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
|
|
Takashi Iwai |
dd6e2e |
EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
|
|
Takashi Iwai |
dd6e2e |
- ESpalette, ESosc };
|
|
Takashi Iwai |
dd6e2e |
+ ESpalette, ESosc, ESapc, ESpm, ESdcs };
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
/* console_lock is held (except via vc_init()) */
|
|
Takashi Iwai |
dd6e2e |
static void reset_terminal(struct vc_data *vc, int do_clear)
|
|
Takashi Iwai |
dd6e2e |
@@ -2133,20 +2133,28 @@ static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
|
|
Takashi Iwai |
dd6e2e |
vc->vc_translate = set_translate(*charset, vc);
|
|
Takashi Iwai |
dd6e2e |
}
|
|
Takashi Iwai |
dd6e2e |
|
|
Takashi Iwai |
dd6e2e |
+/* is this state an ANSI control string? */
|
|
Takashi Iwai |
dd6e2e |
+static bool ansi_control_string(unsigned int state)
|
|
Takashi Iwai |
dd6e2e |
+{
|
|
Takashi Iwai |
dd6e2e |
+ if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
|
|
Takashi Iwai |
dd6e2e |
+ return true;
|
|
Takashi Iwai |
dd6e2e |
+ return false;
|
|
Takashi Iwai |
dd6e2e |
+}
|
|
Takashi Iwai |
dd6e2e |
+
|
|
Takashi Iwai |
dd6e2e |
/* console_lock is held */
|
|
Takashi Iwai |
dd6e2e |
static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
|
|
Takashi Iwai |
dd6e2e |
{
|
|
Takashi Iwai |
dd6e2e |
/*
|
|
Takashi Iwai |
dd6e2e |
* Control characters can be used in the _middle_
|
|
Takashi Iwai |
dd6e2e |
- * of an escape sequence.
|
|
Takashi Iwai |
dd6e2e |
+ * of an escape sequence, aside from ANSI control strings.
|
|
Takashi Iwai |
dd6e2e |
*/
|
|
Takashi Iwai |
dd6e2e |
- if (vc->vc_state == ESosc && c>=8 && c<=13) /* ... except for OSC */
|
|
Takashi Iwai |
dd6e2e |
+ if (ansi_control_string(vc->vc_state) && c >= 8 && c <= 13)
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
switch (c) {
|
|
Takashi Iwai |
dd6e2e |
case 0:
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
case 7:
|
|
Takashi Iwai |
dd6e2e |
- if (vc->vc_state == ESosc)
|
|
Takashi Iwai |
dd6e2e |
+ if (ansi_control_string(vc->vc_state))
|
|
Takashi Iwai |
dd6e2e |
vc->vc_state = ESnormal;
|
|
Takashi Iwai |
dd6e2e |
else if (vc->vc_bell_duration)
|
|
Takashi Iwai |
dd6e2e |
kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
|
|
Takashi Iwai |
dd6e2e |
@@ -2207,6 +2215,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
|
|
Takashi Iwai |
dd6e2e |
case ']':
|
|
Takashi Iwai |
dd6e2e |
vc->vc_state = ESnonstd;
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
+ case '_':
|
|
Takashi Iwai |
dd6e2e |
+ vc->vc_state = ESapc;
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
+ case '^':
|
|
Takashi Iwai |
dd6e2e |
+ vc->vc_state = ESpm;
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
case '%':
|
|
Takashi Iwai |
dd6e2e |
vc->vc_state = ESpercent;
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
@@ -2224,6 +2238,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
|
|
Takashi Iwai |
dd6e2e |
if (vc->state.x < VC_TABSTOPS_COUNT)
|
|
Takashi Iwai |
dd6e2e |
set_bit(vc->state.x, vc->vc_tab_stop);
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
+ case 'P':
|
|
Takashi Iwai |
dd6e2e |
+ vc->vc_state = ESdcs;
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
case 'Z':
|
|
Takashi Iwai |
dd6e2e |
respond_ID(tty);
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
@@ -2520,8 +2537,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
|
|
Takashi Iwai |
dd6e2e |
vc_setGx(vc, 1, c);
|
|
Takashi Iwai |
dd6e2e |
vc->vc_state = ESnormal;
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
+ case ESapc:
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
case ESosc:
|
|
Takashi Iwai |
dd6e2e |
return;
|
|
Takashi Iwai |
dd6e2e |
+ case ESpm:
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
+ case ESdcs:
|
|
Takashi Iwai |
dd6e2e |
+ return;
|
|
Takashi Iwai |
dd6e2e |
default:
|
|
Takashi Iwai |
dd6e2e |
vc->vc_state = ESnormal;
|
|
Takashi Iwai |
dd6e2e |
}
|
|
Takashi Iwai |
dd6e2e |
--
|
|
Takashi Iwai |
dd6e2e |
2.26.2
|
|
Takashi Iwai |
dd6e2e |
|