Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , 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 X-Mailer: Mozilla 4.05 [en] (WinNT; I) MIME-Version: 1.0 To: "cygwin AT sourceware DOT cygnus DOT com" Subject: termios.ECHO problems Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 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 #include #include #include 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