[PATCH] function bb_askpass only read one line once

Michael Zhu linuxsir320 at gmail.com
Mon Feb 1 09:03:07 UTC 2010


Hi Denys Vlasenko,

Yours is easy to understand. Thanks for your feedback.

+       /* discards \n and \r */
+       while((len = read(fd,&ch, 1)>  0)&&  (ch == '\n' || ch == '\r'));

Reading is terminated when encountering '\r', but DOS file format ends 
with newline '\r\n'.
I wan to get the next line, so '\n' is dropped. I known this 
modification is not better, but
I could not find a better way. How about this: saving the character 
read, when reading next
time, if character is '\n', and last character just saved is '\r', 
skipping it and going on. Maybe
it's not necessary.

diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
index f9b918c..2792c89 100644
--- a/libbb/bb_askpass.c
+++ b/libbb/bb_askpass.c
@@ -24,16 +24,13 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, 
const char *prompt)
      /* Was static char[BIGNUM] */
      enum { sizeof_passwd = 128 };
      static char *passwd;
+    static char last_char = 0;

      char *ret;
      int i;
      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 +43,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 +53,33 @@ 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==1)
+        {
+            if (last_char == '\r' && ret[i] == '\n')
+                continue;
+            last_char = ret[i];
+        }
+
+        if (r == 0 /* EOF */
+         || ret[i] == '\r' || ret[i] == '\n' /* EOL */
+         || ++i == sizeof_passwd-1 /* line limit */
+        ) {
+            ret[i] = '\0';
+            break;
+        }
      }

      if (timeout) {


Thanks again!

Michael

On 1/29/2010 4:29 AM, Denys Vlasenko wrote:
> On Thursday 28 January 2010 10:46, Michael Zhu wrote:
>    
>> > From 48a56ae1c473334e56fa33f8925ae57ce7bc2e0b Mon Sep 17 00:00:00 2001
>> From: Michael Zhu<linuxsir320 at gmail.com>
>> Date: Thu, 28 Jan 2010 09:34:32 +0000
>> Subject: [PATCH] function bb_askpass only read one line once
>>
>> ---
>>   libbb/bb_askpass.c |    4 ++--
>>   1 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
>> index f9b918c..ef93c2f 100644
>> --- a/libbb/bb_askpass.c
>> +++ b/libbb/bb_askpass.c
>> @@ -57,9 +57,9 @@ 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,
>> +	/* On timeout or Ctrl-C, fgets will hopefully be interrupted,
>>   	 * and we return NULL */
>> -	if (read(fd, passwd, sizeof_passwd - 1)>  0) {
>> +	if (fgets(passwd, sizeof_passwd, stdin)) {
>>      
> Are you serious??
>
> --
> vda
>
>    



More information about the busybox mailing list