less: rearrange detection of non-regular files

Move the code to detect non-regular files to the point where the
file is being opened.  If num_lines == READING_FILE guarantees
that the file is regular.

Detect when a file becomes unreadable between it first being opened
and the call to update_num_lines.  Mark the file as being non-regular
so we don't try that again.

function                                             old     new   delta
reinitialize                                         197     245     +48
update_num_lines                                     159     127     -32
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 48/-32)             Total: 16 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Ron Yorston 2015-07-24 14:28:08 +01:00 committed by Denys Vlasenko
parent 159e032bf4
commit 70b84be9e8

View File

@ -167,7 +167,8 @@ enum { pattern_valid = 0 };
enum { enum {
READING_FILE = -1, READING_FILE = -1,
READING_STDIN = -2 READING_STDIN = -2,
READING_NONREG = -3
}; };
struct globals { struct globals {
@ -615,15 +616,16 @@ static void update_num_lines(void)
int count, fd; int count, fd;
ssize_t len, i; ssize_t len, i;
char buf[4096]; char buf[4096];
struct stat stbuf;
/* only do this for regular files */
if (num_lines == READING_FILE) { if (num_lines == READING_FILE) {
count = 0; count = 0;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) if (fd < 0) {
goto skip; /* somebody stole my file! */
if (fstat(fd, &stbuf) != 0 || !S_ISREG(stbuf.st_mode)) num_lines = READING_NONREG;
goto do_close; return;
}
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)
@ -632,9 +634,7 @@ static void update_num_lines(void)
} }
done: done:
num_lines = count; num_lines = count;
do_close:
close(fd); close(fd);
skip: ;
} }
} }
@ -943,6 +943,13 @@ static void buffer_line(int linenum)
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);
} else { } else {
/* "less" with no arguments in argv[] */ /* "less" with no arguments in argv[] */