aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-02-01 04:55:30 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-02-01 04:55:30 +0100
commite936c6d1c501517a68404612235c79e0a3600fad (patch)
treeebb76a682fd7d3d7fab7e3ff453320d3ef408690
parent460f8276449f0933f242c9295b241ec213bcef82 (diff)
downloadbusybox-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.c38
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) {