diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2014-09-22 21:14:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-09-22 21:14:02 +0200 |
commit | d6e7672545c717497490c0b0f54f64594f374f9d (patch) | |
tree | 736aa8a2f9264221709b45361939475c8ae83c24 /miscutils | |
parent | 15943c886d6e1929b90db9bc6077c849cbaa187e (diff) | |
download | busybox-w32-d6e7672545c717497490c0b0f54f64594f374f9d.tar.gz busybox-w32-d6e7672545c717497490c0b0f54f64594f374f9d.tar.bz2 busybox-w32-d6e7672545c717497490c0b0f54f64594f374f9d.zip |
less: move "retry-on-EAGAIN" logic closer to read ops
This makes "G" (goto end of input) command work as well as
/search_for_nonexistent_string: both will read to EOF now
even from somewhat slow input (such as kernel's "git log").
function old new delta
ndelay_on 35 43 +8
ndelay_off 35 43 +8
read_lines 695 691 -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 16/-4) Total: 12 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/less.c | 47 |
1 files changed, 21 insertions, 26 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index 719af5a0d..3016c5b47 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -414,10 +414,10 @@ static void read_lines(void) | |||
414 | char *current_line, *p; | 414 | char *current_line, *p; |
415 | int w = width; | 415 | int w = width; |
416 | char last_terminated = terminated; | 416 | char last_terminated = terminated; |
417 | time_t last_time = 0; | ||
418 | int retry_EAGAIN = 2; | ||
417 | #if ENABLE_FEATURE_LESS_REGEXP | 419 | #if ENABLE_FEATURE_LESS_REGEXP |
418 | unsigned old_max_fline = max_fline; | 420 | unsigned old_max_fline = max_fline; |
419 | time_t last_time = 0; | ||
420 | int had_progress = 2; | ||
421 | #endif | 421 | #endif |
422 | 422 | ||
423 | /* (careful: max_fline can be -1) */ | 423 | /* (careful: max_fline can be -1) */ |
@@ -427,8 +427,6 @@ static void read_lines(void) | |||
427 | if (option_mask32 & FLAG_N) | 427 | if (option_mask32 & FLAG_N) |
428 | w -= 8; | 428 | w -= 8; |
429 | 429 | ||
430 | IF_FEATURE_LESS_REGEXP(again0:) | ||
431 | |||
432 | p = current_line = ((char*)xmalloc(w + 4)) + 4; | 430 | p = current_line = ((char*)xmalloc(w + 4)) + 4; |
433 | max_fline += last_terminated; | 431 | max_fline += last_terminated; |
434 | if (!last_terminated) { | 432 | if (!last_terminated) { |
@@ -448,15 +446,29 @@ static void read_lines(void) | |||
448 | char c; | 446 | char c; |
449 | /* if no unprocessed chars left, eat more */ | 447 | /* if no unprocessed chars left, eat more */ |
450 | if (readpos >= readeof) { | 448 | if (readpos >= readeof) { |
451 | errno = 0; | 449 | int flags = ndelay_on(0); |
452 | ndelay_on(0); | 450 | |
453 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | 451 | while (1) { |
454 | ndelay_off(0); | 452 | time_t t; |
453 | |||
454 | errno = 0; | ||
455 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | ||
456 | if (errno != EAGAIN) | ||
457 | break; | ||
458 | t = time(NULL); | ||
459 | if (t != last_time) { | ||
460 | last_time = t; | ||
461 | if (--retry_EAGAIN < 0) | ||
462 | break; | ||
463 | } | ||
464 | sched_yield(); | ||
465 | } | ||
466 | fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ | ||
455 | readpos = 0; | 467 | readpos = 0; |
456 | readeof = eof_error; | 468 | readeof = eof_error; |
457 | if (eof_error <= 0) | 469 | if (eof_error <= 0) |
458 | goto reached_eof; | 470 | goto reached_eof; |
459 | IF_FEATURE_LESS_REGEXP(had_progress = 1;) | 471 | retry_EAGAIN = 1; |
460 | } | 472 | } |
461 | c = readbuf[readpos]; | 473 | c = readbuf[readpos]; |
462 | /* backspace? [needed for manpages] */ | 474 | /* backspace? [needed for manpages] */ |
@@ -534,24 +546,7 @@ static void read_lines(void) | |||
534 | #endif | 546 | #endif |
535 | } | 547 | } |
536 | if (eof_error <= 0) { | 548 | if (eof_error <= 0) { |
537 | #if !ENABLE_FEATURE_LESS_REGEXP | ||
538 | break; | 549 | break; |
539 | #else | ||
540 | if (wanted_match < num_matches) { | ||
541 | break; | ||
542 | } /* else: goto_match() called us */ | ||
543 | if (errno == EAGAIN) { | ||
544 | time_t t = time(NULL); | ||
545 | if (t != last_time) { | ||
546 | last_time = t; | ||
547 | if (--had_progress < 0) | ||
548 | break; | ||
549 | } | ||
550 | sched_yield(); | ||
551 | goto again0; | ||
552 | } | ||
553 | break; | ||
554 | #endif | ||
555 | } | 550 | } |
556 | max_fline++; | 551 | max_fline++; |
557 | current_line = ((char*)xmalloc(w + 4)) + 4; | 552 | current_line = ((char*)xmalloc(w + 4)) + 4; |