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">&quot;<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">&quot;</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, &amp=
 ;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(&amp;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, &amp;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">&lt;later in code, t=
 o revert RAW&gt;</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, &amp;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&#39;d be better to call &quot;cfmak=
 eraw()&quot; something like &quot;cf-sort-of-makeraw()&quot; ?=C2=A0 =C2=A0=
 ;-)=C2=A0 since it doesn&#39;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 &#39;fix&#39; 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&#39;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 &lt;<a href=3D"mailto:rvp@sdf.org">rvp@sdf.org</a>&gt; 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 &lt;<a href=3D"mailto:rvp@SDF.ORG" target=3D"_blank">rvp@SDF.ORG<=
 /a>&gt;<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&gt; cfmakeraw changes the configuration in a termios structure,<br>
 =C2=A0&gt; but it doesn&#39;t magically initialize values. Your code<br>
 =C2=A0&gt; just uses random stack content with unpredictable results.<br>
 =C2=A0&gt;<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:

NetBSD Home
NetBSD PR Database Search

(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.