www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/1999/09/01/02:51:35

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Unsubscribe: <mailto:cygwin-unsubscribe-archive-cygwin=delorie DOT com AT sourceware DOT cygnus DOT com>
List-Subscribe: <mailto:cygwin-subscribe AT sourceware DOT cygnus DOT com>
List-Archive: <http://sourceware.cygnus.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sourceware DOT cygnus DOT com>
List-Help: <mailto:cygwin-help AT sourceware DOT cygnus DOT com>,
<http://sourceware.cygnus.com/ml/#faqs>
Sender: cygwin-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com
Message-ID: <37CCCC7F.E590D11F@acm.org>
Date: Wed, 01 Sep 1999 15:49:35 +0900
From: horio shoichi <horio AT acm DOT org>
X-Mailer: Mozilla 4.05 [en] (WinNT; I)
MIME-Version: 1.0
To: "cygwin AT sourceware DOT cygnus DOT com" <cygwin AT sourceware DOT cygnus DOT com>
Subject: termios.ECHO problems

This might be already discussed here, but I could not find the evidence
from mail archive. So I present my findings here. See attachment.
I tested this under NT4.0 sp3 + cygwinb20.1. Since I don't have SDK,
I didn't go further to find out true cause(s) of the symptom.

Briefly stated, resetting ECHO flag from termios.c_lflag destroys the
whole content and cannot recover back to ICANON|ECHO state.
 This results in:

o fgets appears to hang if large buffer is given.
o the result string is not cooked.
o .../src/newlib/unix/getpass.c never returns since it cannot find '\n'.

The most serious is that termios doesn't have the way to restore
previous states. Does anyone have workaround aginst this ?


horio shoichi


/*-------------------------------------------------------------------------
  usage: .../a.out [-bufsiz] [-e] [-v] [-g]
        -bufsize        size of buffer to test input overflow
        -e              test echo on condition
        -g              test getc effect
        -v              watch termios.c_lflag
 
-------------------------------------------------------------------------
  */
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <termios.h>

int
main(int argc, char **argv) {
struct termios  ttydef ;
struct termios  v_ttydef ;
FILE    *tty = stdin;
char    abuff[BUFSIZ] ;
char    *p;
int     eflag = 1 ;
int     gflag = 0 ;
int     vflag = 0 ;
int     i ;
char    **a = argv + 1 ;
int     s = BUFSIZ ;
int     c_lflag ;

for (i = 1 ; i < argc ; i++, a++) {
        if (**a != '-')
                break ;
        switch (*++*a) {
        case 'e' :
                eflag = 0 ;
                break ;
                eflag = 0 ;
                break ;
        case 'g' :
                gflag = 1 ;
                break ;
        case 'v' :
                vflag = 1 ;
                break ;
        default :
                /* pick up buffer size - first doubt if it's numeric */
                for (p = *a ; *p ; p++)
                        if (*p < '0' || *p > '9')
                                fprintf(stderr, "bad buffer size\n"),
                                exit(1) ;
                /* now get buffer size */
                s = atoi(*a) ;
                if (!s || s >= BUFSIZ - 1)
                        fprintf(stderr, "bad buffer size\n"),
                        exit(1) ;
                }
        }

if (tcgetattr(fileno(tty), &ttydef) == -1)
        pperror(__LINE__) ;

if (eflag && (eflag = ttydef.c_lflag & ECHO)) {
        ttydef.c_lflag &= ~ECHO;
        if (tcsetattr(fileno(tty), TCSANOW, &ttydef) == -1)
                        /* TCSADRAIN, TCSAFLUSH give the same result */
                pperror(__LINE__) ;
        }
if (vflag) {
        c_lflag = ttydef.c_lflag ;
        printf("initial lflag = %08.8x\n", ttydef.c_lflag) ;

        memset(&v_ttydef, 0xff, sizeof(v_ttydef)) ;
        if (tcgetattr(fileno(tty), &v_ttydef) == -1)
                pperror(__LINE__) ;
        if (v_ttydef.c_lflag ^ c_lflag)
                printf("changed lflag = %08.8x\n", v_ttydef.c_lflag) ;
        }

fputs("enter any string:", stderr);
fflush(stderr);

memset(abuff, 0, sizeof(abuff)) ;
if (gflag) {
        for (p = abuff ; (i = getc(tty)) != EOF && i != '\n' && i !=
'\r' ; )
                if (p < abuff + BUFSIZ)
                        *p++ = i ;
        /* look at terminator */
        *p = i ;
        }
else {
        fgets(abuff, s, tty);
        if (feof(tty))
                pperror(__LINE__) ;
        if (ferror(tty))
                pperror(__LINE__) ;
        }

printf("strlen(abuff) = %d\n", strlen(abuff)) ;
for (p = abuff ; *p ; p++)
        printf("%02.2x", *p) ;
putchar('\n') ;

if (eflag) {
        ttydef.c_lflag |= ECHO;
        if (tcsetattr(fileno(tty), TCSANOW, &ttydef) == -1)
                pperror(__LINE__) ;
        if (vflag)
                printf("last lflag = %08.8x\n", ttydef.c_lflag) ;
        }

if (vflag) {
        if (tcgetattr(fileno(tty), &v_ttydef) == -1)
                pperror(__LINE__) ;
        printf("final lflag = %08.8x\n", v_ttydef.c_lflag) ;
#if 1
        /* is ECHO flag not recovered -- i.e., is lflag reported
correctly ? */
        fgets(abuff, s, tty);
                /* hm, still echo off. report seems true ! */
#endif
        }
}
/*----------------------------------------------------------------------------*/
int
pperror(int l) {
char    b[BUFSIZ] ;
sprintf(b, "%d", l) ;
perror(b) ;
exit(0) ;
}
/*----------------------------------------------------------------------------*/

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019