diff options
Diffstat (limited to 'miscutils/less.c')
-rw-r--r-- | miscutils/less.c | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index d84df469c..554e54687 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,17 +427,14 @@ 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; | ||
434 | if (!last_terminated) { | 431 | if (!last_terminated) { |
435 | const char *cp = flines[max_fline]; | 432 | const char *cp = flines[max_fline]; |
436 | strcpy(p, cp); | 433 | p = stpcpy(p, cp); |
437 | p += strlen(current_line); | 434 | free(MEMPTR(cp)); |
438 | free(MEMPTR(flines[max_fline])); | ||
439 | /* last_line_pos is still valid from previous read_lines() */ | 435 | /* last_line_pos is still valid from previous read_lines() */ |
440 | } else { | 436 | } else { |
437 | max_fline++; | ||
441 | last_line_pos = 0; | 438 | last_line_pos = 0; |
442 | } | 439 | } |
443 | 440 | ||
@@ -448,15 +445,29 @@ static void read_lines(void) | |||
448 | char c; | 445 | char c; |
449 | /* if no unprocessed chars left, eat more */ | 446 | /* if no unprocessed chars left, eat more */ |
450 | if (readpos >= readeof) { | 447 | if (readpos >= readeof) { |
451 | errno = 0; | 448 | int flags = ndelay_on(0); |
452 | ndelay_on(0); | 449 | |
453 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | 450 | while (1) { |
454 | ndelay_off(0); | 451 | time_t t; |
452 | |||
453 | errno = 0; | ||
454 | eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); | ||
455 | if (errno != EAGAIN) | ||
456 | break; | ||
457 | t = time(NULL); | ||
458 | if (t != last_time) { | ||
459 | last_time = t; | ||
460 | if (--retry_EAGAIN < 0) | ||
461 | break; | ||
462 | } | ||
463 | sched_yield(); | ||
464 | } | ||
465 | fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ | ||
455 | readpos = 0; | 466 | readpos = 0; |
456 | readeof = eof_error; | 467 | readeof = eof_error; |
457 | if (eof_error <= 0) | 468 | if (eof_error <= 0) |
458 | goto reached_eof; | 469 | goto reached_eof; |
459 | IF_FEATURE_LESS_REGEXP(had_progress = 1;) | 470 | retry_EAGAIN = 1; |
460 | } | 471 | } |
461 | c = readbuf[readpos]; | 472 | c = readbuf[readpos]; |
462 | /* backspace? [needed for manpages] */ | 473 | /* backspace? [needed for manpages] */ |
@@ -491,6 +502,11 @@ static void read_lines(void) | |||
491 | *p++ = c; | 502 | *p++ = c; |
492 | *p = '\0'; | 503 | *p = '\0'; |
493 | } /* end of "read chars until we have a line" loop */ | 504 | } /* end of "read chars until we have a line" loop */ |
505 | #if 0 | ||
506 | //BUG: also triggers on this: | ||
507 | // { printf "\nfoo\n"; sleep 1; printf "\nbar\n"; } | less | ||
508 | // (resulting in lost empty line between "foo" and "bar" lines) | ||
509 | // the "terminated" logic needs fixing (or explaining) | ||
494 | /* Corner case: linewrap with only "" wrapping to next line */ | 510 | /* Corner case: linewrap with only "" wrapping to next line */ |
495 | /* Looks ugly on screen, so we do not store this empty line */ | 511 | /* Looks ugly on screen, so we do not store this empty line */ |
496 | if (!last_terminated && !current_line[0]) { | 512 | if (!last_terminated && !current_line[0]) { |
@@ -498,6 +514,7 @@ static void read_lines(void) | |||
498 | max_lineno++; | 514 | max_lineno++; |
499 | continue; | 515 | continue; |
500 | } | 516 | } |
517 | #endif | ||
501 | reached_eof: | 518 | reached_eof: |
502 | last_terminated = terminated; | 519 | last_terminated = terminated; |
503 | flines = xrealloc_vector(flines, 8, max_fline); | 520 | flines = xrealloc_vector(flines, 8, max_fline); |
@@ -528,24 +545,7 @@ static void read_lines(void) | |||
528 | #endif | 545 | #endif |
529 | } | 546 | } |
530 | if (eof_error <= 0) { | 547 | if (eof_error <= 0) { |
531 | #if !ENABLE_FEATURE_LESS_REGEXP | ||
532 | break; | 548 | break; |
533 | #else | ||
534 | if (wanted_match < num_matches) { | ||
535 | break; | ||
536 | } /* else: goto_match() called us */ | ||
537 | if (errno == EAGAIN) { | ||
538 | time_t t = time(NULL); | ||
539 | if (t != last_time) { | ||
540 | last_time = t; | ||
541 | if (--had_progress < 0) | ||
542 | break; | ||
543 | } | ||
544 | sched_yield(); | ||
545 | goto again0; | ||
546 | } | ||
547 | break; | ||
548 | #endif | ||
549 | } | 549 | } |
550 | max_fline++; | 550 | max_fline++; |
551 | current_line = ((char*)xmalloc(w + 4)) + 4; | 551 | current_line = ((char*)xmalloc(w + 4)) + 4; |
@@ -802,11 +802,18 @@ static void buffer_print(void) | |||
802 | unsigned i; | 802 | unsigned i; |
803 | 803 | ||
804 | move_cursor(0, 0); | 804 | move_cursor(0, 0); |
805 | for (i = 0; i <= max_displayed_line; i++) | 805 | for (i = 0; i <= max_displayed_line; i++) { |
806 | if (pattern_valid) | 806 | if (pattern_valid) |
807 | print_found(buffer[i]); | 807 | print_found(buffer[i]); |
808 | else | 808 | else |
809 | print_ascii(buffer[i]); | 809 | print_ascii(buffer[i]); |
810 | } | ||
811 | if ((option_mask32 & FLAG_E) | ||
812 | && eof_error <= 0 | ||
813 | && (max_fline - cur_fline) <= max_displayed_line | ||
814 | ) { | ||
815 | less_exit(EXIT_SUCCESS); | ||
816 | } | ||
810 | status_print(); | 817 | status_print(); |
811 | } | 818 | } |
812 | 819 | ||