aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2025-04-05 07:07:29 -0400
committerEli Zaretskii2025-04-05 07:07:29 -0400
commit2054060d56573e9dadc53b69a5aa4063e4cebae6 (patch)
treecd01e02394207215c4004b6170bc744a4755febd
parentd403be4811a3d541785f58a5ed75a9ccda3fb781 (diff)
parentae7f65f3f9cbe03608c9920e7f2f82a5a82e62d6 (diff)
downloademacs-2054060d56573e9dadc53b69a5aa4063e4cebae6.tar.gz
emacs-2054060d56573e9dadc53b69a5aa4063e4cebae6.zip
Merge from origin/emacs-30
ae7f65f3f9c Fix obsolete documentation of desktop library fd5f817882a Improve Tramp's initial warnings 1e865a2f288 Explain, how to suppress Tramp warnings a0962074743 printed manuals: xrefs in and out of "Preparing Patches" 3f9ac99fc7e Fix Tramp's file-attributes cache
-rw-r--r--doc/emacs/misc.texi4
-rw-r--r--doc/emacs/package.texi8
-rw-r--r--doc/emacs/vc1-xtra.texi9
-rw-r--r--doc/misc/tramp.texi9
-rw-r--r--lisp/net/tramp-adb.el17
-rw-r--r--lisp/net/tramp-cache.el11
-rw-r--r--lisp/net/tramp-compat.el40
-rw-r--r--lisp/net/tramp-gvfs.el5
-rw-r--r--lisp/net/tramp-message.el2
-rw-r--r--lisp/net/tramp-sh.el23
-rw-r--r--lisp/net/tramp-sudoedit.el24
-rw-r--r--lisp/net/tramp.el31
-rw-r--r--test/lisp/net/tramp-tests.el4
13 files changed, 108 insertions, 79 deletions
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}
2972command kills all buffers except for internal ones, and clears the 2972command kills all buffers except for internal ones, and clears the
2973global variables listed in @code{desktop-globals-to-clear}. If you 2973global variables listed in @code{desktop-globals-to-clear}. If you
2974want it to preserve certain buffers, customize the variable 2974want it to preserve certain buffers, customize the variable
2975@code{desktop-clear-preserve-buffers-regexp}, whose value is a regular 2975@code{desktop-clear-preserve-buffers}, whose value is a list of regular
2976expression matching the names of buffers not to kill. 2976expressions matching the names of buffers not to kill.
2977 2977
2978@vindex desktop-globals-to-save 2978@vindex desktop-globals-to-save
2979 If you want to save minibuffer history from one session to 2979 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
654report a bug via Email. This report will include all the user options 654report a bug via Email. This report will include all the user options
655that you have customized. If you have made a change you wish to share 655that you have customized. If you have made a change you wish to share
656with the maintainers, first commit your changes then use the command 656with the maintainers, first commit your changes then use the command
657@code{package-vc-prepare-patch} to share it. @xref{Preparing Patches}. 657@code{package-vc-prepare-patch} to share it.
658@iftex
659@xref{Preparing Patches,,,emacs-xtra, Specialized Emacs Features}.
660@end iftex
661@ifnottex
662@xref{Preparing Patches}.
663@end ifnottex
658 664
659@findex package-vc-install-from-checkout 665@findex package-vc-install-from-checkout
660@findex package-vc-rebuild 666@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
312the user option @code{vc-default-patch-addressee} to the address(es) 312the user option @code{vc-default-patch-addressee} to the address(es)
313you wish to use. This will be used as the default value when invoking 313you wish to use. This will be used as the default value when invoking
314@code{vc-prepare-patch}. Project maintainers may consider setting 314@code{vc-prepare-patch}. Project maintainers may consider setting
315this as a directory local variable (@pxref{Directory Variables}). 315this as a directory local variable
316@iftex
317(@pxref{Directory Variables,,Per-Directory Local Variables,
318emacs, the Emacs Manual}).
319@end iftex
320@ifnottex
321(@pxref{Directory Variables}).
322@end ifnottex
316 323
317@node Customizing VC 324@node Customizing VC
318@subsection Customizing VC 325@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:
6769@end group 6769@end group
6770@end lisp 6770@end lisp
6771 6771
6772@vindex warning-suppress-types
6773@value{tramp} warnings are displayed in the @file{*Warnings*} buffer,
6774which pops up. If you don't want to see this buffer for every
6775@value{tramp} warning, set @code{warning-suppress-types}:
6776
6777@lisp
6778(setq warning-suppress-types '((tramp)))
6779@end lisp
6780
6772If @code{tramp-verbose} is greater than or equal to 10, Lisp 6781If @code{tramp-verbose} is greater than or equal to 10, Lisp
6773backtraces are also added to the @value{tramp} debug buffer in case of 6782backtraces are also added to the @value{tramp} debug buffer in case of
6774errors. 6783errors.
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."
484 (with-tramp-file-property v localname "file-executable-p" 484 (with-tramp-file-property v localname "file-executable-p"
485 ;; Examine `file-attributes' cache to see if request can be 485 ;; Examine `file-attributes' cache to see if request can be
486 ;; satisfied without remote operation. 486 ;; satisfied without remote operation.
487 (if (tramp-use-file-attributes v) 487 (or (tramp-check-cached-permissions v ?x)
488 (or (tramp-check-cached-permissions v ?x) 488 (tramp-check-cached-permissions v ?s)
489 (tramp-check-cached-permissions v ?s)) 489 (tramp-check-cached-permissions v ?t)
490 (tramp-adb-send-command-and-check 490 (tramp-adb-send-command-and-check
491 v (format "test -x %s" (tramp-shell-quote-argument localname))))))) 491 v (format "test -x %s" (tramp-shell-quote-argument localname)))))))
492 492
493(defun tramp-adb-handle-file-exists-p (filename) 493(defun tramp-adb-handle-file-exists-p (filename)
494 "Like `file-exists-p' for Tramp files." 494 "Like `file-exists-p' for Tramp files."
@@ -502,10 +502,9 @@ Emacs dired can't find files."
502 (with-tramp-file-property v localname "file-readable-p" 502 (with-tramp-file-property v localname "file-readable-p"
503 ;; Examine `file-attributes' cache to see if request can be 503 ;; Examine `file-attributes' cache to see if request can be
504 ;; satisfied without remote operation. 504 ;; satisfied without remote operation.
505 (if (tramp-use-file-attributes v) 505 (or (tramp-handle-file-readable-p filename)
506 (tramp-handle-file-readable-p filename) 506 (tramp-adb-send-command-and-check
507 (tramp-adb-send-command-and-check 507 v (format "test -r %s" (tramp-shell-quote-argument localname)))))))
508 v (format "test -r %s" (tramp-shell-quote-argument localname)))))))
509 508
510(defun tramp-adb-handle-file-writable-p (filename) 509(defun tramp-adb-handle-file-writable-p (filename)
511 "Like `file-writable-p' for Tramp files." 510 "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)."
590 print-length print-level) 590 print-length print-level)
591 ;; Remove `tramp-null-hop'. 591 ;; Remove `tramp-null-hop'.
592 (remhash tramp-null-hop cache) 592 (remhash tramp-null-hop cache)
593 ;; Remove temporary data. If there is the key "login-as", we 593 ;; If there is the key "login-as", we don't save, because all
594 ;; don't save either, because all other properties might 594 ;; other properties might depend on the login name, and we
595 ;; depend on the login name, and we want to give the 595 ;; want to give the possibility to use another login name
596 ;; possibility to use another login name later on. Key 596 ;; later on. Key "started" exists for the "ftp" method only,
597 ;; "started" exists for the "ftp" method only, which must not 597 ;; which must not be kept persistent.
598 ;; be kept persistent.
599 (maphash 598 (maphash
600 (lambda (key value) 599 (lambda (key value)
601 (if (and (tramp-file-name-p key) (hash-table-p value) 600 (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 @@
38(require 'xdg) 38(require 'xdg)
39 39
40(declare-function tramp-error "tramp-message") 40(declare-function tramp-error "tramp-message")
41(declare-function tramp-warning "tramp-message")
41(declare-function tramp-tramp-file-p "tramp") 42(declare-function tramp-tramp-file-p "tramp")
42(defvar tramp-temp-name-prefix) 43(defvar tramp-temp-name-prefix)
43 44
44(defconst tramp-compat-emacs-compiled-version (eval-when-compile emacs-version) 45(defconst tramp-compat-emacs-compiled-version (eval-when-compile emacs-version)
45 "The Emacs version used for compilation.") 46 "The Emacs version used for compilation.")
46 47
47(unless (= emacs-major-version 48(with-eval-after-load 'tramp
48 (car (version-to-list tramp-compat-emacs-compiled-version))) 49 (unless (= emacs-major-version
49 (lwarn 'tramp :warning 50 (car (version-to-list tramp-compat-emacs-compiled-version)))
50 "Tramp has been compiled with Emacs %s, this is Emacs %s" 51 (tramp-warning nil
51 tramp-compat-emacs-compiled-version emacs-version)) 52 "Tramp has been compiled with Emacs %s, this is Emacs %s"
52 53 tramp-compat-emacs-compiled-version emacs-version))
53(with-eval-after-load 'docker-tramp 54
54 (lwarn 'tramp :warning 55 (with-eval-after-load 'docker-tramp
55 (concat "Package `docker-tramp' has been obsoleted, " 56 (tramp-warning nil
56 "please use integrated package `tramp-container'"))) 57 (concat "Package `docker-tramp' has been obsoleted, "
57(with-eval-after-load 'kubernetes-tramp 58 "please use integrated package `tramp-container'")))
58 (lwarn 'tramp :warning 59
59 (concat "Package `kubernetes-tramp' has been obsoleted, " 60 (with-eval-after-load 'kubernetes-tramp
60 "please use integrated package `tramp-container'"))) 61 (tramp-warning nil
61(with-eval-after-load 'tramp-nspawn 62 (concat "Package `kubernetes-tramp' has been obsoleted, "
62 (lwarn 'tramp :warning 63 "please use integrated package `tramp-container'")))
63 (concat "Package `tramp-nspawn' has been obsoleted, " 64
64 "please use integrated package `tramp-container'"))) 65 (with-eval-after-load 'tramp-nspawn
66 (tramp-warning nil
67 (concat "Package `tramp-nspawn' has been obsoleted, "
68 "please use integrated package `tramp-container'"))))
65 69
66;; For not existing functions, obsolete functions, or functions with a 70;; For not existing functions, obsolete functions, or functions with a
67;; changed argument list, there are compiler warnings. We want to 71;; 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."
1469 "Like `file-executable-p' for Tramp files." 1469 "Like `file-executable-p' for Tramp files."
1470 (with-parsed-tramp-file-name (expand-file-name filename) nil 1470 (with-parsed-tramp-file-name (expand-file-name filename) nil
1471 (with-tramp-file-property v localname "file-executable-p" 1471 (with-tramp-file-property v localname "file-executable-p"
1472 (or (tramp-check-cached-permissions v ?x) 1472 (or (tramp-check-cached-permissions v ?x 'force)
1473 (tramp-check-cached-permissions v ?s))))) 1473 (tramp-check-cached-permissions v ?s 'force)
1474 (tramp-check-cached-permissions v ?t 'force)))))
1474 1475
1475(defun tramp-gvfs-handle-file-name-all-completions (filename directory) 1476(defun tramp-gvfs-handle-file-name-all-completions (filename directory)
1476 "Like `file-name-all-completions' for Tramp files." 1477 "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."
464 "Show a warning. 464 "Show a warning.
465VEC-OR-PROC identifies the connection to use, remaining arguments passed 465VEC-OR-PROC identifies the connection to use, remaining arguments passed
466to `tramp-message'." 466to `tramp-message'."
467 (declare (tramp-suppress-trace t)) 467 (declare (indent 1) (tramp-suppress-trace t))
468 (let (signal-hook-function) 468 (let (signal-hook-function)
469 (apply 'tramp-message vec-or-proc 2 fmt-string arguments) 469 (apply 'tramp-message vec-or-proc 2 fmt-string arguments)
470 (apply 'lwarn 'tramp :warning fmt-string arguments))) 470 (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'."
1787 (with-tramp-file-property v localname "file-executable-p" 1787 (with-tramp-file-property v localname "file-executable-p"
1788 ;; Examine `file-attributes' cache to see if request can be 1788 ;; Examine `file-attributes' cache to see if request can be
1789 ;; satisfied without remote operation. 1789 ;; satisfied without remote operation.
1790 (if (tramp-use-file-attributes v) 1790 (or (tramp-check-cached-permissions v ?x)
1791 (or (tramp-check-cached-permissions v ?x) 1791 (tramp-check-cached-permissions v ?s)
1792 (tramp-check-cached-permissions v ?s)) 1792 (tramp-check-cached-permissions v ?t)
1793 (tramp-run-test v "-x" localname))))) 1793 (tramp-run-test v "-x" localname)))))
1794 1794
1795(defun tramp-sh-handle-file-readable-p (filename) 1795(defun tramp-sh-handle-file-readable-p (filename)
1796 "Like `file-readable-p' for Tramp files." 1796 "Like `file-readable-p' for Tramp files."
@@ -1798,9 +1798,8 @@ ID-FORMAT valid values are `string' and `integer'."
1798 (with-tramp-file-property v localname "file-readable-p" 1798 (with-tramp-file-property v localname "file-readable-p"
1799 ;; Examine `file-attributes' cache to see if request can be 1799 ;; Examine `file-attributes' cache to see if request can be
1800 ;; satisfied without remote operation. 1800 ;; satisfied without remote operation.
1801 (if (tramp-use-file-attributes v) 1801 (or (tramp-handle-file-readable-p filename)
1802 (tramp-handle-file-readable-p filename) 1802 (tramp-run-test v "-r" localname)))))
1803 (tramp-run-test v "-r" localname)))))
1804 1803
1805;; Functions implemented using the basic functions above. 1804;; Functions implemented using the basic functions above.
1806 1805
@@ -1830,13 +1829,11 @@ ID-FORMAT valid values are `string' and `integer'."
1830 (if (file-exists-p filename) 1829 (if (file-exists-p filename)
1831 ;; Examine `file-attributes' cache to see if request can be 1830 ;; Examine `file-attributes' cache to see if request can be
1832 ;; satisfied without remote operation. 1831 ;; satisfied without remote operation.
1833 (if (tramp-use-file-attributes v) 1832 (or (tramp-check-cached-permissions v ?w)
1834 (tramp-check-cached-permissions v ?w) 1833 (tramp-run-test v "-w" localname))
1835 (tramp-run-test v "-w" localname))
1836 ;; If file doesn't exist, check if directory is writable. 1834 ;; If file doesn't exist, check if directory is writable.
1837 (and 1835 (and (file-directory-p (file-name-directory filename))
1838 (file-directory-p (file-name-directory filename)) 1836 (file-writable-p (file-name-directory filename)))))))
1839 (file-writable-p (file-name-directory filename)))))))
1840 1837
1841(defun tramp-sh-handle-file-ownership-preserved-p (filename &optional group) 1838(defun tramp-sh-handle-file-ownership-preserved-p (filename &optional group)
1842 "Like `file-ownership-preserved-p' for Tramp files." 1839 "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."
479 (with-tramp-file-property v localname "file-executable-p" 479 (with-tramp-file-property v localname "file-executable-p"
480 ;; Examine `file-attributes' cache to see if request can be 480 ;; Examine `file-attributes' cache to see if request can be
481 ;; satisfied without remote operation. 481 ;; satisfied without remote operation.
482 (if (tramp-use-file-attributes v) 482 (or (tramp-check-cached-permissions v ?x)
483 (or (tramp-check-cached-permissions v ?x) 483 (tramp-check-cached-permissions v ?s)
484 (tramp-check-cached-permissions v ?s)) 484 (tramp-check-cached-permissions v ?t)
485 (tramp-sudoedit-send-command 485 (tramp-sudoedit-send-command
486 v "test" "-x" (file-name-unquote localname)))))) 486 v "test" "-x" (file-name-unquote localname))))))
487 487
488(defun tramp-sudoedit-handle-file-exists-p (filename) 488(defun tramp-sudoedit-handle-file-exists-p (filename)
489 "Like `file-exists-p' for Tramp files." 489 "Like `file-exists-p' for Tramp files."
@@ -519,10 +519,9 @@ the result will be a local, non-Tramp, file name."
519 (with-tramp-file-property v localname "file-readable-p" 519 (with-tramp-file-property v localname "file-readable-p"
520 ;; Examine `file-attributes' cache to see if request can be 520 ;; Examine `file-attributes' cache to see if request can be
521 ;; satisfied without remote operation. 521 ;; satisfied without remote operation.
522 (if (tramp-use-file-attributes v) 522 (or (tramp-handle-file-readable-p filename)
523 (tramp-handle-file-readable-p filename) 523 (tramp-sudoedit-send-command
524 (tramp-sudoedit-send-command 524 v "test" "-r" (file-name-unquote localname))))))
525 v "test" "-r" (file-name-unquote localname))))))
526 525
527(defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag) 526(defun tramp-sudoedit-handle-set-file-modes (filename mode &optional flag)
528 "Like `set-file-modes' for Tramp files." 527 "Like `set-file-modes' for Tramp files."
@@ -604,10 +603,9 @@ the result will be a local, non-Tramp, file name."
604 (if (file-exists-p filename) 603 (if (file-exists-p filename)
605 ;; Examine `file-attributes' cache to see if request can be 604 ;; Examine `file-attributes' cache to see if request can be
606 ;; satisfied without remote operation. 605 ;; satisfied without remote operation.
607 (if (tramp-use-file-attributes v) 606 (or (tramp-check-cached-permissions v ?w)
608 (tramp-check-cached-permissions v ?w) 607 (tramp-sudoedit-send-command
609 (tramp-sudoedit-send-command 608 v "test" "-w" (file-name-unquote localname)))
610 v "test" "-w" (file-name-unquote localname)))
611 ;; If file doesn't exist, check if directory is writable. 609 ;; If file doesn't exist, check if directory is writable.
612 (and 610 (and
613 (file-directory-p (file-name-directory filename)) 611 (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."
3545 nil))) 3545 nil)))
3546 3546
3547(defcustom tramp-use-file-attributes t 3547(defcustom tramp-use-file-attributes t
3548 "Whether to use \"file-attributes\" file property for check. 3548 "Whether to use \"file-attributes\" connection property for check.
3549This is relevant for read, write, and execute permissions. On some file 3549This is relevant for read, write, and execute permissions. On some file
3550systems using NFS4_ACL, the permission string as returned from `stat' or 3550systems using NFS4_ACL, the permission string as returned from `stat' or
3551`ls', is not sufficient to provide more fine-grained information. 3551`ls', is not sufficient to provide more fine-grained information.
@@ -4368,13 +4368,12 @@ Let-bind it when necessary.")
4368 "Like `file-readable-p' for Tramp files." 4368 "Like `file-readable-p' for Tramp files."
4369 (with-parsed-tramp-file-name (expand-file-name filename) nil 4369 (with-parsed-tramp-file-name (expand-file-name filename) nil
4370 (with-tramp-file-property v localname "file-readable-p" 4370 (with-tramp-file-property v localname "file-readable-p"
4371 (or (tramp-check-cached-permissions v ?r) 4371 (or (tramp-check-cached-permissions v ?r 'force)
4372 ;; `tramp-check-cached-permissions' doesn't handle symbolic 4372 ;; `tramp-check-cached-permissions' doesn't handle symbolic
4373 ;; links. 4373 ;; links.
4374 (and-let* ((symlink (file-symlink-p filename)) 4374 (and-let* ((symlink (file-symlink-p filename))
4375 ((stringp symlink)) 4375 ((stringp symlink))
4376 ((file-readable-p 4376 ((file-readable-p (file-truename filename)))))))))
4377 (concat (file-remote-p filename) symlink)))))))))
4378 4377
4379(defun tramp-handle-file-regular-p (filename) 4378(defun tramp-handle-file-regular-p (filename)
4380 "Like `file-regular-p' for Tramp files." 4379 "Like `file-regular-p' for Tramp files."
@@ -4468,7 +4467,12 @@ existing) are returned."
4468 (with-parsed-tramp-file-name (expand-file-name filename) nil 4467 (with-parsed-tramp-file-name (expand-file-name filename) nil
4469 (with-tramp-file-property v localname "file-writable-p" 4468 (with-tramp-file-property v localname "file-writable-p"
4470 (if (file-exists-p filename) 4469 (if (file-exists-p filename)
4471 (tramp-check-cached-permissions v ?w) 4470 (or (tramp-check-cached-permissions v ?w 'force)
4471 ;; `tramp-check-cached-permissions' doesn't handle
4472 ;; symbolic links.
4473 (and-let* ((symlink (file-symlink-p filename))
4474 ((stringp symlink))
4475 ((file-writable-p (file-truename filename))))))
4472 ;; If file doesn't exist, check if directory is writable. 4476 ;; If file doesn't exist, check if directory is writable.
4473 (and (file-directory-p (file-name-directory filename)) 4477 (and (file-directory-p (file-name-directory filename))
4474 (file-writable-p (file-name-directory filename))))))) 4478 (file-writable-p (file-name-directory filename)))))))
@@ -6472,23 +6476,24 @@ VEC is used for tracing."
6472 (when vec (tramp-message vec 7 "locale %s" (or locale "C"))) 6476 (when vec (tramp-message vec 7 "locale %s" (or locale "C")))
6473 (or locale "C")))) 6477 (or locale "C"))))
6474 6478
6475(defun tramp-check-cached-permissions (vec access) 6479(defun tramp-check-cached-permissions (vec access &optional force)
6476 "Check `file-attributes' caches for VEC. 6480 "Check `file-attributes' caches for VEC.
6477Return t if according to the cache access type ACCESS is known to 6481Return t if according to the cache access type ACCESS is known to be
6478be granted." 6482granted, if `tramp-use-file-attributes' mandates this. If FORCE is
6483non-nil, use connection property \"file-attributes\" mandatory."
6479 (when-let* ((offset (cond 6484 (when-let* ((offset (cond
6480 ((eq ?r access) 1) 6485 ((eq ?r access) 1)
6481 ((eq ?w access) 2) 6486 ((eq ?w access) 2)
6482 ((eq ?x access) 3) 6487 ((eq ?x access) 3)
6483 ((eq ?s access) 3))) 6488 ((eq ?s access) 3)
6489 ((eq ?t access) 3)))
6490 ((or force (tramp-use-file-attributes vec)))
6484 (file-attr (file-attributes (tramp-make-tramp-file-name vec))) 6491 (file-attr (file-attributes (tramp-make-tramp-file-name vec)))
6492 ;; Not a symlink.
6493 ((not (stringp (file-attribute-type file-attr))))
6485 (remote-uid (tramp-get-remote-uid vec 'integer)) 6494 (remote-uid (tramp-get-remote-uid vec 'integer))
6486 (remote-gid (tramp-get-remote-gid vec 'integer))) 6495 (remote-gid (tramp-get-remote-gid vec 'integer)))
6487 (or 6496 (or
6488 ;; Not a symlink.
6489 (eq t (file-attribute-type file-attr))
6490 (null (file-attribute-type file-attr)))
6491 (or
6492 ;; World accessible. 6497 ;; World accessible.
6493 (eq access (aref (file-attribute-modes file-attr) (+ offset 6))) 6498 (eq access (aref (file-attribute-modes file-attr) (+ offset 6)))
6494 ;; User accessible and owned by user. 6499 ;; User accessible and owned by user.
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'."
4255 (ignore-errors (delete-file tmp-name1)) 4255 (ignore-errors (delete-file tmp-name1))
4256 (ignore-errors (delete-file tmp-name2))))))) 4256 (ignore-errors (delete-file tmp-name2)))))))
4257 4257
4258(tramp--test-deftest-without-file-attributes tramp-test20-file-modes)
4259
4258;; Method "smb" could run into "NT_STATUS_REVISION_MISMATCH" error. 4260;; Method "smb" could run into "NT_STATUS_REVISION_MISMATCH" error.
4259(defmacro tramp--test-ignore-add-name-to-file-error (&rest body) 4261(defmacro tramp--test-ignore-add-name-to-file-error (&rest body)
4260 "Run BODY, ignoring \"error with add-name-to-file\" file error." 4262 "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'."
4554 (should (string-equal (file-truename dir1) (expand-file-name dir1))) 4556 (should (string-equal (file-truename dir1) (expand-file-name dir1)))
4555 (should (string-equal (file-truename dir2) (expand-file-name dir2))))))) 4557 (should (string-equal (file-truename dir2) (expand-file-name dir2)))))))
4556 4558
4559(tramp--test-deftest-without-file-attributes tramp-test21-file-links)
4560
4557(ert-deftest tramp-test22-file-times () 4561(ert-deftest tramp-test22-file-times ()
4558 "Check `set-file-times' and `file-newer-than-file-p'." 4562 "Check `set-file-times' and `file-newer-than-file-p'."
4559 (skip-unless (tramp--test-enabled)) 4563 (skip-unless (tramp--test-enabled))