all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Jonathan Tomer <jktomer@google.com>
To: 35497@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de
Cc: Jonathan Tomer <jktomer@google.com>
Subject: bug#35497: [PATCH v3] Don't rewrite buffer contents after saving by rename
Date: Wed,  1 May 2019 16:02:01 -0700	[thread overview]
Message-ID: <20190501230200.46879-1-jktomer@google.com> (raw)
In-Reply-To: <83tveeosqe.fsf@gnu.org>

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






  parent reply	other threads:[~2019-05-01 23:02 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-29 23:20 bug#35497: [PATCH] Don't rewrite buffer contents after saving by rename Jonathan Tomer
2019-04-30  7:18 ` Michael Albinus
2019-04-30 19:27   ` Jonathan Tomer
2019-04-30 20:47     ` Michael Albinus
2019-04-30 21:10       ` Jonathan Tomer
2019-04-30 21:21         ` Michael Albinus
2019-04-30 22:42           ` Jonathan Tomer
2019-05-01  0:26           ` bug#35497: [PATCH v2] " Jonathan Tomer
2019-05-01 17:48         ` bug#35497: [PATCH] " Eli Zaretskii
2019-05-01 19:29           ` Jonathan Tomer
2019-05-01 19:54             ` Eli Zaretskii
2019-05-01 19:56               ` Jonathan Tomer
2019-05-01 23:02               ` Jonathan Tomer [this message]
2019-05-02 11:50                 ` bug#35497: [PATCH v3] " Michael Albinus
2019-05-02 22:04                   ` Jonathan Tomer
2019-05-02 22:06                   ` bug#35497: [PATCH v4] " Jonathan Tomer
2019-05-03  7:52 ` Michael Albinus
2019-05-03 12:29   ` Eli Zaretskii
2019-05-06 20:45   ` Jonathan Tomer
2019-05-07 14:05     ` Michael Albinus
2019-05-07 23:46       ` Richard Stallman
2019-05-06 20:46   ` bug#35497: [PATCH v5] " Jonathan Tomer
2019-05-06 20:48   ` bug#35497: [PATCH v6] " Jonathan Tomer
2019-05-07 14:03     ` Michael Albinus
2019-05-07 14:10       ` Michael Albinus
2019-05-07 17:25         ` Jonathan Tomer
2019-05-07 17:33         ` bug#35497: [PATCH v7] " Jonathan Tomer
2019-05-08  7:48           ` Michael Albinus
2019-05-08 17:03             ` Jonathan Tomer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190501230200.46879-1-jktomer@google.com \
    --to=jktomer@google.com \
    --cc=35497@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=michael.albinus@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.