Mail Archives: cygwin/1999/09/01/02:51:35
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 -