]> git.eshelyaron.com Git - emacs.git/commitdiff
Add remote-file-name-inhibit-locks
authorMichael Albinus <michael.albinus@gmx.de>
Tue, 13 Jul 2021 17:50:05 +0000 (19:50 +0200)
committerMichael Albinus <michael.albinus@gmx.de>
Tue, 13 Jul 2021 17:50:05 +0000 (19:50 +0200)
* doc/emacs/files.texi (Interlocking):
* doc/lispref/files.texi (File Locks):
* doc/misc/tramp.texi (Auto-save File Lock and Backup):
Add remote-file-name-inhibit-locks.

* etc/NEWS: New user option 'remote-file-name-inhibit-locks'.

* lisp/files.el (remote-file-name-inhibit-locks): New defcustom.

* lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
* lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
* lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist):
* lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
* lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist):
* lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist):
* lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
Use `tramp-handle-make-lock-file-name'.

* lisp/net/tramp.el (tramp-allow-unsafe-temporary-files): Fix docstring.
(tramp-handle-make-lock-file-name): New defun.

* test/lisp/net/tramp-tests.el (tramp-test39-lock-file): Extend test.

15 files changed:
doc/emacs/files.texi
doc/lispref/files.texi
doc/misc/tramp.texi
etc/NEWS
lisp/files.el
lisp/net/tramp-adb.el
lisp/net/tramp-crypt.el
lisp/net/tramp-gvfs.el
lisp/net/tramp-rclone.el
lisp/net/tramp-sh.el
lisp/net/tramp-smb.el
lisp/net/tramp-sshfs.el
lisp/net/tramp-sudoedit.el
lisp/net/tramp.el
test/lisp/net/tramp-tests.el

index 98b6b194d2d61a364ea041cbbd79dc15642e698e..32a2f1bb8151296e9595dbbf1e5f6edfe7c47f58 100644 (file)
@@ -836,6 +836,10 @@ warning message and asks for confirmation before saving; answer
 place, one way to compare the buffer to its file is the @kbd{M-x
 diff-buffer-with-file} command.  @xref{Comparing Files}.
 
+@vindex remote-file-name-inhibit-locks
+  You can prevent the creation of remote lock files by setting the
+variable @code{remote-file-name-inhibit-locks} to @code{t}.
+
 @node File Shadowing
 @subsection Shadowing Files
 @cindex shadow files
index b1b70a9f0633d2c2da629d733f0c2b9727bdf96c..1f4049f715cdee05e85f7a54962da6dc4df2ebd5 100644 (file)
@@ -821,6 +821,11 @@ If you wish, you can replace the @code{ask-user-about-lock} function
 with your own version that makes the decision in another way.
 @end defun
 
+@defopt remote-file-name-inhibit-locks
+You can prevent the creation of remote lock files by setting the
+variable @code{remote-file-name-inhibit-locks} to @code{t}.
+@end defopt
+
 @node Information about Files
 @section Information about Files
 @cindex file, information about
index 8ba5f0118a3389d9c33547ab3f9afea2452e226e..088352e8a8a85c68901d9c72c75966ace930d43a 100644 (file)
@@ -2858,11 +2858,15 @@ to warn you, if a file is changed in parallel from different Emacs
 sessions, or via different remote connections.  Be careful with such
 settings.
 
+@vindex remote-file-name-inhibit-locks
+Setting @code{remote-file-name-inhibit-locks} to non-@code{nil}
+prevents the creation of remote lock files at all.
+
 @vindex tramp-allow-unsafe-temporary-files
 Per default, @value{tramp} asks for confirmation if a
-@samp{root}-owned backup or auto-save remote file has to be written to
-your local temporary directory.  If you want to suppress this
-confirmation question, set user option
+@samp{root}-owned remote backup, auto-save or lock file has to be
+written to your local temporary directory.  If you want to suppress
+this confirmation question, set user option
 @code{tramp-allow-unsafe-temporary-files} to @code{t}.
 
 
index 923cfcc47228918c72fd38c049cf1caad13c84b4..fd661a1e7a62a61f4e0222858acd398e2a2ad216 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1464,12 +1464,15 @@ buffer to a file under the "/tmp/" directory.  This is useful, if (in
 rare cases) Tramp blocks Emacs, and we need further debug information.
 
 +++
-*** Writing sensitive auto-save or backup files to the local temporary
-directory must be confirmed.  In order to suppress this confirmation,
-set user option 'tramp-allow-unsafe-temporary-files' to t.
+*** Tramp supports lock files now.
+In order to deactivate this, set user option
+'remote-file-name-inhibit-locks' to t.
 
 +++
-*** Tramp supports file locks now.
+*** Writing sensitive auto-save, backup or lock files to the local
+temporary directory must be confirmed.  In order to suppress this
+confirmation, set user option 'tramp-allow-unsafe-temporary-files' to
+t.
 
 ** Tempo
 
@@ -2182,6 +2185,10 @@ summaries will include the failing condition.
 This option allows controlling where lock files are written.  It uses
 the same syntax as 'auto-save-file-name-transforms'.
 
++++
+*** New user option 'remote-file-name-inhibit-locks'.
+When non-nil, this option suppresses lock files for remote files.
+
 +++
 *** New user option 'kill-transform-function'.
 This can be used to transform (and suppress) strings from entering the
index 0dfcab8f89b831f659d7af184ee26c0448cb78b6..ad02d373fd05782d497d05b1bde1e7e553f0360a 100644 (file)
@@ -427,6 +427,12 @@ file it's locking, and it has the same name, but with \".#\" prepended."
   :initialize 'custom-initialize-delay
   :version "28.1")
 
+(defcustom remote-file-name-inhibit-locks nil
+  "Whether to use file locks for remote files."
+  :group 'files
+  :version "28.1"
+  :type 'boolean)
+
 (defvar auto-save--timer nil "Timer for `auto-save-visited-mode'.")
 
 (defcustom auto-save-visited-interval 5
index dbbbfe6a3f9f64be1da62479f2b9edc782eceebc..8138d9a3608839d395a775cfb3c384811676f165 100644 (file)
@@ -164,7 +164,7 @@ It is used for TCP/IP devices."
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-adb-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . tramp-adb-handle-make-process)
     (make-symbolic-link . tramp-handle-make-symbolic-link)
index 1b77fea7e185d55f2faef2352d0b38a113469a7e..109db3b1d7b26a05f0db127eda4f819f858472f8 100644 (file)
@@ -213,7 +213,7 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-crypt-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . ignore)
     (make-symbolic-link . tramp-handle-make-symbolic-link)
index 04de5defb37f8c071abf94720c6ec7f01e073545..022fdeeb885dc2399e17f50efbd77915aad5e01e 100644 (file)
@@ -805,7 +805,7 @@ It has been changed in GVFS 1.14.")
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-gvfs-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . ignore)
     (make-symbolic-link . tramp-handle-make-symbolic-link)
index 473fa8a8f0ea20d0f19cc4280a896a643d467a30..49e366c01c6b496169112ba2213cada1b10fd013 100644 (file)
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-fuse-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . ignore)
     (make-symbolic-link . tramp-handle-make-symbolic-link)
index 3595bd26557600ffec0cf6a57c851e51750f5988..760320d7ed4307f0c89c8c3bd6f56ced73738019 100644 (file)
@@ -993,7 +993,7 @@ Format specifiers \"%s\" are replaced before the script is used.")
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-sh-handle-make-directory)
     ;; `make-directory-internal' performed by default handler.
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . tramp-sh-handle-make-process)
     (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
index 1c7ddee0086cfa4f9db40db591b462ad75dcb5ca..4008c25d3af14a6258dfe1ac66bae364ccb52ca4 100644 (file)
@@ -278,7 +278,7 @@ See `tramp-actions-before-shell' for more info.")
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-smb-handle-make-directory)
     (make-directory-internal . tramp-smb-handle-make-directory-internal)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . ignore)
     (make-symbolic-link . tramp-smb-handle-make-symbolic-link)
index 5f6807a0db711909ea40904cc99ec4375b1bcdec..99f4063988fbc774a9610bdae4ac6a04829faaf4 100644 (file)
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-fuse-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . tramp-handle-make-process)
     (make-symbolic-link . tramp-handle-make-symbolic-link)
index d68a5c1adf424d2d2686c6c00f97e0cb7c5ef461..45d9fab986c71ebfd3c3ce32bed78f1daf31faa8 100644 (file)
@@ -120,7 +120,7 @@ See `tramp-actions-before-shell' for more info.")
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-sudoedit-handle-make-directory)
     (make-directory-internal . ignore)
-    ;; `make-lock-file-name' performed by default handler.
+    (make-lock-file-name . tramp-handle-make-lock-file-name)
     (make-nearby-temp-file . tramp-handle-make-nearby-temp-file)
     (make-process . ignore)
     (make-symbolic-link . tramp-sudoedit-handle-make-symbolic-link)
index 9e6bfceb49a7919a9cc8093ab27acc4fcba861b4..3f586c621701e33d719b6edee373057e6d537f85 100644 (file)
@@ -3630,7 +3630,7 @@ User is always nil."
             (file-writable-p (file-name-directory filename)))))))
 
 (defcustom tramp-allow-unsafe-temporary-files nil
-  "Whether root-owned auto-save or backup files can be written to \"/tmp\"."
+  "Whether root-owned auto-save, backup or lock files can be written to \"/tmp\"."
   :version "28.1"
   :type 'boolean)
 
@@ -3880,6 +3880,30 @@ Return nil when there is no lockfile."
              (write-region info nil lockname)
              (set-file-modes lockname #o0644))))))))
 
+(defun tramp-handle-make-lock-file-name (file)
+  "Like `make-lock-file-name' for Tramp files."
+  (when (and create-lockfiles
+            ;; This variable has been introduced with Emacs 28.1.
+            (not (bound-and-true-p remote-file-name-inhibit-locks)))
+    (with-parsed-tramp-file-name file nil
+      (let ((result
+            ;; Run plain `make-lock-file-name'.
+            (tramp-run-real-handler #'make-lock-file-name (list file))))
+       ;; Protect against security hole.
+       (when (and (not tramp-allow-unsafe-temporary-files)
+                  (file-in-directory-p result temporary-file-directory)
+                  (zerop (or (tramp-compat-file-attribute-user-id
+                              (file-attributes file 'integer))
+                             tramp-unknown-id-integer))
+                  (not (with-tramp-connection-property
+                           (tramp-get-process v) "unsafe-temporary-file"
+                         (yes-or-no-p
+                          (concat
+                           "Lock file on local temporary directory, "
+                           "do you want to continue? ")))))
+         (tramp-error v 'file-error "Unsafe lock file name"))
+       result))))
+
 (defun tramp-handle-unlock-file (file)
   "Like `unlock-file' for Tramp files."
   (when-let ((lockname (tramp-compat-make-lock-file-name file)))
index 44fd1b45b261e7afc16e4aefdb4b728779f491bb..bc05db8095b11b7fef1b0437cf3ba1cf3a88a921 100644 (file)
@@ -5751,8 +5751,10 @@ Use direct async.")
   (skip-unless (and (fboundp 'lock-file) (fboundp 'unlock-file)))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
-    (let ((tmp-name (tramp--test-make-temp-name nil quoted))
+    (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
+         (tmp-name2 (tramp--test-make-temp-name nil quoted))
          (remote-file-name-inhibit-cache t)
+         (remote-file-name-inhibit-locks nil)
          (create-lockfiles t)
           (inhibit-message t)
          ;; tramp-rclone.el and tramp-sshfs.el cache the mounted files.
@@ -5765,51 +5767,73 @@ Use direct async.")
       (unwind-protect
          (progn
            ;; A simple file lock.
-           (should-not (file-locked-p tmp-name))
-           (lock-file tmp-name)
-           (should (eq (file-locked-p tmp-name) t))
+           (should-not (file-locked-p tmp-name1))
+           (lock-file tmp-name1)
+           (should (eq (file-locked-p tmp-name1) t))
 
            ;; If it is locked already, nothing changes.
-           (lock-file tmp-name)
-           (should (eq (file-locked-p tmp-name) t))
+           (lock-file tmp-name1)
+           (should (eq (file-locked-p tmp-name1) t))
 
            ;; A new connection changes process id, and also the
            ;; lockname contents.
            (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
-           (should (stringp (file-locked-p tmp-name)))
+           (should (stringp (file-locked-p tmp-name1)))
+
+           ;; When `remote-file-name-inhibit-locks' is set, nothing happens.
+           (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
+           (let ((remote-file-name-inhibit-locks t))
+             (lock-file tmp-name1)
+             (should-not (file-locked-p tmp-name1)))
+
+           ;; When `lock-file-name-transforms' is set, another lock
+           ;; file is used.
+           (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
+           (let ((lock-file-name-transforms `((".*" ,tmp-name2))))
+             (should
+              (string-equal
+               (make-lock-file-name tmp-name1)
+               (make-lock-file-name tmp-name2)))
+             (lock-file tmp-name1)
+             (should (eq (file-locked-p tmp-name1) t))
+             (unlock-file tmp-name1)
+             (should-not (file-locked-p tmp-name1)))
 
            ;; Steal the file lock.
            (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
            (cl-letf (((symbol-function #'read-char) (lambda (&rest _args) ?s)))
-             (lock-file tmp-name))
-           (should (eq (file-locked-p tmp-name) t))
+             (lock-file tmp-name1))
+           (should (eq (file-locked-p tmp-name1) t))
 
            ;; Ignore the file lock.
            (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
            (cl-letf (((symbol-function #'read-char) (lambda (&rest _args) ?p)))
-             (lock-file tmp-name))
-           (should (stringp (file-locked-p tmp-name)))
+             (lock-file tmp-name1))
+           (should (stringp (file-locked-p tmp-name1)))
 
            ;; Quit the file lock machinery.
            (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
            (cl-letf (((symbol-function #'read-char) (lambda (&rest _args) ?q)))
-             (should-error (lock-file tmp-name) :type 'file-locked)
+             (should-error (lock-file tmp-name1) :type 'file-locked)
              ;; The same for `write-region'.
-             (should-error (write-region "foo" nil tmp-name) :type 'file-locked)
              (should-error
-              (write-region "foo" nil tmp-name nil nil tmp-name)
+              (write-region "foo" nil tmp-name1) :type 'file-locked)
+             (should-error
+              (write-region "foo" nil tmp-name1 nil nil tmp-name1)
                :type 'file-locked)
              ;; The same for `set-visited-file-name'.
               (with-temp-buffer
                (should-error
-                 (set-visited-file-name tmp-name) :type 'file-locked)))
-           (should (stringp (file-locked-p tmp-name)))
-           (should-not (file-exists-p tmp-name)))
+                 (set-visited-file-name tmp-name1) :type 'file-locked)))
+           (should (stringp (file-locked-p tmp-name1)))
+           (should-not (file-exists-p tmp-name1)))
 
        ;; Cleanup.
-       (ignore-errors (delete-file tmp-name))
-       (unlock-file tmp-name)
-       (should-not (file-locked-p tmp-name))))))
+       (ignore-errors (delete-file tmp-name1))
+       (unlock-file tmp-name1)
+       (unlock-file tmp-name2)
+       (should-not (file-locked-p tmp-name1))
+       (should-not (file-locked-p tmp-name2))))))
 
 ;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test40-make-nearby-temp-file ()