diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-07-31 16:42:20 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-07-31 16:42:20 +0200 |
| commit | 9dc526d0f91c37ecdf6280c2cd69107c6102076e (patch) | |
| tree | f55255e96215b8a444c77c157be6858f32df3e07 /miscutils | |
| parent | 1ecb996fd2641e6ad3fdf07e78781823c71fcf13 (diff) | |
| download | busybox-w32-9dc526d0f91c37ecdf6280c2cd69107c6102076e.tar.gz busybox-w32-9dc526d0f91c37ecdf6280c2cd69107c6102076e.tar.bz2 busybox-w32-9dc526d0f91c37ecdf6280c2cd69107c6102076e.zip | |
less: improve regular file detection in line counting code
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/less.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/miscutils/less.c b/miscutils/less.c index b38fcf766..be8d20e66 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
| @@ -165,12 +165,6 @@ enum { | |||
| 165 | enum { pattern_valid = 0 }; | 165 | enum { pattern_valid = 0 }; |
| 166 | #endif | 166 | #endif |
| 167 | 167 | ||
| 168 | enum { | ||
| 169 | READING_FILE = -1, | ||
| 170 | READING_STDIN = -2, | ||
| 171 | READING_NONREG = -3 | ||
| 172 | }; | ||
| 173 | |||
| 174 | struct globals { | 168 | struct globals { |
| 175 | int cur_fline; /* signed */ | 169 | int cur_fline; /* signed */ |
| 176 | int kbd_fd; /* fd to get input from */ | 170 | int kbd_fd; /* fd to get input from */ |
| @@ -195,7 +189,10 @@ struct globals { | |||
| 195 | char *filename; | 189 | char *filename; |
| 196 | char **files; | 190 | char **files; |
| 197 | #if ENABLE_FEATURE_LESS_FLAGS | 191 | #if ENABLE_FEATURE_LESS_FLAGS |
| 198 | int num_lines; /* input source if < 0, line count if >= 0 */ | 192 | int num_lines; /* a flag if < 0, line count if >= 0 */ |
| 193 | # define REOPEN_AND_COUNT (-1) | ||
| 194 | # define REOPEN_STDIN (-2) | ||
| 195 | # define NOT_REGULAR_FILE (-3) | ||
| 199 | #endif | 196 | #endif |
| 200 | #if ENABLE_FEATURE_LESS_MARKS | 197 | #if ENABLE_FEATURE_LESS_MARKS |
| 201 | unsigned num_marks; | 198 | unsigned num_marks; |
| @@ -622,14 +619,29 @@ static void update_num_lines(void) | |||
| 622 | char buf[4096]; | 619 | char buf[4096]; |
| 623 | 620 | ||
| 624 | /* only do this for regular files */ | 621 | /* only do this for regular files */ |
| 625 | if (num_lines == READING_FILE) { | 622 | if (num_lines != NOT_REGULAR_FILE) { |
| 626 | count = 0; | 623 | count = 0; |
| 627 | fd = open(filename, O_RDONLY); | 624 | fd = open("/proc/self/fd/0", O_RDONLY); |
| 625 | if (fd < 0 && num_lines == REOPEN_AND_COUNT) { | ||
| 626 | /* "filename" is valid only if REOPEN_AND_COUNT */ | ||
| 627 | fd = open(filename, O_RDONLY); | ||
| 628 | } | ||
| 628 | if (fd < 0) { | 629 | if (fd < 0) { |
| 629 | /* somebody stole my file! */ | 630 | /* somebody stole my file! */ |
| 630 | num_lines = READING_NONREG; | 631 | num_lines = NOT_REGULAR_FILE; |
| 631 | return; | 632 | return; |
| 632 | } | 633 | } |
| 634 | #if ENABLE_FEATURE_LESS_FLAGS | ||
| 635 | { | ||
| 636 | struct stat stbuf; | ||
| 637 | if (fstat(fd, &stbuf) != 0 | ||
| 638 | || !S_ISREG(stbuf.st_mode) | ||
| 639 | ) { | ||
| 640 | num_lines = NOT_REGULAR_FILE; | ||
| 641 | goto do_close; | ||
| 642 | } | ||
| 643 | } | ||
| 644 | #endif | ||
| 633 | while ((len = safe_read(fd, buf, sizeof(buf))) > 0) { | 645 | while ((len = safe_read(fd, buf, sizeof(buf))) > 0) { |
| 634 | for (i = 0; i < len; ++i) { | 646 | for (i = 0; i < len; ++i) { |
| 635 | if (buf[i] == '\n' && ++count == MAXLINES) | 647 | if (buf[i] == '\n' && ++count == MAXLINES) |
| @@ -638,6 +650,7 @@ static void update_num_lines(void) | |||
| 638 | } | 650 | } |
| 639 | done: | 651 | done: |
| 640 | num_lines = count; | 652 | num_lines = count; |
| 653 | do_close: | ||
| 641 | close(fd); | 654 | close(fd); |
| 642 | } | 655 | } |
| 643 | } | 656 | } |
| @@ -991,18 +1004,17 @@ static void buffer_lineno(int lineno) | |||
| 991 | static void open_file_and_read_lines(void) | 1004 | static void open_file_and_read_lines(void) |
| 992 | { | 1005 | { |
| 993 | if (filename) { | 1006 | if (filename) { |
| 1007 | xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO); | ||
| 994 | #if ENABLE_FEATURE_LESS_FLAGS | 1008 | #if ENABLE_FEATURE_LESS_FLAGS |
| 995 | struct stat stbuf; | 1009 | num_lines = REOPEN_AND_COUNT; |
| 996 | |||
| 997 | xstat(filename, &stbuf); | ||
| 998 | if (!S_ISREG(stbuf.st_mode)) | ||
| 999 | num_lines = READING_NONREG; | ||
| 1000 | #endif | 1010 | #endif |
| 1001 | xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO); | ||
| 1002 | } else { | 1011 | } else { |
| 1003 | /* "less" with no arguments in argv[] */ | 1012 | /* "less" with no arguments in argv[] */ |
| 1004 | /* For status line only */ | 1013 | /* For status line only */ |
| 1005 | filename = xstrdup(bb_msg_standard_input); | 1014 | filename = xstrdup(bb_msg_standard_input); |
| 1015 | #if ENABLE_FEATURE_LESS_FLAGS | ||
| 1016 | num_lines = REOPEN_STDIN; | ||
| 1017 | #endif | ||
| 1006 | } | 1018 | } |
| 1007 | readpos = 0; | 1019 | readpos = 0; |
| 1008 | readeof = 0; | 1020 | readeof = 0; |
| @@ -1026,9 +1038,6 @@ static void reinitialize(void) | |||
| 1026 | max_fline = -1; | 1038 | max_fline = -1; |
| 1027 | cur_fline = 0; | 1039 | cur_fline = 0; |
| 1028 | max_lineno = 0; | 1040 | max_lineno = 0; |
| 1029 | #if ENABLE_FEATURE_LESS_FLAGS | ||
| 1030 | num_lines = filename ? READING_FILE : READING_STDIN; | ||
| 1031 | #endif | ||
| 1032 | open_file_and_read_lines(); | 1041 | open_file_and_read_lines(); |
| 1033 | #if ENABLE_FEATURE_LESS_ASK_TERMINAL | 1042 | #if ENABLE_FEATURE_LESS_ASK_TERMINAL |
| 1034 | if (G.winsize_err) | 1043 | if (G.winsize_err) |
