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
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
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}.
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
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
: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
(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)
(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)
(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)
(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)
(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)
(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)
(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)
(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)
(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)
(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)))
(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.
(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 ()