select doesn't seem to recognize a single '\n' as input waiting
so we can;t use it, sigh.
This commit is contained in:
95
tgetpass.c
95
tgetpass.c
@@ -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));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user