aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2023-02-13 12:32:11 -0800
committerPaul Eggert2023-02-13 12:32:59 -0800
commitb950b46f514989442fdd9937a0e96d53a3affa88 (patch)
treecf02f481ec03906bdc17caa5baea265eeee28280 /src
parentbae5fa5d9a8ef8c41fbb3408eea441a2ee14d1db (diff)
downloademacs-b950b46f514989442fdd9937a0e96d53a3affa88.tar.gz
emacs-b950b46f514989442fdd9937a0e96d53a3affa88.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c57
1 files changed, 25 insertions, 32 deletions
diff --git a/src/fileio.c b/src/fileio.c
index ee30db8b49b..b80f8d61de4 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3907,7 +3907,6 @@ by calling `format-decode', which see. */)
3907 struct timespec mtime; 3907 struct timespec mtime;
3908 int fd; 3908 int fd;
3909 ptrdiff_t inserted = 0; 3909 ptrdiff_t inserted = 0;
3910 ptrdiff_t how_much;
3911 int unprocessed; 3910 int unprocessed;
3912 specpdl_ref count = SPECPDL_INDEX (); 3911 specpdl_ref count = SPECPDL_INDEX ();
3913 Lisp_Object handler, val, insval, orig_filename, old_undo; 3912 Lisp_Object handler, val, insval, orig_filename, old_undo;
@@ -3920,7 +3919,8 @@ by calling `format-decode', which see. */)
3920 bool replace_handled = false; 3919 bool replace_handled = false;
3921 bool set_coding_system = false; 3920 bool set_coding_system = false;
3922 Lisp_Object coding_system; 3921 Lisp_Object coding_system;
3923 bool read_quit = false; 3922 /* Negative if read error, 0 if OK so far, positive if quit. */
3923 ptrdiff_t read_quit = 0;
3924 /* If the undo log only contains the insertion, there's no point 3924 /* If the undo log only contains the insertion, there's no point
3925 keeping it. It's typically when we first fill a file-buffer. */ 3925 keeping it. It's typically when we first fill a file-buffer. */
3926 bool empty_undo_list_p 3926 bool empty_undo_list_p
@@ -4404,7 +4404,7 @@ by calling `format-decode', which see. */)
4404 ptrdiff_t bufpos; 4404 ptrdiff_t bufpos;
4405 unsigned char *decoded; 4405 unsigned char *decoded;
4406 ptrdiff_t temp; 4406 ptrdiff_t temp;
4407 ptrdiff_t this = 0; 4407 ptrdiff_t this;
4408 specpdl_ref this_count = SPECPDL_INDEX (); 4408 specpdl_ref this_count = SPECPDL_INDEX ();
4409 bool multibyte 4409 bool multibyte
4410 = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 4410 = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
@@ -4580,8 +4580,12 @@ by calling `format-decode', which see. */)
4580 } 4580 }
4581 4581
4582 move_gap_both (PT, PT_BYTE); 4582 move_gap_both (PT, PT_BYTE);
4583 if (GAP_SIZE < total) 4583
4584 make_gap (total - GAP_SIZE); 4584 /* Ensure the gap is at least one byte larger than needed for the
4585 estimated file size, so that in the usual case we read to EOF
4586 without reallocating. */
4587 if (GAP_SIZE <= total)
4588 make_gap (total - GAP_SIZE + 1);
4585 4589
4586 if (beg_offset != 0 || !NILP (replace)) 4590 if (beg_offset != 0 || !NILP (replace))
4587 { 4591 {
@@ -4589,12 +4593,6 @@ by calling `format-decode', which see. */)
4589 report_file_error ("Setting file position", orig_filename); 4593 report_file_error ("Setting file position", orig_filename);
4590 } 4594 }
4591 4595
4592 /* In the following loop, HOW_MUCH contains the total bytes read so
4593 far for a regular file, and not changed for a special file. But,
4594 before exiting the loop, it is set to a negative value if I/O
4595 error occurs. */
4596 how_much = 0;
4597
4598 /* Total bytes inserted. */ 4596 /* Total bytes inserted. */
4599 inserted = 0; 4597 inserted = 0;
4600 4598
@@ -4603,23 +4601,26 @@ by calling `format-decode', which see. */)
4603 { 4601 {
4604 ptrdiff_t gap_size = GAP_SIZE; 4602 ptrdiff_t gap_size = GAP_SIZE;
4605 4603
4606 while (how_much < total) 4604 while (NILP (end) || inserted < total)
4607 { 4605 {
4608 /* `try' is reserved in some compilers (Microsoft C). */
4609 ptrdiff_t trytry = min (total - how_much, READ_BUF_SIZE);
4610 ptrdiff_t this; 4606 ptrdiff_t this;
4611 4607
4608 if (gap_size == 0)
4609 {
4610 /* The size estimate was wrong. Make the gap 50% larger. */
4611 make_gap (GAP_SIZE >> 1);
4612 gap_size = GAP_SIZE - inserted;
4613 }
4614
4615 /* 'try' is reserved in some compilers (Microsoft C). */
4616 ptrdiff_t trytry = min (gap_size, READ_BUF_SIZE);
4617 if (!NILP (end))
4618 trytry = min (trytry, total - inserted);
4619
4612 if (!seekable && NILP (end)) 4620 if (!seekable && NILP (end))
4613 { 4621 {
4614 Lisp_Object nbytes; 4622 Lisp_Object nbytes;
4615 4623
4616 /* Maybe make more room. */
4617 if (gap_size < trytry)
4618 {
4619 make_gap (trytry - gap_size);
4620 gap_size = GAP_SIZE - inserted;
4621 }
4622
4623 /* Read from the file, capturing `quit'. When an 4624 /* Read from the file, capturing `quit'. When an
4624 error occurs, end the loop, and arrange for a quit 4625 error occurs, end the loop, and arrange for a quit
4625 to be signaled after decoding the text we read. */ 4626 to be signaled after decoding the text we read. */
@@ -4630,7 +4631,7 @@ by calling `format-decode', which see. */)
4630 4631
4631 if (NILP (nbytes)) 4632 if (NILP (nbytes))
4632 { 4633 {
4633 read_quit = true; 4634 read_quit = 1;
4634 break; 4635 break;
4635 } 4636 }
4636 4637
@@ -4649,19 +4650,11 @@ by calling `format-decode', which see. */)
4649 4650
4650 if (this <= 0) 4651 if (this <= 0)
4651 { 4652 {
4652 how_much = this; 4653 read_quit = this;
4653 break; 4654 break;
4654 } 4655 }
4655 4656
4656 gap_size -= this; 4657 gap_size -= this;
4657
4658 /* For a regular file, where TOTAL is the real size,
4659 count HOW_MUCH to compare with it.
4660 For a special file, where TOTAL is just a buffer size,
4661 so don't bother counting in HOW_MUCH.
4662 (INSERTED is where we count the number of characters inserted.) */
4663 if (seekable || !NILP (end))
4664 how_much += this;
4665 inserted += this; 4658 inserted += this;
4666 } 4659 }
4667 } 4660 }
@@ -4682,7 +4675,7 @@ by calling `format-decode', which see. */)
4682 emacs_close (fd); 4675 emacs_close (fd);
4683 clear_unwind_protect (fd_index); 4676 clear_unwind_protect (fd_index);
4684 4677
4685 if (how_much < 0) 4678 if (read_quit < 0)
4686 report_file_error ("Read error", orig_filename); 4679 report_file_error ("Read error", orig_filename);
4687 4680
4688 notfound: 4681 notfound: