aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/fileio.c b/src/fileio.c
index cbdfeacf8e4..5d383a7b44d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4289,12 +4289,38 @@ by calling `format-decode', which see. */)
4289 { 4289 {
4290 off_t tailoff = emacs_fd_lseek (fd, - 3 * 1024, SEEK_END); 4290 off_t tailoff = emacs_fd_lseek (fd, - 3 * 1024, SEEK_END);
4291 if (tailoff < 0) 4291 if (tailoff < 0)
4292 seekable = false;
4293 else if (1024 < tailoff)
4294 { 4292 {
4295 ptrdiff_t ntail = emacs_fd_read (fd, read_buf + 1024, 4293 seekable = false;
4296 3 * 1024); 4294 tailoff = nread;
4297 nread = ntail < 0 ? ntail : 1024 + ntail; 4295 }
4296
4297 /* When appending the last 3 KiB, read until EOF
4298 without trusting tailoff, as the file may be in
4299 /proc or be mutating. */
4300 nread = 1024;
4301 for (;;)
4302 {
4303 ptrdiff_t r = emacs_fd_read (fd, read_buf + nread,
4304 sizeof read_buf - nread);
4305 if (r <= 0)
4306 {
4307 if (r < 0)
4308 nread = r;
4309 else
4310 file_size_hint = tailoff;
4311 break;
4312 }
4313 tailoff += r;
4314 nread += r;
4315 bool eof = nread < sizeof read_buf;
4316 if (4 * 1024 < nread)
4317 {
4318 memmove (read_buf + 1024,
4319 read_buf + nread - 3 * 1024, 3 * 1024);
4320 nread = 4 * 1024;
4321 }
4322 if (eof)
4323 break;
4298 } 4324 }
4299 } 4325 }
4300 4326