NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/56173: libcurses: reset_prog_mode() after reset_shell_mode() overwrites original TTY state
The following reply was made to PR lib/56173; it has been noted by GNATS.
From: Christos Zoulas <christos%zoulas.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: lib-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost,
netbsd-bugs%netbsd.org@localhost
Subject: Re: lib/56173: libcurses: reset_prog_mode() after reset_shell_mode()
overwrites original TTY state
Date: Mon, 31 May 2021 13:07:09 -0400
--Apple-Mail=_6F304CAD-4C8E-4B9A-8419-26EA703F25C3
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=us-ascii
This program behaves very differently under ncurses and curses:
include <stdio.h>
#include <curses.h>
#include <stdlib.h>
int
main(void)
{
printf("\r\ninitially\n");
system("stty -a");
initscr();
printf("\r\nafter initscr\n");
system("stty -a");
reset_shell_mode();
printf("\r\nafter reset_shell_mode\n");
system("stty -a");
reset_prog_mode();
printf("\r\nafter reset_prog_mode\n");
system("stty -a");
endwin();
printf("\r\nafter endwin\n");
system("stty -a");
return 0;
}
The question is who is right?
christos
> On May 15, 2021, at 12:15 AM, mforney%mforney.org@localhost wrote:
>=20
>> Number: 56173
>> Category: lib
>> Synopsis: libcurses: reset_prog_mode() after reset_shell_mode() =
overwrites original TTY state
>> Confidential: no
>> Severity: serious
>> Priority: medium
>> Responsible: lib-bug-people
>> State: open
>> Class: sw-bug
>> Submitter-Id: net
>> Arrival-Date: Sat May 15 04:15:00 +0000 2021
>> Originator: Michael Forney
>> Release: trunk
>> Organization:
>> Environment:
>> Description:
> If a curses program calls reset_shell_mode() and then =
reset_prog_mode() to temporarily switch to shell mode and then back to =
curses mode, the original TTY settings are overwritten. This results in =
incorrect TTY settings after the application exits.
>=20
> This pattern is used in the text editor vis when you read output from =
a shell command.
>=20
> The problem seems to be that reset_shell_mode() calls __stopwin() to =
save the curses mode settings and restore the shell mode settings, but =
reset_prog_mode() just restores the saved curses mode settings, leaving =
the screen in the "endwin" state. Then, when the application performs a =
refresh(), __restartwin() is called which saves the current (already =
restored) settings as the original settings, and then restores the =
curses mode settings again. At this point, the original settings have =
been overwritten with the curses mode settings, which persist even after =
the application calls endwin() and exits.
>=20
> In other words, the following sequence of events occurs:
>=20
> reset_shell_mode()
> __stopwin()
> saved settings =3D current settings
> current settings =3D original settings
> endwin =3D 1
> reset_prog_mode()
> current settings =3D saved settings
> refresh()
> __restartwin()
> original settings =3D current settings
> current settings =3D saved settings
>=20
> At this point we have original settings =3D=3D current settings =3D=3D =
curses mode settings. The original settings have been overwritten.
>=20
> It appears that this behavior dates back to this commit from 2003:
> =
https://github.com/NetBSD/src/commit/880234af7eb36a86d6adfa775327ccec592d5=
19d#diff-3825aa201b54dbfe36d66fe3f650737571d39e3459b936691d1c955f37871d2dL=
199-R204
>=20
> Previously, reset_shell_mode() and reset_prog_mode() were symmetrical, =
calling __endwin() and __restartwin() respectively. After the change, =
reset_shell_mode() still calls __endwin(), but reset_prog_mode() just =
changes the TTY settings leaving the screen in the endwin state.
>> How-To-Repeat:
> 1. Build vis (https://github.com/martanne/vis) against NetBSD =
libcurses, then run it.
> 2. Type ":<echo hello" to read the output of a command into the =
buffer.
> 3. Exit vis with ":q!".
> 4. Terminal settings are now messed up.
>> Fix:
> I don't quite understand what problem the commit referenced above was =
attempting to fix, but if I revert the highlighted hunk, the problem is =
fixed.
>=20
> diff --git a/lib/libcurses/tstp.c b/lib/libcurses/tstp.c
> index f0baa999120b..ef54143a4a54 100644
> --- a/lib/libcurses/tstp.c
> +++ b/lib/libcurses/tstp.c
> @@ -348,8 +348,8 @@ int
> reset_prog_mode(void)
> {
>=20
> - return tcsetattr(fileno(_cursesi_screen->infd), TCSASOFT | =
TCSADRAIN,
> - &_cursesi_screen->save_termios) ? ERR : OK;
> + __restartwin();
> + return OK;
> }
>=20
> int
--Apple-Mail=_6F304CAD-4C8E-4B9A-8419-26EA703F25C3
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename=signature.asc
Content-Type: application/pgp-signature;
name=signature.asc
Content-Description: Message signed with OpenPGP
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - http://gpgtools.org
iF0EARECAB0WIQS+BJlbqPkO0MDBdsRxESqxbLM7OgUCYLUXvQAKCRBxESqxbLM7
OgDzAJ4ulhf4OsPZOcIHyjSKH7O1HGY2bACg4cqhYJXyUIGVEA8bACdHAZpFM70=
=od53
-----END PGP SIGNATURE-----
--Apple-Mail=_6F304CAD-4C8E-4B9A-8419-26EA703F25C3--
Home |
Main Index |
Thread Index |
Old Index