NetBSD Problem Report #56779
From mac@arm64.localdomain Tue Apr 5 06:13:25 2022
Return-Path: <mac@arm64.localdomain>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id BFAA51A921F
for <gnats-bugs@gnats.NetBSD.org>; Tue, 5 Apr 2022 06:13:25 +0000 (UTC)
Message-Id: <20220405045415.B7AEA23AC1@arm64.localdomain>
Date: Tue, 5 Apr 2022 04:54:15 +0000 (UTC)
From: mac@culver.net
Reply-To: mac@culver.net
To: gnats-bugs@NetBSD.org
Subject: RAW mode on the TTY always returns EOF (-1)
X-Send-Pr-Version: 3.95
>Number: 56779
>Category: kern
>Synopsis: RAW mode on the TTY always returns EOF (-1)
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Apr 05 06:15:00 +0000 2022
>Last-Modified: Tue Apr 05 16:30:01 +0000 2022
>Originator: mac@culver.net
>Release: NetBSD 9.99.96
>Organization:
>Environment:
System: NetBSD arm64 9.99.96 NetBSD 9.99.96 (G64) #1: Tue Apr 5 04:22:19 UTC 2022 mac@arm64:/usr/obj/sys/arch/evbarm/compile/G64 evbarm
Architecture: aarch64
Machine: evbarm
>Description:
The attached program, below, is supposed to put the terminal in RAW mode,
and echo back characters, until the character 'c' is typed, at which point
the program ends.
Instead, getchar() always returns -1 independent of any characters being typed
>How-To-Repeat:
#include <stdio.h>
#include <unistd.h> // STDIN_FILENO, isatty(), ttyname()
#include <stdlib.h> // exit()
#include <termios.h>
int main() {
struct termios tty_opts_backup, tty_opts_raw;
if (!isatty(STDIN_FILENO)) {
printf("Error: stdin is not a TTY\n");
exit(1);
}
printf("stdin is %s\n", ttyname(STDIN_FILENO));
// Back up current TTY settings
tcgetattr(STDIN_FILENO, &tty_opts_backup);
// Change TTY settings to raw mode
cfmakeraw(&tty_opts_raw);
tty_opts_raw.c_ispeed = tty_opts_backup.c_ispeed;
tty_opts_raw.c_ospeed = tty_opts_backup.c_ospeed;
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
// Read and print characters from stdin
int c, i = 1;
for (c = getchar(); c != 99; c = getchar()) { // 99 = 'c'
printf("%d. 0x%02x (0%02o)\r\n", i++, c, c);
}
printf("You typed 0x03 (003). Exiting.\r\n");
// Restore previous TTY settings
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_backup);
}
>Fix:
>Audit-Trail:
From: mlelstv@serpens.de (Michael van Elst)
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)
Date: Tue, 5 Apr 2022 07:35:51 -0000 (UTC)
mac@culver.net writes:
> // Back up current TTY settings
> tcgetattr(STDIN_FILENO, &tty_opts_backup);
> // Change TTY settings to raw mode
> cfmakeraw(&tty_opts_raw);
> tty_opts_raw.c_ispeed = tty_opts_backup.c_ispeed;
> tty_opts_raw.c_ospeed = tty_opts_backup.c_ospeed;
> tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
Try:
tty_opts_raw = tty_opts_backup;
cfmakeraw(&tty_opts_raw);
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
cfmakeraw changes the configuration in a termios structure,
but it doesn't magically initialize values. Your code
just uses random stack content with unpredictable results.
From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)
Date: Tue, 5 Apr 2022 07:50:35 +0000 (UTC)
On Tue, 5 Apr 2022, mac@culver.net wrote:
> // Change TTY settings to raw mode
> cfmakeraw(&tty_opts_raw);
> tty_opts_raw.c_ispeed = tty_opts_backup.c_ispeed;
> tty_opts_raw.c_ospeed = tty_opts_backup.c_ospeed;
> tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
>
You have to initialize `tty_opts_raw' first before calling
cfmakeraw():
tty_opts_raw = tty_opts_backup;
cfmakeraw(&tty_opts_raw);
Otherwise, you will have junk in most of your structure. Try
a `stty -a -f ...' to see.
-RVP
From: RVP <rvp@SDF.ORG>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)
Date: Tue, 5 Apr 2022 08:17:19 +0000 (UTC)
On Tue, 5 Apr 2022, Michael van Elst wrote:
> cfmakeraw changes the configuration in a termios structure,
> but it doesn't magically initialize values. Your code
> just uses random stack content with unpredictable results.
>
c_cc[VMIN] = 1;
c_cc[VTIME] = 0;
can also be done in src/lib/libc/termios/cfmakeraw.c, I think.
-RVP
From: Michael Cheponis <michael.cheponis@gmail.com>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
mac@culver.net
Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)
Date: Tue, 5 Apr 2022 09:27:46 -0700
--000000000000c6c87705dbeabb18
Content-Type: text/plain; charset="UTF-8"
Thanks, you know, I read :
"the correct method is for
an application to snapshot the current terminal state using the
function
tcgetattr, setting raw mode with cfmakeraw and the subsequent
tcsetattr,
and then using another tcsetattr with the saved state to revert to the
previous terminal state."
This English is less-clear than a code example:
*tcgetattr(STDIN_FILENO, &tty_opts_backup);*
*tty_opts_raw = tty_opts_backup;*
*cfmakeraw(&tty_opts_raw);*
*tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);*
*<later in code, to revert RAW>*
*tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_backup);*
I think what threw me off is: the code, as-was (w/o assignment of structs)
works fine on WSL under Windows; and also linux/arm.
Maybe it'd be better to call "cfmakeraw()" something like
"cf-sort-of-makeraw()" ? ;-) since it doesn't actually *make* things raw.
Or, of course, simply 'fix' makeraw() to be compliant w/linux?
Thanks for the super-prompt reply.
My suggestions:
1) Add a Code Example to the TCSETATTR (3) page
2) Change behavior of cfmakeraw() to be consistent w/linux
3) I'm only kidding about changing the name.
-Mike
On Tue, Apr 5, 2022 at 1:20 AM RVP <rvp@sdf.org> wrote:
> The following reply was made to PR kern/56779; it has been noted by GNATS.
>
> From: RVP <rvp@SDF.ORG>
> To: gnats-bugs@netbsd.org
> Cc:
> Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)
> Date: Tue, 5 Apr 2022 08:17:19 +0000 (UTC)
>
> On Tue, 5 Apr 2022, Michael van Elst wrote:
>
> > cfmakeraw changes the configuration in a termios structure,
> > but it doesn't magically initialize values. Your code
> > just uses random stack content with unpredictable results.
> >
>
> c_cc[VMIN] = 1;
> c_cc[VTIME] = 0;
>
> can also be done in src/lib/libc/termios/cfmakeraw.c, I think.
>
> -RVP
>
>
--000000000000c6c87705dbeabb18
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_default" style=3D"fon=
t-family:arial,helvetica,sans-serif;font-size:small">Thanks, you know, I re=
ad :</div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica=
,sans-serif;font-size:small"><br></div><div class=3D"gmail_default" style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small">"<span sty=
le=3D"font-family:Arial,Helvetica,sans-serif">the correct method is for</sp=
an></div>=C2=A0 =C2=A0 =C2=A0an application to snapshot the current termina=
l state using the function<br>=C2=A0 =C2=A0 =C2=A0tcgetattr, setting raw mo=
de with cfmakeraw and the subsequent tcsetattr,<br>=C2=A0 =C2=A0 =C2=A0and =
then using another tcsetattr with the saved state to revert to the<br>=C2=
=A0 =C2=A0 =C2=A0previous terminal state.<span class=3D"gmail_default" styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small">"</span><=
div><span class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans=
-serif;font-size:small"><br></span></div><div><span class=3D"gmail_default"=
style=3D"font-family:arial,helvetica,sans-serif;font-size:small">This Engl=
ish is less-clear than a code example:</span><br></div><div><span class=3D"=
gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all"><br></span></div></div><blockquote style=3D"margin:0 0 0 40px;border:n=
one;padding:0px"><div><div><font size=3D"1">tcgetattr(STDIN_FILENO, &=
;tty_opts_backup);</font></div><div><font size=3D"1"><b style=3D"font-f=
amily:monospace">tty_opts_raw =3D tty_opts_backup;<br></font></div></di=
v><div><div><span class=3D"gmail_default" style=3D""><font face=3D"monospac=
e" style=3D"" size=3D"1">cfmakeraw(&tty_opts_raw);</f=
ont></span></div></div><div><div><span class=3D"gmail_default" style=3D""><=
font face=3D"monospace" style=3D"" size=3D"1">tcsetattr(STDIN=
_FILENO, TCSANOW, &tty_opts_raw);</font></span></div></div><div><di=
v><span class=3D"gmail_default" style=3D""><font face=3D"monospace" size=3D=
"1"><br></font></span></div></div><div><div><div class=3D"gmail_defa=
ult" style=3D""><font face=3D"monospace" size=3D"1"><later in code, t=
o revert RAW></font></div></div></div></blockquote><div><div><font s=
ize=3D"1"><span class=3D"gmail_default" style=3D""></span></font></div></di=
v><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"><div dir=
=3D"ltr"><div class=3D"gmail_default" style=3D""><font face=3D"monospace" s=
tyle=3D"" size=3D"1">tcsetattr(STDIN_FILENO, TCSANOW, &tt=
y_opts_backup);</font></div></div></blockquote><div dir=3D"ltr"><div><b=
r class=3D"gmail-Apple-interchange-newline"></div><div class=3D"gmail_defau=
lt" style=3D"font-family:arial,helvetica,sans-serif;font-size:small">I thin=
k what threw me off is:=C2=A0 the code, as-was (w/o assignment of structs) =
works fine on WSL under Windows; and also linux/arm.</div><div class=3D"gma=
il_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small=
"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,helveti=
ca,sans-serif;font-size:small">Maybe it'd be better to call "cfmak=
eraw()" something like "cf-sort-of-makeraw()" ?=C2=A0 =C2=A0=
;-)=C2=A0 since it doesn't actually *make* things raw.</div><div class=
=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-siz=
e:small"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,=
helvetica,sans-serif;font-size:small">Or, of course, simply 'fix' m=
akeraw() to be compliant w/linux?</div><br></div><div class=3D"gmail_defaul=
t" style=3D"font-family:arial,helvetica,sans-serif;font-size:small"></div><=
div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif=
;font-size:small">Thanks for the super-prompt reply.</div><div class=3D"gma=
il_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small=
"><br></div><div class=3D"gmail_default" style=3D"font-family:arial,helveti=
ca,sans-serif;font-size:small">My suggestions:</div><div class=3D"gmail_def=
ault" style=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br>=
</div><blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"><div =
class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;fon=
t-size:small">1) Add a Code Example to the=C2=A0 TCSETATTR=C2=A0(3) page</d=
iv><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-s=
erif;font-size:small"><br></div><div class=3D"gmail_default" style=3D"font-=
family:arial,helvetica,sans-serif;font-size:small">2) Change behavior of cf=
makeraw() to be consistent w/linux</div><div class=3D"gmail_default" style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small"><br></div><div =
class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;fon=
t-size:small">3) I'm only kidding about changing the name.</div></block=
quote><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,san=
s-serif;font-size:small"><br></div><div class=3D"gmail_default" style=3D"fo=
nt-family:arial,helvetica,sans-serif;font-size:small"><br></div><div class=
=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font-siz=
e:small">-Mike</div><div class=3D"gmail_default" style=3D"font-family:arial=
,helvetica,sans-serif;font-size:small"><br></div><div><br></div><br><div cl=
ass=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Tue, Apr 5, 20=
22 at 1:20 AM RVP <<a href=3D"mailto:rvp@sdf.org">rvp@sdf.org</a>> wr=
ote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The followi=
ng reply was made to PR kern/56779; it has been noted by GNATS.<br>
<br>
From: RVP <<a href=3D"mailto:rvp@SDF.ORG" target=3D"_blank">rvp@SDF.ORG<=
/a>><br>
To: <a href=3D"mailto:gnats-bugs@netbsd.org" target=3D"_blank">gnats-bugs@n=
etbsd.org</a><br>
Cc: <br>
Subject: Re: kern/56779: RAW mode on the TTY always returns EOF (-1)<br>
Date: Tue, 5 Apr 2022 08:17:19 +0000 (UTC)<br>
<br>
=C2=A0On Tue, 5 Apr 2022, Michael van Elst wrote:<br>
<br>
=C2=A0> cfmakeraw changes the configuration in a termios structure,<br>
=C2=A0> but it doesn't magically initialize values. Your code<br>
=C2=A0> just uses random stack content with unpredictable results.<br>
=C2=A0><br>
<br>
=C2=A0c_cc[VMIN] =3D 1;<br>
=C2=A0c_cc[VTIME] =3D 0;<br>
<br>
=C2=A0can also be done in=C2=A0 src/lib/libc/termios/cfmakeraw.c, I think.<=
br>
<br>
=C2=A0-RVP<br>
<br>
</blockquote></div></div>
--000000000000c6c87705dbeabb18--
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.