[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#67490: [PATCH] tail: fix following /proc and /sys files when using a
From: |
dann frazier |
Subject: |
bug#67490: [PATCH] tail: fix following /proc and /sys files when using a 64K page size |
Date: |
Mon, 27 Nov 2023 09:24:33 -0700 |
* src/tail.c (file_lines): Use fstat() to determine a file's block
size and dynamically allocate a buffer of that size for traversing
backwards.
---
src/tail.c | 36 ++++++++++++++++++++++++++----------
1 file changed, 26 insertions(+), 10 deletions(-)
diff --git a/src/tail.c b/src/tail.c
index c45f3b65a..437a38204 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -518,18 +518,30 @@ static bool
file_lines (char const *pretty_filename, int fd, uintmax_t n_lines,
off_t start_pos, off_t end_pos, uintmax_t *read_pos)
{
- char buffer[BUFSIZ];
+ char *buffer;
size_t bytes_read;
+ blksize_t bufsize;
off_t pos = end_pos;
+ bool ok = true;
+ struct stat stats;
if (n_lines == 0)
return true;
+ if (fstat (fd, &stats) != 0)
+ {
+ error (0, errno, _("cannot fstat %s"), quoteaf (pretty_filename));
+ return false;
+ }
+
+ bufsize = ST_BLKSIZE (stats);
+ buffer = xmalloc (bufsize);
+
/* Set 'bytes_read' to the size of the last, probably partial, buffer;
0 < 'bytes_read' <= 'BUFSIZ'. */
- bytes_read = (pos - start_pos) % BUFSIZ;
+ bytes_read = (pos - start_pos) % bufsize;
if (bytes_read == 0)
- bytes_read = BUFSIZ;
+ bytes_read = bufsize;
/* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all
reads will be on block boundaries, which might increase efficiency. */
pos -= bytes_read;
@@ -538,7 +550,8 @@ file_lines (char const *pretty_filename, int fd, uintmax_t
n_lines,
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, _("error reading %s"), quoteaf (pretty_filename));
- return false;
+ ok = false;
+ goto free_buffer;
}
*read_pos = pos + bytes_read;
@@ -565,7 +578,7 @@ file_lines (char const *pretty_filename, int fd, uintmax_t
n_lines,
xwrite_stdout (nl + 1, bytes_read - (n + 1));
*read_pos += dump_remainder (false, pretty_filename, fd,
end_pos - (pos + bytes_read));
- return true;
+ goto free_buffer;
}
}
@@ -577,23 +590,26 @@ file_lines (char const *pretty_filename, int fd,
uintmax_t n_lines,
xlseek (fd, start_pos, SEEK_SET, pretty_filename);
*read_pos = start_pos + dump_remainder (false, pretty_filename, fd,
end_pos);
- return true;
+ goto free_buffer;
}
- pos -= BUFSIZ;
+ pos -= bufsize;
xlseek (fd, pos, SEEK_SET, pretty_filename);
- bytes_read = safe_read (fd, buffer, BUFSIZ);
+ bytes_read = safe_read (fd, buffer, bufsize);
if (bytes_read == SAFE_READ_ERROR)
{
error (0, errno, _("error reading %s"), quoteaf (pretty_filename));
- return false;
+ ok = false;
+ goto free_buffer;
}
*read_pos = pos + bytes_read;
}
while (bytes_read > 0);
- return true;
+free_buffer:
+ free (buffer);
+ return ok;
}
/* Print the last N_LINES lines from the end of the standard input,
--
2.42.0
- bug#67490: [PATCH] tail: fix following /proc and /sys files when using a 64K page size,
dann frazier <=