select doesn't seem to recognize a single '\n' as input waiting

so we can;t use it, sigh.
This commit is contained in:
Todd C. Miller
1994-06-28 22:25:08 +00:00
parent a541ff80b0
commit 391a73f40b

View File

@@ -52,6 +52,11 @@
#define _PASSWD_LEN 8 #define _PASSWD_LEN 8
#endif /* _PASSWD_LEN */ #endif /* _PASSWD_LEN */
/*
* Local Prototypes
*/
static int tgetc __P((FILE *, int));
/****************************************************************** /******************************************************************
* *
@@ -76,7 +81,7 @@ char * tgetpass(prompt, timeout)
#endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
FILE * input, * output; FILE * input, * output;
static char buf[_PASSWD_LEN + 1]; static char buf[_PASSWD_LEN + 2];
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
sigset_t oldmask; sigset_t oldmask;
sigset_t mask; sigset_t mask;
@@ -138,35 +143,43 @@ char * tgetpass(prompt, timeout)
#endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
/* print the prompt & rewind */ /* rewind if necesary */
(void) write(fileno(output), prompt, strlen(prompt)); if (input == output) {
(void) fflush(output);
(void) rewind(output);
}
/* print the prompt */
(void) fputs(prompt, output);
/* rewind if necesary */
if (input == output) {
(void) fflush(output);
(void) rewind(output);
}
/* setup for select(2) */ /* setup for select(2) */
FD_ZERO(&readfds); FD_ZERO(&readfds);
/* get the password */ /* get the password */
for (i=0; i < _PASSWD_LEN; i++) { for (i=0; i <= _PASSWD_LEN; i++) {
/* do select */ buf[i] = tgetc(input, timeout);
FD_SET(fileno(input), &readfds); if (buf[i] == EOF) {
tv.tv_sec = timeout;
tv.tv_usec = 0;
#ifdef HAVE_SYSCONF
if (select(sysconf(_SC_OPEN_MAX), &readfds, NULL, NULL, &tv) <= 0) {
#else
if (select(getdtablesize(), &readfds, NULL, NULL, &tv) <= 0) {
#endif /* HAVE_SYSCONF */
buf[0] = '\0'; buf[0] = '\0';
break; break;
} }
if (buf[i] == '\n') {
buf[i] = fgetc(input);
if (buf[i] == EOF || buf[i] == '\n') {
buf[i] = '\0'; buf[i] = '\0';
break; break;
} }
} }
buf[_PASSWD_LEN - 1] = '\0'; buf[_PASSWD_LEN] = '\0';
(void) fputc('\n', output);
/* rewind if necesary and print a newline */
if (input == output) {
(void) fflush(output);
(void) rewind(output);
}
/* turn on echo */ /* turn on echo */
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
@@ -182,6 +195,17 @@ char * tgetpass(prompt, timeout)
#endif /* HAVE_TERMIO_H */ #endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */ #endif /* HAVE_TERMIOS_H */
/* rewind if necesary */
if (input == output) {
(void) fflush(output);
(void) rewind(output);
}
#if 1
(void) write(fileno(output), "\n", 1);
#else
(void) fputc('\n', output);
#endif
/* restore old signal mask */ /* restore old signal mask */
#ifdef POSIX_SIGNALS #ifdef POSIX_SIGNALS
(void) sigprocmask(SIG_SETMASK, &oldmask, NULL); (void) sigprocmask(SIG_SETMASK, &oldmask, NULL);
@@ -198,3 +222,38 @@ char * tgetpass(prompt, timeout)
else else
return(NULL); return(NULL);
} }
/******************************************************************
*
* tgetc()
*
* this function returns getc(input) unless the input times out
* (based on the value of timeout).
*/
static int tgetc(stream, timeout)
FILE * stream;
int timeout;
{
fd_set readfds;
struct timeval tv;
/* setup for select(2) */
FD_ZERO(&readfds);
FD_SET(fileno(stream), &readfds);
/* set timeout for select */
tv.tv_sec = timeout;
tv.tv_usec = 0;
/* return EOF if nothing to read by timeout */
#ifdef HAVE_SYSCONF
if (select(sysconf(_SC_OPEN_MAX), &readfds, NULL, NULL, &tv) <= 0)
#else
if (select(getdtablesize(), &readfds, NULL, NULL, &tv) <= 0)
#endif /* HAVE_SYSCONF */
return(EOF);
return(getc(stream));
}