mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
Fix insert-file-contents on /proc files
This should fix Bug#9800 (2011-10-19). * src/fileio.c (Finsert_file_contents): Do not trust st_size even on regular files, as the file might be a Linux /proc file, or it might be growing. Instead, always read to EOF when END is nil.
This commit is contained in:
parent
bae5fa5d9a
commit
b950b46f51
57
src/fileio.c
57
src/fileio.c
@ -3907,7 +3907,6 @@ by calling `format-decode', which see. */)
|
||||
struct timespec mtime;
|
||||
int fd;
|
||||
ptrdiff_t inserted = 0;
|
||||
ptrdiff_t how_much;
|
||||
int unprocessed;
|
||||
specpdl_ref count = SPECPDL_INDEX ();
|
||||
Lisp_Object handler, val, insval, orig_filename, old_undo;
|
||||
@ -3920,7 +3919,8 @@ by calling `format-decode', which see. */)
|
||||
bool replace_handled = false;
|
||||
bool set_coding_system = false;
|
||||
Lisp_Object coding_system;
|
||||
bool read_quit = false;
|
||||
/* Negative if read error, 0 if OK so far, positive if quit. */
|
||||
ptrdiff_t read_quit = 0;
|
||||
/* If the undo log only contains the insertion, there's no point
|
||||
keeping it. It's typically when we first fill a file-buffer. */
|
||||
bool empty_undo_list_p
|
||||
@ -4404,7 +4404,7 @@ by calling `format-decode', which see. */)
|
||||
ptrdiff_t bufpos;
|
||||
unsigned char *decoded;
|
||||
ptrdiff_t temp;
|
||||
ptrdiff_t this = 0;
|
||||
ptrdiff_t this;
|
||||
specpdl_ref this_count = SPECPDL_INDEX ();
|
||||
bool multibyte
|
||||
= ! NILP (BVAR (current_buffer, enable_multibyte_characters));
|
||||
@ -4580,8 +4580,12 @@ by calling `format-decode', which see. */)
|
||||
}
|
||||
|
||||
move_gap_both (PT, PT_BYTE);
|
||||
if (GAP_SIZE < total)
|
||||
make_gap (total - GAP_SIZE);
|
||||
|
||||
/* Ensure the gap is at least one byte larger than needed for the
|
||||
estimated file size, so that in the usual case we read to EOF
|
||||
without reallocating. */
|
||||
if (GAP_SIZE <= total)
|
||||
make_gap (total - GAP_SIZE + 1);
|
||||
|
||||
if (beg_offset != 0 || !NILP (replace))
|
||||
{
|
||||
@ -4589,12 +4593,6 @@ by calling `format-decode', which see. */)
|
||||
report_file_error ("Setting file position", orig_filename);
|
||||
}
|
||||
|
||||
/* In the following loop, HOW_MUCH contains the total bytes read so
|
||||
far for a regular file, and not changed for a special file. But,
|
||||
before exiting the loop, it is set to a negative value if I/O
|
||||
error occurs. */
|
||||
how_much = 0;
|
||||
|
||||
/* Total bytes inserted. */
|
||||
inserted = 0;
|
||||
|
||||
@ -4603,23 +4601,26 @@ by calling `format-decode', which see. */)
|
||||
{
|
||||
ptrdiff_t gap_size = GAP_SIZE;
|
||||
|
||||
while (how_much < total)
|
||||
while (NILP (end) || inserted < total)
|
||||
{
|
||||
/* `try' is reserved in some compilers (Microsoft C). */
|
||||
ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
|
||||
ptrdiff_t this;
|
||||
|
||||
if (gap_size == 0)
|
||||
{
|
||||
/* The size estimate was wrong. Make the gap 50% larger. */
|
||||
make_gap (GAP_SIZE >> 1);
|
||||
gap_size = GAP_SIZE - inserted;
|
||||
}
|
||||
|
||||
/* 'try' is reserved in some compilers (Microsoft C). */
|
||||
ptrdiff_t trytry = min (gap_size, READ_BUF_SIZE);
|
||||
if (!NILP (end))
|
||||
trytry = min (trytry, total - inserted);
|
||||
|
||||
if (!seekable && NILP (end))
|
||||
{
|
||||
Lisp_Object nbytes;
|
||||
|
||||
/* Maybe make more room. */
|
||||
if (gap_size < trytry)
|
||||
{
|
||||
make_gap (trytry - gap_size);
|
||||
gap_size = GAP_SIZE - inserted;
|
||||
}
|
||||
|
||||
/* Read from the file, capturing `quit'. When an
|
||||
error occurs, end the loop, and arrange for a quit
|
||||
to be signaled after decoding the text we read. */
|
||||
@ -4630,7 +4631,7 @@ by calling `format-decode', which see. */)
|
||||
|
||||
if (NILP (nbytes))
|
||||
{
|
||||
read_quit = true;
|
||||
read_quit = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4649,19 +4650,11 @@ by calling `format-decode', which see. */)
|
||||
|
||||
if (this <= 0)
|
||||
{
|
||||
how_much = this;
|
||||
read_quit = this;
|
||||
break;
|
||||
}
|
||||
|
||||
gap_size -= this;
|
||||
|
||||
/* For a regular file, where TOTAL is the real size,
|
||||
count HOW_MUCH to compare with it.
|
||||
For a special file, where TOTAL is just a buffer size,
|
||||
so don't bother counting in HOW_MUCH.
|
||||
(INSERTED is where we count the number of characters inserted.) */
|
||||
if (seekable || !NILP (end))
|
||||
how_much += this;
|
||||
inserted += this;
|
||||
}
|
||||
}
|
||||
@ -4682,7 +4675,7 @@ by calling `format-decode', which see. */)
|
||||
emacs_close (fd);
|
||||
clear_unwind_protect (fd_index);
|
||||
|
||||
if (how_much < 0)
|
||||
if (read_quit < 0)
|
||||
report_file_error ("Read error", orig_filename);
|
||||
|
||||
notfound:
|
||||
|
Loading…
Reference in New Issue
Block a user