[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: backup-buffer-copy loops if old backup can't be deleted

From: Ulrich Mueller
Subject: Re: backup-buffer-copy loops if old backup can't be deleted
Date: Wed, 22 Aug 2007 11:51:52 +0200

>>>>> On Wed, 22 Aug 2007, Martin von Gagern wrote:

> I can think of at least two scenarios where this could be a problem:

> 1. The dir is not writable, but the backup file is. Here the current
>    behaviour will loop and even with the suggested fix it will fall
>    back to ~/%backup%~ unnecessarily.

> [...]

> I originally assumed that emacs would try backup-buffer-copy only
> after figuring out that it could not write to the existing backup
> file, but it seems I was wrong there, at least if I read
> backup-buffer correctly.

It seems that your assumption is the intended behaviour. At least the
problem was noticed and a fix was installed in March 2005:

However, it no longer works due to the introduction of the loop in
backup-buffer-copy one month later (this change was in CVS revision
1.757 of files.el). The relevant part is:

 (defun backup-buffer-copy (from-name to-name modes)
-  (condition-case ()
-      (copy-file from-name to-name t t)
-    (file-error
-     ;; If copying fails because file TO-NAME
-     ;; is not writable, delete that file and try again.
-     (if (and (file-exists-p to-name)
-             (not (file-writable-p to-name)))
-        (delete-file to-name))
-     (copy-file from-name to-name t t)))
+  (let ((umask (default-file-modes)))
+    (unwind-protect
+       (progn
+         ;; Create temp files with strict access rights.  It's easy to
+         ;; loosen them later, whereas it's impossible to close the
+         ;; time-window of loose permissions otherwise.
+         (set-default-file-modes ?\700)
+         (while (condition-case ()
+                    (progn
+                      (condition-case nil
+                          (delete-file to-name)
+                        (file-error nil))
+                      (write-region "" nil to-name nil 'silent nil 'excl)
+                      nil)
+                  (file-already-exists t))
+           ;; the file was somehow created by someone else between
+           ;; `make-temp-name' and `write-region', let's try again.
+           nil)
+         (copy-file from-name to-name t t 'excl))
+      ;; Reset the umask.
+      (set-default-file-modes umask)))
   (and modes
        (set-file-modes to-name (logand modes #o1777))))

with the following ChangeLog entry:

2005-04-23  Richard M. Stallman  <address@hidden>

        * files.el [...]
        (backup-buffer-copy, basic-save-buffer-2): Take care against
        writing thru an unexpected existing symlink.

There should be easier ways to achieve protection against writing
through symlinks.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]