[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