less: fix bugs discovered with "git log -p | less -m" on kernel tree
function old new delta read_lines 685 733 +48 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
32afd3aa60
commit
69b114fb8a
@ -404,6 +404,9 @@ static void fill_match_lines(unsigned pos);
|
||||
* last_line_pos - screen line position of next char to be read
|
||||
* (takes into account tabs and backspaces)
|
||||
* eof_error - < 0 error, == 0 EOF, > 0 not EOF/error
|
||||
*
|
||||
* "git log -p | less -m" on the kernel git tree is a good test for EAGAINs,
|
||||
* "/search on very long input" and "reaching max line count" corner cases.
|
||||
*/
|
||||
static void read_lines(void)
|
||||
{
|
||||
@ -414,9 +417,13 @@ static void read_lines(void)
|
||||
#if ENABLE_FEATURE_LESS_REGEXP
|
||||
unsigned old_max_fline = max_fline;
|
||||
time_t last_time = 0;
|
||||
unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */
|
||||
int had_progress = 2;
|
||||
#endif
|
||||
|
||||
/* (careful: max_fline can be -1) */
|
||||
if (max_fline + 1 > MAXLINES)
|
||||
return;
|
||||
|
||||
if (option_mask32 & FLAG_N)
|
||||
w -= 8;
|
||||
|
||||
@ -441,6 +448,7 @@ 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);
|
||||
@ -448,6 +456,7 @@ static void read_lines(void)
|
||||
readeof = eof_error;
|
||||
if (eof_error <= 0)
|
||||
goto reached_eof;
|
||||
had_progress = 1;
|
||||
}
|
||||
c = readbuf[readpos];
|
||||
/* backspace? [needed for manpages] */
|
||||
@ -519,31 +528,23 @@ static void read_lines(void)
|
||||
#endif
|
||||
}
|
||||
if (eof_error <= 0) {
|
||||
if (eof_error < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* not yet eof or error, reset flag (or else
|
||||
* we will hog CPU - select() will return
|
||||
* immediately */
|
||||
eof_error = 1;
|
||||
} else {
|
||||
print_statusline(bb_msg_read_error);
|
||||
}
|
||||
}
|
||||
#if !ENABLE_FEATURE_LESS_REGEXP
|
||||
break;
|
||||
#else
|
||||
if (wanted_match < num_matches) {
|
||||
break;
|
||||
} else { /* goto_match called us */
|
||||
} /* else: goto_match() called us */
|
||||
if (errno == EAGAIN) {
|
||||
time_t t = time(NULL);
|
||||
if (t != last_time) {
|
||||
last_time = t;
|
||||
if (--seconds_p1 == 0)
|
||||
if (--had_progress < 0)
|
||||
break;
|
||||
}
|
||||
sched_yield();
|
||||
goto again0; /* go loop again (max 2 seconds) */
|
||||
goto again0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
max_fline++;
|
||||
@ -551,6 +552,15 @@ static void read_lines(void)
|
||||
p = current_line;
|
||||
last_line_pos = 0;
|
||||
} /* end of "read lines until we reach cur_fline" loop */
|
||||
|
||||
if (eof_error < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
eof_error = 1;
|
||||
} else {
|
||||
print_statusline(bb_msg_read_error);
|
||||
}
|
||||
}
|
||||
|
||||
fill_match_lines(old_max_fline);
|
||||
#if ENABLE_FEATURE_LESS_REGEXP
|
||||
/* prevent us from being stuck in search for a match */
|
||||
|
Loading…
Reference in New Issue
Block a user