diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 5feee108331..d4f2de982d6 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2972,8 +2972,8 @@ invoking @kbd{M-x desktop-read} next. The @code{desktop-clear} command kills all buffers except for internal ones, and clears the global variables listed in @code{desktop-globals-to-clear}. If you want it to preserve certain buffers, customize the variable -@code{desktop-clear-preserve-buffers-regexp}, whose value is a regular -expression matching the names of buffers not to kill. +@code{desktop-clear-preserve-buffers}, whose value is a list of regular +expressions matching the names of buffers not to kill. @vindex desktop-globals-to-save If you want to save minibuffer history from one session to diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 857584b9933..182efff7afb 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -654,7 +654,13 @@ maintainer, you can use the command @code{package-report-bug} to report a bug via Email. This report will include all the user options that you have customized. If you have made a change you wish to share with the maintainers, first commit your changes then use the command -@code{package-vc-prepare-patch} to share it. @xref{Preparing Patches}. +@code{package-vc-prepare-patch} to share it. +@iftex +@xref{Preparing Patches,,,emacs-xtra, Specialized Emacs Features}. +@end iftex +@ifnottex +@xref{Preparing Patches}. +@end ifnottex @findex package-vc-install-from-checkout @findex package-vc-rebuild diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index 45bc6d77728..5c448e741f2 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi @@ -312,7 +312,14 @@ If you expect to contribute patches on a regular basis, you can set the user option @code{vc-default-patch-addressee} to the address(es) you wish to use. This will be used as the default value when invoking @code{vc-prepare-patch}. Project maintainers may consider setting -this as a directory local variable (@pxref{Directory Variables}). +this as a directory local variable +@iftex +(@pxref{Directory Variables,,Per-Directory Local Variables, +emacs, the Emacs Manual}). +@end iftex +@ifnottex +(@pxref{Directory Variables}). +@end ifnottex @node Customizing VC @subsection Customizing VC diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index a22e514f055..c3af74ea1df 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -6769,6 +6769,15 @@ the following settings are required: @end group @end lisp +@vindex warning-suppress-types +@value{tramp} warnings are displayed in the @file{*Warnings*} buffer, +which pops up. If you don't want to see this buffer for every +@value{tramp} warning, set @code{warning-suppress-types}: + +@lisp +(setq warning-suppress-types '((tramp))) +@end lisp + If @code{tramp-verbose} is greater than or equal to 10, Lisp backtraces are also added to the @value{tramp} debug buffer in case of errors. diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index fb54abfa0c6..44808a80dc3 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -484,11 +484,11 @@ Emacs dired can't find files." (with-tramp-file-property v localname "file-executable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (or (tramp-check-cached-permissions v ?x) - (tramp-check-cached-permissions v ?s)) - (tramp-adb-send-command-and-check - v (format "test -x %s" (tramp-shell-quote-argument localname))))))) + (or (tramp-check-cached-permissions v ?x) + (tramp-check-cached-permissions v ?s) + (tramp-check-cached-permissions v ?t) + (tramp-adb-send-command-and-check + v (format "test -x %s" (tramp-shell-quote-argument localname))))))) (defun tramp-adb-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." @@ -502,10 +502,9 @@ Emacs dired can't find files." (with-tramp-file-property v localname "file-readable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (tramp-handle-file-readable-p filename) - (tramp-adb-send-command-and-check - v (format "test -r %s" (tramp-shell-quote-argument localname))))))) + (or (tramp-handle-file-readable-p filename) + (tramp-adb-send-command-and-check + v (format "test -r %s" (tramp-shell-quote-argument localname))))))) (defun tramp-adb-handle-file-writable-p (filename) "Like `file-writable-p' for Tramp files." diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 4ff7d649b42..cbdaa48fc0e 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -590,12 +590,11 @@ PROPERTIES is a list of file properties (strings)." print-length print-level) ;; Remove `tramp-null-hop'. (remhash tramp-null-hop cache) - ;; Remove temporary data. If there is the key "login-as", we - ;; don't save either, because all other properties might - ;; depend on the login name, and we want to give the - ;; possibility to use another login name later on. Key - ;; "started" exists for the "ftp" method only, which must not - ;; be kept persistent. + ;; If there is the key "login-as", we don't save, because all + ;; other properties might depend on the login name, and we + ;; want to give the possibility to use another login name + ;; later on. Key "started" exists for the "ftp" method only, + ;; which must not be kept persistent. (maphash (lambda (key value) (if (and (tramp-file-name-p key) (hash-table-p value) diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 8b18b9b14e6..9787e3a6553 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -38,30 +38,34 @@ (require 'xdg) (declare-function tramp-error "tramp-message") +(declare-function tramp-warning "tramp-message") (declare-function tramp-tramp-file-p "tramp") (defvar tramp-temp-name-prefix) (defconst tramp-compat-emacs-compiled-version (eval-when-compile emacs-version) "The Emacs version used for compilation.") -(unless (= emacs-major-version - (car (version-to-list tramp-compat-emacs-compiled-version))) - (lwarn 'tramp :warning - "Tramp has been compiled with Emacs %s, this is Emacs %s" - tramp-compat-emacs-compiled-version emacs-version)) +(with-eval-after-load 'tramp + (unless (= emacs-major-version + (car (version-to-list tramp-compat-emacs-compiled-version))) + (tramp-warning nil + "Tramp has been compiled with Emacs %s, this is Emacs %s" + tramp-compat-emacs-compiled-version emacs-version)) -(with-eval-after-load 'docker-tramp - (lwarn 'tramp :warning - (concat "Package `docker-tramp' has been obsoleted, " - "please use integrated package `tramp-container'"))) -(with-eval-after-load 'kubernetes-tramp - (lwarn 'tramp :warning - (concat "Package `kubernetes-tramp' has been obsoleted, " - "please use integrated package `tramp-container'"))) -(with-eval-after-load 'tramp-nspawn - (lwarn 'tramp :warning - (concat "Package `tramp-nspawn' has been obsoleted, " - "please use integrated package `tramp-container'"))) + (with-eval-after-load 'docker-tramp + (tramp-warning nil + (concat "Package `docker-tramp' has been obsoleted, " + "please use integrated package `tramp-container'"))) + + (with-eval-after-load 'kubernetes-tramp + (tramp-warning nil + (concat "Package `kubernetes-tramp' has been obsoleted, " + "please use integrated package `tramp-container'"))) + + (with-eval-after-load 'tramp-nspawn + (tramp-warning nil + (concat "Package `tramp-nspawn' has been obsoleted, " + "please use integrated package `tramp-container'")))) ;; For not existing functions, obsolete functions, or functions with a ;; changed argument list, there are compiler warnings. We want to diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index d1f806bf7c6..65a1595c29e 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -1469,8 +1469,9 @@ If FILE-SYSTEM is non-nil, return file system attributes." "Like `file-executable-p' for Tramp files." (with-parsed-tramp-file-name (expand-file-name filename) nil (with-tramp-file-property v localname "file-executable-p" - (or (tramp-check-cached-permissions v ?x) - (tramp-check-cached-permissions v ?s))))) + (or (tramp-check-cached-permissions v ?x 'force) + (tramp-check-cached-permissions v ?s 'force) + (tramp-check-cached-permissions v ?t 'force))))) (defun tramp-gvfs-handle-file-name-all-completions (filename directory) "Like `file-name-all-completions' for Tramp files." diff --git a/lisp/net/tramp-message.el b/lisp/net/tramp-message.el index 20bf720c41b..d87c62a4b50 100644 --- a/lisp/net/tramp-message.el +++ b/lisp/net/tramp-message.el @@ -464,7 +464,7 @@ the resulting error message." "Show a warning. VEC-OR-PROC identifies the connection to use, remaining arguments passed to `tramp-message'." - (declare (tramp-suppress-trace t)) + (declare (indent 1) (tramp-suppress-trace t)) (let (signal-hook-function) (apply 'tramp-message vec-or-proc 2 fmt-string arguments) (apply 'lwarn 'tramp :warning fmt-string arguments))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 5e79d4be41e..047d93a51b8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1787,10 +1787,10 @@ ID-FORMAT valid values are `string' and `integer'." (with-tramp-file-property v localname "file-executable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (or (tramp-check-cached-permissions v ?x) - (tramp-check-cached-permissions v ?s)) - (tramp-run-test v "-x" localname))))) + (or (tramp-check-cached-permissions v ?x) + (tramp-check-cached-permissions v ?s) + (tramp-check-cached-permissions v ?t) + (tramp-run-test v "-x" localname))))) (defun tramp-sh-handle-file-readable-p (filename) "Like `file-readable-p' for Tramp files." @@ -1798,9 +1798,8 @@ ID-FORMAT valid values are `string' and `integer'." (with-tramp-file-property v localname "file-readable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (tramp-handle-file-readable-p filename) - (tramp-run-test v "-r" localname))))) + (or (tramp-handle-file-readable-p filename) + (tramp-run-test v "-r" localname))))) ;; Functions implemented using the basic functions above. @@ -1830,13 +1829,11 @@ ID-FORMAT valid values are `string' and `integer'." (if (file-exists-p filename) ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (tramp-check-cached-permissions v ?w) - (tramp-run-test v "-w" localname)) + (or (tramp-check-cached-permissions v ?w) + (tramp-run-test v "-w" localname)) ;; If file doesn't exist, check if directory is writable. - (and - (file-directory-p (file-name-directory filename)) - (file-writable-p (file-name-directory filename))))))) + (and (file-directory-p (file-name-directory filename)) + (file-writable-p (file-name-directory filename))))))) (defun tramp-sh-handle-file-ownership-preserved-p (filename &optional group) "Like `file-ownership-preserved-p' for Tramp files." diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 517bd85736a..4cf1ef8c226 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -479,11 +479,11 @@ the result will be a local, non-Tramp, file name." (with-tramp-file-property v localname "file-executable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (or (tramp-check-cached-permissions v ?x) - (tramp-check-cached-permissions v ?s)) - (tramp-sudoedit-send-command - v "test" "-x" (file-name-unquote localname)))))) + (or (tramp-check-cached-permissions v ?x) + (tramp-check-cached-permissions v ?s) + (tramp-check-cached-permissions v ?t) + (tramp-sudoedit-send-command + v "test" "-x" (file-name-unquote localname)))))) (defun tramp-sudoedit-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." @@ -519,10 +519,9 @@ the result will be a local, non-Tramp, file name." (with-tramp-file-property v localname "file-readable-p" ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (tramp-handle-file-readable-p filename) - (tramp-sudoedit-send-command - v "test" "-r" (file-name-unquote localname)))))) + (or (tramp-handle-file-readable-p filename) + (tramp-sudoedit-send-command + v "test" "-r" (file-name-unquote localname)))))) (defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag) "Like `set-file-modes' for Tramp files." @@ -604,10 +603,9 @@ the result will be a local, non-Tramp, file name." (if (file-exists-p filename) ;; Examine `file-attributes' cache to see if request can be ;; satisfied without remote operation. - (if (tramp-use-file-attributes v) - (tramp-check-cached-permissions v ?w) - (tramp-sudoedit-send-command - v "test" "-w" (file-name-unquote localname))) + (or (tramp-check-cached-permissions v ?w) + (tramp-sudoedit-send-command + v "test" "-w" (file-name-unquote localname))) ;; If file doesn't exist, check if directory is writable. (and (file-directory-p (file-name-directory filename)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 91ba71510e1..c3e9b252d24 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3545,7 +3545,7 @@ BODY is the backend specific code." nil))) (defcustom tramp-use-file-attributes t - "Whether to use \"file-attributes\" file property for check. + "Whether to use \"file-attributes\" connection property for check. This is relevant for read, write, and execute permissions. On some file systems using NFS4_ACL, the permission string as returned from `stat' or `ls', is not sufficient to provide more fine-grained information. @@ -4368,13 +4368,12 @@ Let-bind it when necessary.") "Like `file-readable-p' for Tramp files." (with-parsed-tramp-file-name (expand-file-name filename) nil (with-tramp-file-property v localname "file-readable-p" - (or (tramp-check-cached-permissions v ?r) + (or (tramp-check-cached-permissions v ?r 'force) ;; `tramp-check-cached-permissions' doesn't handle symbolic ;; links. (and-let* ((symlink (file-symlink-p filename)) ((stringp symlink)) - ((file-readable-p - (concat (file-remote-p filename) symlink))))))))) + ((file-readable-p (file-truename filename))))))))) (defun tramp-handle-file-regular-p (filename) "Like `file-regular-p' for Tramp files." @@ -4468,7 +4467,12 @@ existing) are returned." (with-parsed-tramp-file-name (expand-file-name filename) nil (with-tramp-file-property v localname "file-writable-p" (if (file-exists-p filename) - (tramp-check-cached-permissions v ?w) + (or (tramp-check-cached-permissions v ?w 'force) + ;; `tramp-check-cached-permissions' doesn't handle + ;; symbolic links. + (and-let* ((symlink (file-symlink-p filename)) + ((stringp symlink)) + ((file-writable-p (file-truename filename)))))) ;; If file doesn't exist, check if directory is writable. (and (file-directory-p (file-name-directory filename)) (file-writable-p (file-name-directory filename))))))) @@ -6472,22 +6476,23 @@ VEC is used for tracing." (when vec (tramp-message vec 7 "locale %s" (or locale "C"))) (or locale "C")))) -(defun tramp-check-cached-permissions (vec access) +(defun tramp-check-cached-permissions (vec access &optional force) "Check `file-attributes' caches for VEC. -Return t if according to the cache access type ACCESS is known to -be granted." +Return t if according to the cache access type ACCESS is known to be +granted, if `tramp-use-file-attributes' mandates this. If FORCE is +non-nil, use connection property \"file-attributes\" mandatory." (when-let* ((offset (cond ((eq ?r access) 1) ((eq ?w access) 2) ((eq ?x access) 3) - ((eq ?s access) 3))) + ((eq ?s access) 3) + ((eq ?t access) 3))) + ((or force (tramp-use-file-attributes vec))) (file-attr (file-attributes (tramp-make-tramp-file-name vec))) + ;; Not a symlink. + ((not (stringp (file-attribute-type file-attr)))) (remote-uid (tramp-get-remote-uid vec 'integer)) (remote-gid (tramp-get-remote-gid vec 'integer))) - (or - ;; Not a symlink. - (eq t (file-attribute-type file-attr)) - (null (file-attribute-type file-attr))) (or ;; World accessible. (eq access (aref (file-attribute-modes file-attr) (+ offset 6))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 5c5b8c0b157..c13119fb920 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4255,6 +4255,8 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ignore-errors (delete-file tmp-name1)) (ignore-errors (delete-file tmp-name2))))))) +(tramp--test-deftest-without-file-attributes tramp-test20-file-modes) + ;; Method "smb" could run into "NT_STATUS_REVISION_MISMATCH" error. (defmacro tramp--test-ignore-add-name-to-file-error (&rest body) "Run BODY, ignoring \"error with add-name-to-file\" file error." @@ -4554,6 +4556,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (should (string-equal (file-truename dir1) (expand-file-name dir1))) (should (string-equal (file-truename dir2) (expand-file-name dir2))))))) +(tramp--test-deftest-without-file-attributes tramp-test21-file-links) + (ert-deftest tramp-test22-file-times () "Check `set-file-times' and `file-newer-than-file-p'." (skip-unless (tramp--test-enabled))