linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] console: consume APC, DM, DCS
@ 2021-08-30  8:56 nick black
  2021-08-30  9:17 ` Jiri Slaby
  0 siblings, 1 reply; 7+ messages in thread
From: nick black @ 2021-08-30  8:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Jiri Slaby, Tetsuo Handa, Daniel Vetter, linux-kernel,
	nick black, Linus Torvalds

console: consume APC, DM, DCS

The Linux console's VT102 implementation already
consumes OSC ("Operating System Command") sequences,
probably because that's how palette changes are
transmitted. In addition to OSC, there are three other
major clases of ANSI control strings: APC ("Application
Program Command"), PM ("Privacy Message", and DCS
("Device Control String"). They are handled similarly
to OSC in terms of termination.

Source: vt100.net

Add three new enumerated states, one for each of these
types. All three are handled the same way right now--they
simply consume input until terminated. I hope to expand
upon this firmament in the future. Add new predicate
ansi_control_string(), returning true for any of these
states. Replace explicit checks against ESosc with calls
to this function. Transition to these states appropriately
from the escape initiation (ESesc) state.

This was motivated by the following Notcurses bugs:

 https://github.com/dankamongmen/notcurses/issues/2050
 https://github.com/dankamongmen/notcurses/issues/1828
 https://github.com/dankamongmen/notcurses/issues/2069

where standard VT sequences are not consumed by the
Linux console. It's not necessary that the Linux console
*support* these sequences, but it ought *consume* these
well-specified classes of sequences.

Tested by sending a variety of escape sequences to the
console, and verifying that they still worked, or were
now properly consumed. Verified that the escapes were
properly terminated at a generic level. Verified that
the Notcurses tools continued to show expected output on
the Linux console, except now without escape bleedthrough.

Signed-off-by: nick black <dankamongmen@gmail.com>
---
diff --git drivers/tty/vt/vt.c drivers/tty/vt/vt.c
index ef981d3b7bb4..62b77ee3f8d1 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2059,7 +2059,7 @@ static void restore_cur(struct vc_data *vc)
 
 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
 	EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
-	ESpalette, ESosc };
+	ESpalette, ESosc, ESapc, ESpm, ESdcs };
 
 /* console_lock is held (except via vc_init()) */
 static void reset_terminal(struct vc_data *vc, int do_clear)
@@ -2133,20 +2133,28 @@ static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
 		vc->vc_translate = set_translate(*charset, vc);
 }
 
+/* is this state an ANSI control string? */
+static bool ansi_control_string(unsigned int state)
+{
+	if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
+		return true;
+	return false;
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 {
 	/*
 	 *  Control characters can be used in the _middle_
-	 *  of an escape sequence.
+	 *  of an escape sequence, aside from ANSI control strings.
 	 */
-	if (vc->vc_state == ESosc && c>=8 && c<=13) /* ... except for OSC */
+	if (ansi_control_string(vc->vc_state) && c >= 8 && c <= 13)
 		return;
 	switch (c) {
 	case 0:
 		return;
 	case 7:
-		if (vc->vc_state == ESosc)
+		if (ansi_control_string(vc->vc_state))
 			vc->vc_state = ESnormal;
 		else if (vc->vc_bell_duration)
 			kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
@@ -2207,6 +2215,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case ']':
 			vc->vc_state = ESnonstd;
 			return;
+		case '_':
+			vc->vc_state = ESapc;
+			return;
+		case '^':
+			vc->vc_state = ESpm;
+			return;
 		case '%':
 			vc->vc_state = ESpercent;
 			return;
@@ -2224,6 +2238,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			if (vc->state.x < VC_TABSTOPS_COUNT)
 				set_bit(vc->state.x, vc->vc_tab_stop);
 			return;
+		case 'P':
+			vc->vc_state = ESdcs;
+			return;
 		case 'Z':
 			respond_ID(tty);
 			return;
@@ -2520,8 +2537,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		vc_setGx(vc, 1, c);
 		vc->vc_state = ESnormal;
 		return;
+	case ESapc:
+		return;
 	case ESosc:
 		return;
+	case ESpm:
+		return;
+	case ESdcs:
+		return;
 	default:
 		vc->vc_state = ESnormal;
 	}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] console: consume APC, DM, DCS
  2021-08-30  8:56 [PATCH] console: consume APC, DM, DCS nick black
@ 2021-08-30  9:17 ` Jiri Slaby
  2021-08-30  9:59   ` nick black
  0 siblings, 1 reply; 7+ messages in thread
From: Jiri Slaby @ 2021-08-30  9:17 UTC (permalink / raw)
  To: nick black, Greg Kroah-Hartman
  Cc: Tetsuo Handa, Daniel Vetter, linux-kernel, Linus Torvalds

On 30. 08. 21, 10:56, nick black wrote:
> console: consume APC, DM, DCS
> 
> The Linux console's VT102 implementation already
> consumes OSC ("Operating System Command") sequences,
> probably because that's how palette changes are
> transmitted. In addition to OSC, there are three other
> major clases of ANSI control strings: APC ("Application
> Program Command"), PM ("Privacy Message", and DCS
> ("Device Control String"). They are handled similarly
> to OSC in terms of termination.
> 
> Source: vt100.net
> 
> Add three new enumerated states, one for each of these
> types. All three are handled the same way right now--they
> simply consume input until terminated. I hope to expand
> upon this firmament in the future. Add new predicate
> ansi_control_string(), returning true for any of these
> states. Replace explicit checks against ESosc with calls
> to this function. Transition to these states appropriately
> from the escape initiation (ESesc) state.
> 
> This was motivated by the following Notcurses bugs:
> 
>   https://github.com/dankamongmen/notcurses/issues/2050
>   https://github.com/dankamongmen/notcurses/issues/1828
>   https://github.com/dankamongmen/notcurses/issues/2069
> 
> where standard VT sequences are not consumed by the
> Linux console. It's not necessary that the Linux console
> *support* these sequences, but it ought *consume* these
> well-specified classes of sequences.
> 
> Tested by sending a variety of escape sequences to the
> console, and verifying that they still worked, or were
> now properly consumed. Verified that the escapes were
> properly terminated at a generic level. Verified that
> the Notcurses tools continued to show expected output on
> the Linux console, except now without escape bleedthrough.
> 
> Signed-off-by: nick black <dankamongmen@gmail.com>
> ---
> diff --git drivers/tty/vt/vt.c drivers/tty/vt/vt.c
> index ef981d3b7bb4..62b77ee3f8d1 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -2059,7 +2059,7 @@ static void restore_cur(struct vc_data *vc)
>   
>   enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
>   	EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
> -	ESpalette, ESosc };
> +	ESpalette, ESosc, ESapc, ESpm, ESdcs };
>   
>   /* console_lock is held (except via vc_init()) */
>   static void reset_terminal(struct vc_data *vc, int do_clear)
> @@ -2133,20 +2133,28 @@ static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
>   		vc->vc_translate = set_translate(*charset, vc);
>   }
>   
> +/* is this state an ANSI control string? */
> +static bool ansi_control_string(unsigned int state)
> +{
> +	if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
> +		return true;
> +	return false;

So simply:
return state == ESosc || state == ESapc || state == ESpm || state == ESdcs;

I wonder if we can simply hide them all behind single ESignore?

> +}
> +
>   /* console_lock is held */
>   static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
>   {
>   	/*
>   	 *  Control characters can be used in the _middle_
> -	 *  of an escape sequence.
> +	 *  of an escape sequence, aside from ANSI control strings.
>   	 */
> -	if (vc->vc_state == ESosc && c>=8 && c<=13) /* ... except for OSC */
> +	if (ansi_control_string(vc->vc_state) && c >= 8 && c <= 13)
>   		return;
>   	switch (c) {
>   	case 0:
>   		return;
>   	case 7:
> -		if (vc->vc_state == ESosc)
> +		if (ansi_control_string(vc->vc_state))
>   			vc->vc_state = ESnormal;
>   		else if (vc->vc_bell_duration)
>   			kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
> @@ -2207,6 +2215,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
>   		case ']':
>   			vc->vc_state = ESnonstd;
>   			return;
> +		case '_':
> +			vc->vc_state = ESapc;
> +			return;
> +		case '^':
> +			vc->vc_state = ESpm;
> +			return;
>   		case '%':
>   			vc->vc_state = ESpercent;
>   			return;
> @@ -2224,6 +2238,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
>   			if (vc->state.x < VC_TABSTOPS_COUNT)
>   				set_bit(vc->state.x, vc->vc_tab_stop);
>   			return;
> +		case 'P':
> +			vc->vc_state = ESdcs;
> +			return;
>   		case 'Z':
>   			respond_ID(tty);
>   			return;
> @@ -2520,8 +2537,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
>   		vc_setGx(vc, 1, c);
>   		vc->vc_state = ESnormal;
>   		return;
> +	case ESapc:
> +		return;
>   	case ESosc:
>   		return;
> +	case ESpm:
> +		return;
> +	case ESdcs:
> +		return;
>   	default:
>   		vc->vc_state = ESnormal;
>   	}
> 


-- 
js
suse labs

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] console: consume APC, DM, DCS
  2021-08-30  9:17 ` Jiri Slaby
@ 2021-08-30  9:59   ` nick black
  2021-08-30 15:31     ` Linus Torvalds
  0 siblings, 1 reply; 7+ messages in thread
From: nick black @ 2021-08-30  9:59 UTC (permalink / raw)
  To: Jiri Slaby
  Cc: Greg Kroah-Hartman, Tetsuo Handa, Daniel Vetter, linux-kernel,
	Linus Torvalds

Jiri Slaby left as an exercise for the reader:
> So simply:
> return state == ESosc || state == ESapc || state == ESpm || state == ESdcs;

Sure, I can do this. Would you like me to recut the patch?

> I wonder if we can simply hide them all behind single ESignore?

I'd rather not--I have plans beyond this patch which will
require differentiating between them.

-- 
nick black -=- https://www.nick-black.com
to make an apple pie from scratch,
you need first invent a universe.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] console: consume APC, DM, DCS
  2021-08-30  9:59   ` nick black
@ 2021-08-30 15:31     ` Linus Torvalds
  2021-08-30 15:37       ` Linus Torvalds
  0 siblings, 1 reply; 7+ messages in thread
From: Linus Torvalds @ 2021-08-30 15:31 UTC (permalink / raw)
  To: nick black
  Cc: Jiri Slaby, Greg Kroah-Hartman, Tetsuo Handa, Daniel Vetter,
	Linux Kernel Mailing List

On Mon, Aug 30, 2021 at 2:59 AM nick black <dankamongmen@gmail.com> wrote:
>
> Jiri Slaby left as an exercise for the reader:
> > So simply:
> > return state == ESosc || state == ESapc || state == ESpm || state == ESdcs;
>
> Sure, I can do this. Would you like me to recut the patch?
>
> > I wonder if we can simply hide them all behind single ESignore?
>
> I'd rather not--I have plans beyond this patch which will
> require differentiating between them.

I've applied the patch as-is since I'm starting my merge window work
with "random patches in my queue".

I'm not 100% sure we care all that much about trying to make the
console be more vt100-compatible, considering how long we've been at
the current state.

But I have to admit to being slightly emotionally attached to us doing
reasonably well on this side. One of the original things Linux did was
console emulation, even before it was an OS..

                   Linus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] console: consume APC, DM, DCS
  2021-08-30 15:31     ` Linus Torvalds
@ 2021-08-30 15:37       ` Linus Torvalds
  2021-08-30 15:50         ` nick black
  0 siblings, 1 reply; 7+ messages in thread
From: Linus Torvalds @ 2021-08-30 15:37 UTC (permalink / raw)
  To: nick black
  Cc: Jiri Slaby, Greg Kroah-Hartman, Tetsuo Handa, Daniel Vetter,
	Linux Kernel Mailing List

On Mon, Aug 30, 2021 at 8:31 AM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> I've applied the patch as-is since I'm starting my merge window work
> with "random patches in my queue".

Side note: it would have been nice to see "v2: whitespace changes" or
something in the patch description, below the "---" that cuts off the
commit message.

I had your previous patch version pending, and had to check what had
changed in the re-send.

               Linus

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] console: consume APC, DM, DCS
  2021-08-30 15:37       ` Linus Torvalds
@ 2021-08-30 15:50         ` nick black
  0 siblings, 0 replies; 7+ messages in thread
From: nick black @ 2021-08-30 15:50 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jiri Slaby, Greg Kroah-Hartman, Tetsuo Handa, Daniel Vetter,
	Linux Kernel Mailing List

Linus Torvalds left as an exercise for the reader:
> Side note: it would have been nice to see "v2: whitespace changes" or
> something in the patch description, below the "---" that cuts off the
> commit message.
> I had your previous patch version pending, and had to check what had
> changed in the re-send.

thanks for the feedback and heads-up. i'm looking to do some
further work in this area over coming weeks, so i'm glad to hear
you're interested in it =]. this patch was not just conformance
for conformance's sake -- Notcurses is doing several queries
which leave nastiness on the screen without this.

thanks for the merge! =]

-- 
nick black -=- https://www.nick-black.com
to make an apple pie from scratch,
you need first invent a universe.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] console: consume APC, DM, DCS
@ 2021-08-19  3:48 nick black
  0 siblings, 0 replies; 7+ messages in thread
From: nick black @ 2021-08-19  3:48 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Linus Torvalds, linux-kernel; +Cc: nick black

From: nick black <nickblack@linux.com>

console: consume APC, DM, DCS

The Linux console's VT102 implementation already
consumes OSC ("Operating System Command") sequences,
probably because that's how palette changes are
transmitted. In addition to OSC, there are three other
major clases of ANSI control strings: APC ("Application
Program Command"), PM ("Privacy Message", and DCS
("Device Control String"). They are handled similarly
to OSC in terms of termination.

Source: vt100.net

Add three new enumerated states, one for each of these
types. All three are handled the same way right now--they
simply consume input until terminated. I hope to expand
upon this firmament in the future. Add new predicate
ansi_control_string(), returning true for any of these
states. Replace explicit checks against ESosc with calls
to this function. Transition to these states appropriately
from the escape initiation (ESesc) state.

This was motivated by the following Notcurses bugs:

 https://github.com/dankamongmen/notcurses/issues/2050
 https://github.com/dankamongmen/notcurses/issues/1828
 https://github.com/dankamongmen/notcurses/issues/2069

where standard VT sequences are not consumed by the
Linux console. It's not necessary that the Linux console
*support* these sequences, but it ought *consume* these
well-specified classes of sequences.

Tested by sending a variety of escape sequences to the
console, and verifying that they still worked, or were
now properly consumed. Verified that the escapes were
properly terminated at a generic level. Verified that
the Notcurses tools continued to show expected output on
the Linux console, except now without escape bleedthrough.

Signed-off-by: Nick Black <nickblack@linux.com>
---
 drivers/tty/vt/vt.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git drivers/tty/vt/vt.c drivers/tty/vt/vt.c
index ef981d3b7bb4..62b77ee3f8d1 100644
--- drivers/tty/vt/vt.c
+++ drivers/tty/vt/vt.c
@@ -2059,7 +2059,7 @@ static void restore_cur(struct vc_data *vc)
 
 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
 	EShash, ESsetG0, ESsetG1, ESpercent, EScsiignore, ESnonstd,
-	ESpalette, ESosc };
+	ESpalette, ESosc, ESapc, ESpm, ESdcs };
 
 /* console_lock is held (except via vc_init()) */
 static void reset_terminal(struct vc_data *vc, int do_clear)
@@ -2133,20 +2133,28 @@ static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
 		vc->vc_translate = set_translate(*charset, vc);
 }
 
+/* is this state an ANSI control string? */
+static bool ansi_control_string(unsigned state)
+{
+	if (state == ESosc || state == ESapc || state == ESpm || state == ESdcs)
+		return true;
+	return false;
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 {
 	/*
 	 *  Control characters can be used in the _middle_
-	 *  of an escape sequence.
+	 *  of an escape sequence, aside from ANSI control strings.
 	 */
-	if (vc->vc_state == ESosc && c>=8 && c<=13) /* ... except for OSC */
+	if (ansi_control_string(vc->vc_state) && c>=8 && c<=13)
 		return;
 	switch (c) {
 	case 0:
 		return;
 	case 7:
-		if (vc->vc_state == ESosc)
+		if (ansi_control_string(vc->vc_state))
 			vc->vc_state = ESnormal;
 		else if (vc->vc_bell_duration)
 			kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
@@ -2207,6 +2215,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case ']':
 			vc->vc_state = ESnonstd;
 			return;
+		case '_':
+			vc->vc_state = ESapc;
+			return;
+		case '^':
+			vc->vc_state = ESpm;
+			return;
 		case '%':
 			vc->vc_state = ESpercent;
 			return;
@@ -2224,6 +2238,9 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			if (vc->state.x < VC_TABSTOPS_COUNT)
 				set_bit(vc->state.x, vc->vc_tab_stop);
 			return;
+		case 'P':
+			vc->vc_state = ESdcs;
+			return;
 		case 'Z':
 			respond_ID(tty);
 			return;
@@ -2520,8 +2537,14 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		vc_setGx(vc, 1, c);
 		vc->vc_state = ESnormal;
 		return;
+	case ESapc:
+		return;
 	case ESosc:
 		return;
+	case ESpm:
+		return;
+	case ESdcs:
+		return;
 	default:
 		vc->vc_state = ESnormal;
 	}
-- 
2.33.0

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-08-30 15:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-30  8:56 [PATCH] console: consume APC, DM, DCS nick black
2021-08-30  9:17 ` Jiri Slaby
2021-08-30  9:59   ` nick black
2021-08-30 15:31     ` Linus Torvalds
2021-08-30 15:37       ` Linus Torvalds
2021-08-30 15:50         ` nick black
  -- strict thread matches above, loose matches on Subject: below --
2021-08-19  3:48 nick black

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).