aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2013-07-16 14:49:32 -0700
committerPaul Eggert2013-07-16 14:49:32 -0700
commit41d48a42df6ce4e5af9543f97313e256f16aa900 (patch)
tree2c23587c2691d181eb1561ee7347924887f73e53 /src
parent27e498e6e5fea8ac64c90ac13678b537b7b12302 (diff)
downloademacs-41d48a42df6ce4e5af9543f97313e256f16aa900.tar.gz
emacs-41d48a42df6ce4e5af9543f97313e256f16aa900.zip
Fix bug where insert-file-contents closes a file twice.
* fileio.c (close_file_unwind): Don't close if FD is negative; this can happen when unwinding a zapped file descriptor. (Finsert_file_contents): Unwind-protect the fd before the point marker, in case Emacs runs out of memory between the two unwind-protects. Don't trash errno when closing FD. Zap the FD in the specpdl when closing it, instead of deferring the removal of the unwind-protect; this fixes a bug where a child function unwinds the stack past us. Fixes: debbugs:14839
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog10
-rw-r--r--src/fileio.c28
-rw-r--r--src/lisp.h6
3 files changed, 25 insertions, 19 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 8474e8aa5e4..ab90682aa67 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,15 @@
12013-07-16 Paul Eggert <eggert@cs.ucla.edu> 12013-07-16 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Fix bug where Emacs tries to close a file twice (Bug#14839).
4 * fileio.c (close_file_unwind): Don't close if FD is negative;
5 this can happen when unwinding a zapped file descriptor.
6 (Finsert_file_contents): Unwind-protect the fd before the point marker,
7 in case Emacs runs out of memory between the two unwind-protects.
8 Don't trash errno when closing FD.
9 Zap the FD in the specpdl when closing it, instead of deferring
10 the removal of the unwind-protect; this fixes a bug where a child
11 function unwinds the stack past us.
12
3 New unwind-protect flavors to better type-check C callbacks. 13 New unwind-protect flavors to better type-check C callbacks.
4 This also lessens the need to write wrappers for callbacks, 14 This also lessens the need to write wrappers for callbacks,
5 and the need for make_save_pointer. 15 and the need for make_save_pointer.
diff --git a/src/fileio.c b/src/fileio.c
index 1b5208e5f25..b74b0ca91c2 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -215,7 +215,8 @@ report_file_error (char const *string, Lisp_Object name)
215void 215void
216close_file_unwind (int fd) 216close_file_unwind (int fd)
217{ 217{
218 emacs_close (fd); 218 if (0 <= fd)
219 emacs_close (fd);
219} 220}
220 221
221/* Restore point, having saved it as a marker. */ 222/* Restore point, having saved it as a marker. */
@@ -3514,7 +3515,7 @@ by calling `format-decode', which see. */)
3514 && BEG == Z); 3515 && BEG == Z);
3515 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; 3516 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
3516 bool we_locked_file = 0; 3517 bool we_locked_file = 0;
3517 bool deferred_remove_unwind_protect = 0; 3518 ptrdiff_t fd_index;
3518 3519
3519 if (current_buffer->base_buffer && ! NILP (visit)) 3520 if (current_buffer->base_buffer && ! NILP (visit))
3520 error ("Cannot do file visiting in an indirect buffer"); 3521 error ("Cannot do file visiting in an indirect buffer");
@@ -3565,12 +3566,13 @@ by calling `format-decode', which see. */)
3565 goto notfound; 3566 goto notfound;
3566 } 3567 }
3567 3568
3569 fd_index = SPECPDL_INDEX ();
3570 record_unwind_protect_int (close_file_unwind, fd);
3571
3568 /* Replacement should preserve point as it preserves markers. */ 3572 /* Replacement should preserve point as it preserves markers. */
3569 if (!NILP (replace)) 3573 if (!NILP (replace))
3570 record_unwind_protect (restore_point_unwind, Fpoint_marker ()); 3574 record_unwind_protect (restore_point_unwind, Fpoint_marker ());
3571 3575
3572 record_unwind_protect_int (close_file_unwind, fd);
3573
3574 if (fstat (fd, &st) != 0) 3576 if (fstat (fd, &st) != 0)
3575 report_file_error ("Input file status", orig_filename); 3577 report_file_error ("Input file status", orig_filename);
3576 mtime = get_stat_mtime (&st); 3578 mtime = get_stat_mtime (&st);
@@ -4015,15 +4017,10 @@ by calling `format-decode', which see. */)
4015 memcpy (read_buf, coding.carryover, unprocessed); 4017 memcpy (read_buf, coding.carryover, unprocessed);
4016 } 4018 }
4017 UNGCPRO; 4019 UNGCPRO;
4018 emacs_close (fd);
4019
4020 /* We should remove the unwind_protect calling
4021 close_file_unwind, but other stuff has been added the stack,
4022 so defer the removal till we reach the `handled' label. */
4023 deferred_remove_unwind_protect = 1;
4024
4025 if (this < 0) 4020 if (this < 0)
4026 report_file_error ("Read error", orig_filename); 4021 report_file_error ("Read error", orig_filename);
4022 emacs_close (fd);
4023 set_unwind_protect_int (fd_index, -1);
4027 4024
4028 if (unprocessed > 0) 4025 if (unprocessed > 0)
4029 { 4026 {
@@ -4264,9 +4261,7 @@ by calling `format-decode', which see. */)
4264 Vdeactivate_mark = Qt; 4261 Vdeactivate_mark = Qt;
4265 4262
4266 emacs_close (fd); 4263 emacs_close (fd);
4267 4264 set_unwind_protect_int (fd_index, -1);
4268 /* Discard the unwind protect for closing the file. */
4269 specpdl_ptr--;
4270 4265
4271 if (how_much < 0) 4266 if (how_much < 0)
4272 report_file_error ("Read error", orig_filename); 4267 report_file_error ("Read error", orig_filename);
@@ -4393,11 +4388,6 @@ by calling `format-decode', which see. */)
4393 4388
4394 handled: 4389 handled:
4395 4390
4396 if (deferred_remove_unwind_protect)
4397 /* If requested above, discard the unwind protect for closing the
4398 file. */
4399 specpdl_ptr--;
4400
4401 if (!NILP (visit)) 4391 if (!NILP (visit))
4402 { 4392 {
4403 if (empty_undo_list_p) 4393 if (empty_undo_list_p)
diff --git a/src/lisp.h b/src/lisp.h
index 38413f831dc..26e9e18ec9a 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2750,6 +2750,12 @@ set_unwind_protect_ptr (ptrdiff_t count, void *arg)
2750 specpdl[count].unwind_ptr.arg = arg; 2750 specpdl[count].unwind_ptr.arg = arg;
2751} 2751}
2752 2752
2753LISP_INLINE void
2754set_unwind_protect_int (ptrdiff_t count, int arg)
2755{
2756 specpdl[count].unwind_int.arg = arg;
2757}
2758
2753/* Everything needed to describe an active condition case. 2759/* Everything needed to describe an active condition case.
2754 2760
2755 Members are volatile if their values need to survive _longjmp when 2761 Members are volatile if their values need to survive _longjmp when