summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2025-07-12 10:03:26 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2025-07-13 21:09:39 -0700
commit6a9dbed40ccebc18fda6078058b1978e29ef98fa (patch)
treef32c53d7b91e6678b5899e8d7eef11036d5942f1
parent6d09a339ceb986de6d2a49ac8c20a7360f57b7d6 (diff)
Improve inserted file coding system finding
* src/fileio.c (Finsert_file_contents): When inserting a file into a nonempty buffer, improve the heuristic for determining the file’s coding system by not trusting lseek+SEEK_END, which is unreliable in /proc or when the file is mutating.
-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. */)
{
off_t tailoff = emacs_fd_lseek (fd, - 3 * 1024, SEEK_END);
if (tailoff < 0)
- seekable = false;
- else if (1024 < tailoff)
{
- ptrdiff_t ntail = emacs_fd_read (fd, read_buf + 1024,
- 3 * 1024);
- nread = ntail < 0 ? ntail : 1024 + ntail;
+ seekable = false;
+ tailoff = nread;
+ }
+
+ /* When appending the last 3 KiB, read until EOF
+ without trusting tailoff, as the file may be in
+ /proc or be mutating. */
+ nread = 1024;
+ for (;;)
+ {
+ ptrdiff_t r = emacs_fd_read (fd, read_buf + nread,
+ sizeof read_buf - nread);
+ if (r <= 0)
+ {
+ if (r < 0)
+ nread = r;
+ else
+ file_size_hint = tailoff;
+ break;
+ }
+ tailoff += r;
+ nread += r;
+ bool eof = nread < sizeof read_buf;
+ if (4 * 1024 < nread)
+ {
+ memmove (read_buf + 1024,
+ read_buf + nread - 3 * 1024, 3 * 1024);
+ nread = 4 * 1024;
+ }
+ if (eof)
+ break;
}
}