diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-01 04:55:30 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-02-01 04:55:30 +0100 |
commit | e936c6d1c501517a68404612235c79e0a3600fad (patch) | |
tree | ebb76a682fd7d3d7fab7e3ff453320d3ef408690 | |
parent | 460f8276449f0933f242c9295b241ec213bcef82 (diff) | |
download | busybox-e936c6d1c501517a68404612235c79e0a3600fad.tar.gz |
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>
-rw-r--r-- | libbb/bb_askpass.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index f9b918cec..bdb756659 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c @@ -30,10 +30,6 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) struct sigaction sa, oldsa; struct termios tio, oldtio; - if (!passwd) - passwd = xmalloc(sizeof_passwd); - memset(passwd, 0, sizeof_passwd); - tcgetattr(fd, &oldtio); tcflush(fd, TCIFLUSH); tio = oldtio; @@ -46,7 +42,7 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) memset(&sa, 0, sizeof(sa)); /* 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; sigaction(SIGINT, &sa, &oldsa); if (timeout) { @@ -56,18 +52,26 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) fputs(prompt, stdout); fflush_all(); - ret = NULL; - /* On timeout or Ctrl-C, read will hopefully be interrupted, - * and we return NULL */ - if (read(fd, passwd, sizeof_passwd - 1) > 0) { - ret = passwd; - i = 0; - /* Last byte is guaranteed to be 0 - (read did not overwrite it) */ - do { - if (passwd[i] == '\r' || passwd[i] == '\n') - passwd[i] = '\0'; - } while (passwd[i++]); + + if (!passwd) + passwd = xmalloc(sizeof_passwd); + memset(passwd, 0, sizeof_passwd); + ret = passwd; + i = 0; + while (1) { + int r = read(fd, &ret[i], 1); + if (r < 0) { + /* read is interrupted by timeout or ^C */ + ret = NULL; + break; + } + if (r == 0 /* EOF */ + || ret[i] == '\r' || ret[i] == '\n' /* EOL */ + || ++i == sizeof_passwd-1 /* line limit */ + ) { + ret[i] = '\0'; + break; + } } if (timeout) { |