]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve inserted file coding system finding
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 12 Jul 2025 17:03:26 +0000 (10:03 -0700)
committerEshel Yaron <me@eshelyaron.com>
Thu, 24 Jul 2025 08:47:30 +0000 (10:47 +0200)
* 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.

(cherry picked from commit 6a9dbed40ccebc18fda6078058b1978e29ef98fa)

src/fileio.c

index cbdfeacf8e4e1dac5cb211d718fcfa6dccf4ff38..5d383a7b44dc6d3d129c18a880df51d2019e98ce 100644 (file)
@@ -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;
                    }
                }