less: improve regular file detection in line counting code
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
1ecb996fd2
commit
9dc526d0f9
@ -165,12 +165,6 @@ enum {
|
|||||||
enum { pattern_valid = 0 };
|
enum { pattern_valid = 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
|
||||||
READING_FILE = -1,
|
|
||||||
READING_STDIN = -2,
|
|
||||||
READING_NONREG = -3
|
|
||||||
};
|
|
||||||
|
|
||||||
struct globals {
|
struct globals {
|
||||||
int cur_fline; /* signed */
|
int cur_fline; /* signed */
|
||||||
int kbd_fd; /* fd to get input from */
|
int kbd_fd; /* fd to get input from */
|
||||||
@ -195,7 +189,10 @@ struct globals {
|
|||||||
char *filename;
|
char *filename;
|
||||||
char **files;
|
char **files;
|
||||||
#if ENABLE_FEATURE_LESS_FLAGS
|
#if ENABLE_FEATURE_LESS_FLAGS
|
||||||
int num_lines; /* input source if < 0, line count if >= 0 */
|
int num_lines; /* a flag if < 0, line count if >= 0 */
|
||||||
|
# define REOPEN_AND_COUNT (-1)
|
||||||
|
# define REOPEN_STDIN (-2)
|
||||||
|
# define NOT_REGULAR_FILE (-3)
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_LESS_MARKS
|
#if ENABLE_FEATURE_LESS_MARKS
|
||||||
unsigned num_marks;
|
unsigned num_marks;
|
||||||
@ -622,14 +619,29 @@ static void update_num_lines(void)
|
|||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
|
||||||
/* only do this for regular files */
|
/* only do this for regular files */
|
||||||
if (num_lines == READING_FILE) {
|
if (num_lines != NOT_REGULAR_FILE) {
|
||||||
count = 0;
|
count = 0;
|
||||||
fd = open(filename, O_RDONLY);
|
fd = open("/proc/self/fd/0", O_RDONLY);
|
||||||
|
if (fd < 0 && num_lines == REOPEN_AND_COUNT) {
|
||||||
|
/* "filename" is valid only if REOPEN_AND_COUNT */
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
}
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
/* somebody stole my file! */
|
/* somebody stole my file! */
|
||||||
num_lines = READING_NONREG;
|
num_lines = NOT_REGULAR_FILE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if ENABLE_FEATURE_LESS_FLAGS
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
if (fstat(fd, &stbuf) != 0
|
||||||
|
|| !S_ISREG(stbuf.st_mode)
|
||||||
|
) {
|
||||||
|
num_lines = NOT_REGULAR_FILE;
|
||||||
|
goto do_close;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
while ((len = safe_read(fd, buf, sizeof(buf))) > 0) {
|
while ((len = safe_read(fd, buf, sizeof(buf))) > 0) {
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
if (buf[i] == '\n' && ++count == MAXLINES)
|
if (buf[i] == '\n' && ++count == MAXLINES)
|
||||||
@ -638,6 +650,7 @@ static void update_num_lines(void)
|
|||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
num_lines = count;
|
num_lines = count;
|
||||||
|
do_close:
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -991,18 +1004,17 @@ static void buffer_lineno(int lineno)
|
|||||||
static void open_file_and_read_lines(void)
|
static void open_file_and_read_lines(void)
|
||||||
{
|
{
|
||||||
if (filename) {
|
if (filename) {
|
||||||
#if ENABLE_FEATURE_LESS_FLAGS
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
xstat(filename, &stbuf);
|
|
||||||
if (!S_ISREG(stbuf.st_mode))
|
|
||||||
num_lines = READING_NONREG;
|
|
||||||
#endif
|
|
||||||
xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO);
|
xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO);
|
||||||
|
#if ENABLE_FEATURE_LESS_FLAGS
|
||||||
|
num_lines = REOPEN_AND_COUNT;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* "less" with no arguments in argv[] */
|
/* "less" with no arguments in argv[] */
|
||||||
/* For status line only */
|
/* For status line only */
|
||||||
filename = xstrdup(bb_msg_standard_input);
|
filename = xstrdup(bb_msg_standard_input);
|
||||||
|
#if ENABLE_FEATURE_LESS_FLAGS
|
||||||
|
num_lines = REOPEN_STDIN;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
readpos = 0;
|
readpos = 0;
|
||||||
readeof = 0;
|
readeof = 0;
|
||||||
@ -1026,9 +1038,6 @@ static void reinitialize(void)
|
|||||||
max_fline = -1;
|
max_fline = -1;
|
||||||
cur_fline = 0;
|
cur_fline = 0;
|
||||||
max_lineno = 0;
|
max_lineno = 0;
|
||||||
#if ENABLE_FEATURE_LESS_FLAGS
|
|
||||||
num_lines = filename ? READING_FILE : READING_STDIN;
|
|
||||||
#endif
|
|
||||||
open_file_and_read_lines();
|
open_file_and_read_lines();
|
||||||
#if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
#if ENABLE_FEATURE_LESS_ASK_TERMINAL
|
||||||
if (G.winsize_err)
|
if (G.winsize_err)
|
||||||
|
Loading…
Reference in New Issue
Block a user