diff options
author | Denys Vlasenko | 2014-09-22 21:14:02 +0200 |
---|---|---|
committer | Denys Vlasenko | 2014-09-22 21:14:02 +0200 |
commit | d6e7672545c717497490c0b0f54f64594f374f9d (patch) | |
tree | 736aa8a2f9264221709b45361939475c8ae83c24 | |
parent | 15943c886d6e1929b90db9bc6077c849cbaa187e (diff) | |
download | busybox-d6e7672545c717497490c0b0f54f64594f374f9d.zip busybox-d6e7672545c717497490c0b0f54f64594f374f9d.tar.gz |
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>
-rw-r--r-- | include/libbb.h | 4 | ||||
-rw-r--r-- | libbb/xfuncs.c | 10 | ||||
-rw-r--r-- | miscutils/less.c | 47 |
3 files changed, 29 insertions, 32 deletions
diff --git a/include/libbb.h b/include/libbb.h index ff223dd..d57f00e 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -390,8 +390,8 @@ const char *bb_basename(const char *name) FAST_FUNC; char *last_char_is(const char *s, int c) FAST_FUNC; const char* endofname(const char *name) FAST_FUNC; -void ndelay_on(int fd) FAST_FUNC; -void ndelay_off(int fd) FAST_FUNC; +int ndelay_on(int fd) FAST_FUNC; +int ndelay_off(int fd) FAST_FUNC; void close_on_exec_on(int fd) FAST_FUNC; void xdup2(int, int) FAST_FUNC; void xmove_fd(int, int) FAST_FUNC; diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 23f2751..f25ce94 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -25,20 +25,22 @@ #include "libbb.h" /* Turn on nonblocking I/O on a fd */ -void FAST_FUNC ndelay_on(int fd) +int FAST_FUNC ndelay_on(int fd) { int flags = fcntl(fd, F_GETFL); if (flags & O_NONBLOCK) - return; + return flags; fcntl(fd, F_SETFL, flags | O_NONBLOCK); + return flags; } -void FAST_FUNC ndelay_off(int fd) +int FAST_FUNC ndelay_off(int fd) { int flags = fcntl(fd, F_GETFL); if (!(flags & O_NONBLOCK)) - return; + return flags; fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); + return flags; } void FAST_FUNC close_on_exec_on(int fd) diff --git a/miscutils/less.c b/miscutils/less.c index 719af5a..3016c5b 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -414,10 +414,10 @@ static void read_lines(void) char *current_line, *p; int w = width; char last_terminated = terminated; + time_t last_time = 0; + int retry_EAGAIN = 2; #if ENABLE_FEATURE_LESS_REGEXP unsigned old_max_fline = max_fline; - time_t last_time = 0; - int had_progress = 2; #endif /* (careful: max_fline can be -1) */ @@ -427,8 +427,6 @@ static void read_lines(void) if (option_mask32 & FLAG_N) w -= 8; - IF_FEATURE_LESS_REGEXP(again0:) - p = current_line = ((char*)xmalloc(w + 4)) + 4; max_fline += last_terminated; if (!last_terminated) { @@ -448,15 +446,29 @@ static void read_lines(void) char c; /* if no unprocessed chars left, eat more */ if (readpos >= readeof) { - errno = 0; - ndelay_on(0); - eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); - ndelay_off(0); + int flags = ndelay_on(0); + + while (1) { + time_t t; + + errno = 0; + eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); + if (errno != EAGAIN) + break; + t = time(NULL); + if (t != last_time) { + last_time = t; + if (--retry_EAGAIN < 0) + break; + } + sched_yield(); + } + fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ readpos = 0; readeof = eof_error; if (eof_error <= 0) goto reached_eof; - IF_FEATURE_LESS_REGEXP(had_progress = 1;) + retry_EAGAIN = 1; } c = readbuf[readpos]; /* backspace? [needed for manpages] */ @@ -534,24 +546,7 @@ static void read_lines(void) #endif } if (eof_error <= 0) { -#if !ENABLE_FEATURE_LESS_REGEXP break; -#else - if (wanted_match < num_matches) { - break; - } /* else: goto_match() called us */ - if (errno == EAGAIN) { - time_t t = time(NULL); - if (t != last_time) { - last_time = t; - if (--had_progress < 0) - break; - } - sched_yield(); - goto again0; - } - break; -#endif } max_fline++; current_line = ((char*)xmalloc(w + 4)) + 4; |