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>
This commit is contained in:
parent
15943c886d
commit
d6e7672545
@ -390,8 +390,8 @@ const char *bb_basename(const char *name) FAST_FUNC;
|
|||||||
char *last_char_is(const char *s, int c) FAST_FUNC;
|
char *last_char_is(const char *s, int c) FAST_FUNC;
|
||||||
const char* endofname(const char *name) FAST_FUNC;
|
const char* endofname(const char *name) FAST_FUNC;
|
||||||
|
|
||||||
void ndelay_on(int fd) FAST_FUNC;
|
int ndelay_on(int fd) FAST_FUNC;
|
||||||
void ndelay_off(int fd) FAST_FUNC;
|
int ndelay_off(int fd) FAST_FUNC;
|
||||||
void close_on_exec_on(int fd) FAST_FUNC;
|
void close_on_exec_on(int fd) FAST_FUNC;
|
||||||
void xdup2(int, int) FAST_FUNC;
|
void xdup2(int, int) FAST_FUNC;
|
||||||
void xmove_fd(int, int) FAST_FUNC;
|
void xmove_fd(int, int) FAST_FUNC;
|
||||||
|
@ -25,20 +25,22 @@
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
/* Turn on nonblocking I/O on a fd */
|
/* 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);
|
int flags = fcntl(fd, F_GETFL);
|
||||||
if (flags & O_NONBLOCK)
|
if (flags & O_NONBLOCK)
|
||||||
return;
|
return flags;
|
||||||
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
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);
|
int flags = fcntl(fd, F_GETFL);
|
||||||
if (!(flags & O_NONBLOCK))
|
if (!(flags & O_NONBLOCK))
|
||||||
return;
|
return flags;
|
||||||
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||||
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAST_FUNC close_on_exec_on(int fd)
|
void FAST_FUNC close_on_exec_on(int fd)
|
||||||
|
@ -414,10 +414,10 @@ static void read_lines(void)
|
|||||||
char *current_line, *p;
|
char *current_line, *p;
|
||||||
int w = width;
|
int w = width;
|
||||||
char last_terminated = terminated;
|
char last_terminated = terminated;
|
||||||
|
time_t last_time = 0;
|
||||||
|
int retry_EAGAIN = 2;
|
||||||
#if ENABLE_FEATURE_LESS_REGEXP
|
#if ENABLE_FEATURE_LESS_REGEXP
|
||||||
unsigned old_max_fline = max_fline;
|
unsigned old_max_fline = max_fline;
|
||||||
time_t last_time = 0;
|
|
||||||
int had_progress = 2;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* (careful: max_fline can be -1) */
|
/* (careful: max_fline can be -1) */
|
||||||
@ -427,8 +427,6 @@ static void read_lines(void)
|
|||||||
if (option_mask32 & FLAG_N)
|
if (option_mask32 & FLAG_N)
|
||||||
w -= 8;
|
w -= 8;
|
||||||
|
|
||||||
IF_FEATURE_LESS_REGEXP(again0:)
|
|
||||||
|
|
||||||
p = current_line = ((char*)xmalloc(w + 4)) + 4;
|
p = current_line = ((char*)xmalloc(w + 4)) + 4;
|
||||||
max_fline += last_terminated;
|
max_fline += last_terminated;
|
||||||
if (!last_terminated) {
|
if (!last_terminated) {
|
||||||
@ -448,15 +446,29 @@ static void read_lines(void)
|
|||||||
char c;
|
char c;
|
||||||
/* if no unprocessed chars left, eat more */
|
/* if no unprocessed chars left, eat more */
|
||||||
if (readpos >= readeof) {
|
if (readpos >= readeof) {
|
||||||
|
int flags = ndelay_on(0);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
time_t t;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ndelay_on(0);
|
|
||||||
eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
|
eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf));
|
||||||
ndelay_off(0);
|
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;
|
readpos = 0;
|
||||||
readeof = eof_error;
|
readeof = eof_error;
|
||||||
if (eof_error <= 0)
|
if (eof_error <= 0)
|
||||||
goto reached_eof;
|
goto reached_eof;
|
||||||
IF_FEATURE_LESS_REGEXP(had_progress = 1;)
|
retry_EAGAIN = 1;
|
||||||
}
|
}
|
||||||
c = readbuf[readpos];
|
c = readbuf[readpos];
|
||||||
/* backspace? [needed for manpages] */
|
/* backspace? [needed for manpages] */
|
||||||
@ -534,24 +546,7 @@ static void read_lines(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (eof_error <= 0) {
|
if (eof_error <= 0) {
|
||||||
#if !ENABLE_FEATURE_LESS_REGEXP
|
|
||||||
break;
|
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++;
|
max_fline++;
|
||||||
current_line = ((char*)xmalloc(w + 4)) + 4;
|
current_line = ((char*)xmalloc(w + 4)) + 4;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user