aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-07-31 16:42:20 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-07-31 16:42:20 +0200
commit9dc526d0f91c37ecdf6280c2cd69107c6102076e (patch)
treef55255e96215b8a444c77c157be6858f32df3e07
parent1ecb996fd2641e6ad3fdf07e78781823c71fcf13 (diff)
downloadbusybox-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>
-rw-r--r--miscutils/less.c47
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 {
165enum { pattern_valid = 0 }; 165enum { pattern_valid = 0 };
166#endif 166#endif
167 167
168enum {
169 READING_FILE = -1,
170 READING_STDIN = -2,
171 READING_NONREG = -3
172};
173
174struct globals { 168struct 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)
991static void open_file_and_read_lines(void) 1004static 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)