[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rena
From: |
Jonathan Tomer |
Subject: |
bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rename |
Date: |
Wed, 1 May 2019 16:02:01 -0700 |
When `file-precious-flag' is non-nil, files are saved by renaming a
temporary file to the new name; this is an atomic operation on POSIX
so other programs will not see the file in an intermediate state.
Unfortunately, due to a paren-matching error introduced in change
574c05e219476912db3105fa164accd9ba12b35f, we would then write the
contents again in the usual way after this rename. In addition to
being wasteful, this is a serious bug: the whole point of
`file-precious-flag' is to prevent race conditions with other programs
that might otherwise see an empty file, but with this bug the race is
actually much *more* likely to be visible: the rename will alert any
inotify watchers of a change, and then the subsequent write is very
likely to truncate the file just as those programs start to read it!
* lisp/files.el (basic-save-buffer-2): Don't rewrite file contents
after saving-by-renaming.
* test/lisp/files-tests.el (files-tests-dont-rewrite-precious-files):
* test/lisp/net/tramp-tests.el (tramp-test46-file-precious-flag):
Regression tests for this change.
---
lisp/files.el | 4 ++--
test/lisp/files-tests.el | 13 +++++++++++++
test/lisp/net/tramp-tests.el | 16 ++++++++++++++++
3 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/lisp/files.el b/lisp/files.el
index c05d70a00e..72518e8127 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5256,7 +5256,7 @@ basic-save-buffer-2
(set-file-extended-attributes buffer-file-name
(nth 1 setmodes)))
(set-file-modes buffer-file-name
- (logior (car setmodes) 128))))))
+ (logior (car setmodes) 128)))))
(let (success)
(unwind-protect
(progn
@@ -5272,7 +5272,7 @@ basic-save-buffer-2
(and setmodes (not success)
(progn
(rename-file (nth 2 setmodes) buffer-file-name t)
- (setq buffer-backed-up nil))))))
+ (setq buffer-backed-up nil)))))))
setmodes))
(declare-function diff-no-select "diff"
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index ae8ea41a79..0becde4184 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1244,5 +1244,18 @@ files-tests-file-attributes-equal
(executable-find (file-name-nondirectory tmpfile))))))
(delete-file tmpfile))))
+(ert-deftest files-tests-dont-rewrite-precious-files ()
+ "Test that `file-precious-flag' forces files to be saved by
+renaming only, rather than modified in-place."
+ (files-tests--with-temp-file temp-file-name
+ (files-tests--with-advice
+ write-region :before
+ (lambda (_start _end filename &rest r)
+ (should (not (string= filename temp-file-name))))
+ (with-current-buffer (find-file-noselect temp-file-name)
+ (setq-local file-precious-flag t)
+ (insert "foobar")
+ (should (null (save-buffer)))))))
+
(provide 'files-tests)
;;; files-tests.el ends here
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index cba697da18..03ce6a5e94 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -5741,6 +5741,22 @@ tramp--test-asynchronous-requests-timeout
(ignore-errors (all-completions "tramp" (symbol-value x)))
(ert-fail (format "Hook `%s' still contains Tramp function" x))))))
+(ert-deftest tramp-test46-file-precious-flag ()
+ "Check that file-precious-flag is respected with Tramp in use."
+ (let* ((temp-file (make-temp-file "emacs"))
+ (remote-file (concat "/mock:localhost:" temp-file))
+ (advice (lambda (_start _end filename &rest r)
+ (should (not (string= filename temp-file)))
+ (should (not (string= filename remote-file))))))
+ (unwind-protect
+ (with-current-buffer (find-file-noselect remote-file)
+ (advice-add 'write-region :before advice)
+ (setq-local file-precious-flag t)
+ (insert "foobar")
+ (should (null (save-buffer))))
+ (advice-remove 'write-region advice)
+ (delete-file temp-file))))
+
(defun tramp-test-all (&optional interactive)
"Run all tests for \\[tramp]."
(interactive "p")
--
2.21.0.593.g511ec345e18-goog
- bug#35497: [PATCH] Don't rewrite buffer contents after saving by rename, Eli Zaretskii, 2019/05/01
- bug#35497: [PATCH] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/01
- bug#35497: [PATCH] Don't rewrite buffer contents after saving by rename, Eli Zaretskii, 2019/05/01
- bug#35497: [PATCH] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/01
- bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rename,
Jonathan Tomer <=
- bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rename, Michael Albinus, 2019/05/02
- bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/02
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/02
- Message not available
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Michael Albinus, 2019/05/03
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Eli Zaretskii, 2019/05/03
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/06
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Michael Albinus, 2019/05/07
- bug#35497: [PATCH v4] Don't rewrite buffer contents after saving by rename, Richard Stallman, 2019/05/07
- bug#35497: [PATCH v5] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/06
- bug#35497: [PATCH v6] Don't rewrite buffer contents after saving by rename, Jonathan Tomer, 2019/05/06