mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
insert-file-contents st_size cleanup
* src/fileio.c (Finsert_file_contents): Store st_size, not file_size_hint, into current_buffer->modtime_size, since modtime_size is compared to a later st_size, not to the actual file size. Simplify buffer overflow detection from file size, since this occurred only on regular files.
This commit is contained in:
parent
5485bda523
commit
8d83402edc
2 changed files with 18 additions and 27 deletions
11
src/buffer.h
11
src/buffer.h
|
|
@ -649,11 +649,12 @@ struct buffer
|
|||
in no case complain about any mismatch on next save attempt. */
|
||||
struct timespec modtime;
|
||||
|
||||
/* Size of the file when modtime was set. This is used to detect the
|
||||
case where the file grew while we were reading it, so the modtime
|
||||
is still the same (since it's rounded up to seconds) but we're actually
|
||||
not up-to-date. -1 means the size is unknown. Only meaningful if
|
||||
modtime is actually set. */
|
||||
/* Size of the file when modtime was set. This is used to detect when
|
||||
the file size changed while we were reading the file, but the
|
||||
modtime is still the same (since it's truncated to clock resolution)
|
||||
so we're actually not up-to-date. Meaningful only if it is
|
||||
nonnegative and the modtime is actually set. Useful only on
|
||||
platforms with coarse clock resolution. */
|
||||
off_t modtime_size;
|
||||
|
||||
/* The value of text->modiff at the last auto-save. */
|
||||
|
|
|
|||
34
src/fileio.c
34
src/fileio.c
|
|
@ -4107,8 +4107,9 @@ by calling `format-decode', which see. */)
|
|||
restore_window_points needs the old character count. */
|
||||
ptrdiff_t same_at_end_charpos = ZV;
|
||||
|
||||
/* A hint about the file size, or -1 if there is no hint. */
|
||||
off_t file_size_hint = -1;
|
||||
/* The size reported by fstat, or -1 if the file was not found or its
|
||||
size is meaningless. */
|
||||
off_t st_size = -1;
|
||||
|
||||
if (current_buffer->base_buffer && ! NILP (visit))
|
||||
error ("Cannot do file visiting in an indirect buffer");
|
||||
|
|
@ -4201,11 +4202,12 @@ by calling `format-decode', which see. */)
|
|||
|
||||
if (regular | memory_object)
|
||||
{
|
||||
file_size_hint = st.st_size;
|
||||
st_size = st.st_size;
|
||||
|
||||
/* A negative size can happen on a platform that allows file
|
||||
sizes greater than the maximum off_t value. */
|
||||
if (file_size_hint < 0)
|
||||
/* On some ancient platforms, a regular file with a negative size means
|
||||
the actual file size is greater than the maximum off_t value.
|
||||
Fail now rather than doing a lot of work and exhausting memory. */
|
||||
if (st_size < 0)
|
||||
buffer_overflow ();
|
||||
}
|
||||
|
||||
|
|
@ -4256,7 +4258,7 @@ by calling `format-decode', which see. */)
|
|||
This saves a lot of needless work before a buffer overflow.
|
||||
If LIKELY_END is nonnegative, it is likely where we will stop reading.
|
||||
We could read more (or less), if the file grows (or shrinks). */
|
||||
off_t likely_end = min (end_offset, file_size_hint);
|
||||
off_t likely_end = min (end_offset, st_size);
|
||||
if (beg_offset < likely_end)
|
||||
{
|
||||
ptrdiff_t buf_bytes
|
||||
|
|
@ -4303,9 +4305,7 @@ by calling `format-decode', which see. */)
|
|||
do not use st_size or report any SEEK_END failure. */
|
||||
static_assert (4 * 1024 < sizeof read_buf);
|
||||
ptrdiff_t nread = emacs_full_read (fd, read_buf, 4 * 1024);
|
||||
if (nread < 4 * 1024)
|
||||
file_size_hint = nread;
|
||||
else
|
||||
if (4 * 1024 <= nread)
|
||||
{
|
||||
off_t tailoff = emacs_fd_lseek (fd, - 3 * 1024, SEEK_END);
|
||||
if (tailoff < 0)
|
||||
|
|
@ -4326,7 +4326,6 @@ by calling `format-decode', which see. */)
|
|||
}
|
||||
else if (0 <= nread)
|
||||
{
|
||||
file_size_hint = tailoff + nread;
|
||||
nread += 1024;
|
||||
if (4 * 1024 < nread)
|
||||
{
|
||||
|
|
@ -4480,8 +4479,6 @@ by calling `format-decode', which see. */)
|
|||
|
||||
if (nread < bytes_to_read)
|
||||
{
|
||||
file_size_hint = curpos + nread;
|
||||
|
||||
/* Data inserted from the file match the buffer's leading bytes,
|
||||
so there's no need to replace anything. */
|
||||
emacs_fd_close (fd);
|
||||
|
|
@ -4521,8 +4518,6 @@ by calling `format-decode', which see. */)
|
|||
|
||||
if (!giveup_match_end)
|
||||
{
|
||||
file_size_hint = endpos;
|
||||
|
||||
/* Shrink the file's head if the file shrank to
|
||||
be smaller than its head. */
|
||||
if (endpos < same_at_start_pos)
|
||||
|
|
@ -4569,7 +4564,6 @@ by calling `format-decode', which see. */)
|
|||
if (nread < 0)
|
||||
report_file_error ("Read error", orig_filename);
|
||||
/* The file unexpectedly shrank. */
|
||||
file_size_hint = curpos + nread;
|
||||
giveup_match_end = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -4686,7 +4680,6 @@ by calling `format-decode', which see. */)
|
|||
|
||||
inserted = 0; /* Bytes put into CONVERSION_BUFFER so far. */
|
||||
unprocessed = 0; /* Bytes not processed in previous loop. */
|
||||
file_size_hint = beg_offset;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -4700,7 +4693,6 @@ by calling `format-decode', which see. */)
|
|||
if (this == 0)
|
||||
break;
|
||||
|
||||
file_size_hint += this;
|
||||
BUF_TEMP_SET_PT (XBUFFER (conversion_buffer),
|
||||
BUF_Z (XBUFFER (conversion_buffer)));
|
||||
decode_coding_c_string (&coding, (unsigned char *) read_buf,
|
||||
|
|
@ -4861,7 +4853,7 @@ by calling `format-decode', which see. */)
|
|||
/* Ensure the gap is at least one byte larger than needed for the
|
||||
estimated insertion, so that in the usual case we read
|
||||
without reallocating. */
|
||||
off_t inserted_estimate = min (end_offset, file_size_hint) - beg_offset;
|
||||
off_t inserted_estimate = likely_end - beg_offset;
|
||||
if (GAP_SIZE <= inserted_estimate)
|
||||
{
|
||||
ptrdiff_t growth;
|
||||
|
|
@ -4958,8 +4950,6 @@ by calling `format-decode', which see. */)
|
|||
}
|
||||
}
|
||||
|
||||
file_size_hint = beg_offset + inserted;
|
||||
|
||||
/* Now we have either read all the file data into the gap,
|
||||
or stop reading on I/O error or quit. If nothing was
|
||||
read, undo marking the buffer modified. */
|
||||
|
|
@ -5119,7 +5109,7 @@ by calling `format-decode', which see. */)
|
|||
if (NILP (handler))
|
||||
{
|
||||
current_buffer->modtime = mtime;
|
||||
current_buffer->modtime_size = file_size_hint;
|
||||
current_buffer->modtime_size = st_size;
|
||||
bset_filename (current_buffer, orig_filename);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue