make echo -e "foo\nfoo" | passwd USER work

Suggested by Michael Zhu (linuxsir320 AT gmail.com)

function                                             old     new   delta
bb_ask                                               333     340      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-02-01 04:55:30 +01:00
parent 460f827644
commit e936c6d1c5

View File

@ -30,10 +30,6 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt)
struct sigaction sa, oldsa; struct sigaction sa, oldsa;
struct termios tio, oldtio; struct termios tio, oldtio;
if (!passwd)
passwd = xmalloc(sizeof_passwd);
memset(passwd, 0, sizeof_passwd);
tcgetattr(fd, &oldtio); tcgetattr(fd, &oldtio);
tcflush(fd, TCIFLUSH); tcflush(fd, TCIFLUSH);
tio = oldtio; tio = oldtio;
@ -46,7 +42,7 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt)
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
/* sa.sa_flags = 0; - no SA_RESTART! */ /* sa.sa_flags = 0; - no SA_RESTART! */
/* SIGINT and SIGALRM will interrupt read below */ /* SIGINT and SIGALRM will interrupt reads below */
sa.sa_handler = askpass_timeout; sa.sa_handler = askpass_timeout;
sigaction(SIGINT, &sa, &oldsa); sigaction(SIGINT, &sa, &oldsa);
if (timeout) { if (timeout) {
@ -56,18 +52,26 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt)
fputs(prompt, stdout); fputs(prompt, stdout);
fflush_all(); fflush_all();
ret = NULL;
/* On timeout or Ctrl-C, read will hopefully be interrupted, if (!passwd)
* and we return NULL */ passwd = xmalloc(sizeof_passwd);
if (read(fd, passwd, sizeof_passwd - 1) > 0) { memset(passwd, 0, sizeof_passwd);
ret = passwd; ret = passwd;
i = 0; i = 0;
/* Last byte is guaranteed to be 0 while (1) {
(read did not overwrite it) */ int r = read(fd, &ret[i], 1);
do { if (r < 0) {
if (passwd[i] == '\r' || passwd[i] == '\n') /* read is interrupted by timeout or ^C */
passwd[i] = '\0'; ret = NULL;
} while (passwd[i++]); break;
}
if (r == 0 /* EOF */
|| ret[i] == '\r' || ret[i] == '\n' /* EOL */
|| ++i == sizeof_passwd-1 /* line limit */
) {
ret[i] = '\0';
break;
}
} }
if (timeout) { if (timeout) {