branch: externals/tramp
commit 382d8b1ed71eb3e4684d6db3aa69c3023e71ced5
Author: Michael Albinus <[email protected]>
Commit: Michael Albinus <[email protected]>
Tramp ELPA version 2.8.0.4 released
---
README | 6 +--
test/Makefile | 5 ++-
test/README | 3 ++
test/resources/foo.iso/foo | 1 +
test/resources/foo.tar.gz | Bin 0 -> 274 bytes
test/resources/foo.zip | Bin 0 -> 444 bytes
test/tramp-archive-tests.el | 91 ++++++++++++++++++++++++++++++++++++++------
test/tramp-tests.el | 30 +++++++++++----
texi/tramp.texi | 21 +++++++++-
texi/trampver.texi | 2 +-
tramp-archive.el | 11 +++---
tramp-cache.el | 28 +++++++-------
tramp-cmds.el | 28 +++++++++++---
tramp-compat.el | 3 ++
tramp-gvfs.el | 5 ++-
tramp-message.el | 1 -
tramp-sh.el | 59 +++++++++++++++++++++++-----
tramp.el | 59 ++++++++++++++++------------
trampver.el | 6 +--
19 files changed, 269 insertions(+), 90 deletions(-)
diff --git a/README b/README
index 5720b4415f..ee0e398298 100644
--- a/README
+++ b/README
@@ -32,11 +32,11 @@ Emacs 28 or older
• Remove all byte-compiled Tramp files
- $ rm -f ~/.emacs.d/elpa/tramp-2.8.0.3/tramp*.elc
+ $ rm -f ~/.emacs.d/elpa/tramp-2.8.0.4/tramp*.elc
• Start Emacs with Tramp's source files
- $ emacs -L ~/.emacs.d/elpa/tramp-2.8.0.3 -l tramp
+ $ emacs -L ~/.emacs.d/elpa/tramp-2.8.0.4 -l tramp
This should not give you the error.
@@ -50,7 +50,7 @@ Mitigation of a bug in Emacs 29.1
---------------------------------
Due to a bug in Emacs 29.1, you must apply the following change prior
-installation or upgrading Tramp 2.8.0.3 from GNU ELPA:
+installation or upgrading Tramp 2.8.0.4 from GNU ELPA:
(when (string-equal emacs-version "29.1")
(with-current-buffer
diff --git a/test/Makefile b/test/Makefile
index d41f3a9695..b4f0064233 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -23,7 +23,7 @@
EMACS = emacs -Q -batch -L ../
CLEAN_FILES = .\\\#* \\\#* .*~ *~ *.elc *.log
-TESTS = tramp-tests
+TESTS = tramp-tests tramp-archive-tests
SOURCE_DIR = ~/src/tramp
TRAMP_TEST_ARGS ?=
@@ -57,3 +57,6 @@ sync:
cp -p $(SOURCE_DIR)/test/README README
cp -p $(SOURCE_DIR)/test/tramp-archive-tests.el tramp-archive-tests.el
cp -p $(SOURCE_DIR)/test/tramp-tests.el tramp-tests.el
+ cp -p $(SOURCE_DIR)/test/resources/foo.iso/foo resources/foo.iso/foo
+ cp -p $(SOURCE_DIR)/test/resources/foo.tar.gz resources/foo.tar.gz
+ cp -p $(SOURCE_DIR)/test/resources/foo.zip resources/foo.zip
diff --git a/test/README b/test/README
index 9b9a437d6a..4a87719fa7 100644
--- a/test/README
+++ b/test/README
@@ -35,6 +35,9 @@ tramp-time.el (not on GNU ELPA)
These are performance tests on Tramp. Read the "Commentary"
section for details. These tests are not covered by the Makefile.
+resources/
+ A directory containing test files.
+
The Makefile in this directory supports the following targets:
* make all -or- make check
diff --git a/test/resources/foo.iso/foo b/test/resources/foo.iso/foo
new file mode 100644
index 0000000000..257cc5642c
--- /dev/null
+++ b/test/resources/foo.iso/foo
@@ -0,0 +1 @@
+foo
diff --git a/test/resources/foo.tar.gz b/test/resources/foo.tar.gz
new file mode 100644
index 0000000000..0d2e9878dd
Binary files /dev/null and b/test/resources/foo.tar.gz differ
diff --git a/test/resources/foo.zip b/test/resources/foo.zip
new file mode 100644
index 0000000000..deda1013eb
Binary files /dev/null and b/test/resources/foo.zip differ
diff --git a/test/tramp-archive-tests.el b/test/tramp-archive-tests.el
index 33dc0b9d4a..5e9ea756b9 100644
--- a/test/tramp-archive-tests.el
+++ b/test/tramp-archive-tests.el
@@ -36,12 +36,6 @@
(defvar tramp-archive-test-file-archive (ert-resource-file "foo.tar.gz")
"The test file archive.")
-(defun tramp-archive-test-file-archive-hexlified ()
- "Return hexlified `tramp-archive-test-file-archive'.
-Do not hexlify \"/\". This hexlified string is used in `file:///' URLs."
- (let* ((url-unreserved-chars (cons ?/ url-unreserved-chars)))
- (url-hexify-string tramp-archive-test-file-archive)))
-
(defvar tramp-archive-test-archive
(file-name-as-directory tramp-archive-test-file-archive)
"The test archive.")
@@ -50,11 +44,28 @@ Do not hexlify \"/\". This hexlified string is used in
`file:///' URLs."
(file-truename (ert-resource-file "foo.iso"))
"A directory file name, which looks like an archive.")
+(defvar tramp-archive-test-cascaded-file-archive
+ (ert-resource-file "foo.zip/foo.tar.gz")
+ "The cascaded test file archive.")
+
+(defvar tramp-archive-test-cascaded-archive
+ (file-name-as-directory tramp-archive-test-cascaded-file-archive)
+ "The cascaded test archive.")
+
+(defun tramp-archive-test-file-archive-hexlified ()
+ "Return hexlified `tramp-archive-test-file-archive'.
+Do not hexlify \"/\". This hexlified string is used in `file:///' URLs."
+ (let* ((url-unreserved-chars (cons ?/ url-unreserved-chars)))
+ (url-hexify-string tramp-archive-test-file-archive)))
+
(setq password-cache-expiry nil
tramp-cache-read-persistent-data t ;; For auth-sources.
tramp-persistency-file-name nil
tramp-verbose 0)
+(defvar tramp-archive-test-cascaded nil
+ "Indicator, whether we are testing a cascaded archive.")
+
(defun tramp-archive--test-make-temp-name ()
"Return a temporary file name for test.
The temporary file is not created."
@@ -86,9 +97,29 @@ the origin of the temporary TMPFILE, have no write
permissions."
(file-exists-p tramp-archive-test-file-archive)
(tramp-archive-file-name-p tramp-archive-test-archive))))
+;; These tests are inspired by Bug#79582.
+(defmacro tramp-archive--test-deftest-cascaded (test)
+ "Define ert `TEST-cascaded'."
+ (declare (indent 1))
+ `(ert-deftest ,(intern (concat (symbol-name test) "-cascaded")) ()
+ :tags '(:expensive-test)
+ ;(tramp--test-set-ert-test-documentation ',test "cascaded")
+ (skip-unless tramp-archive-enabled)
+ (if-let* ((ert-test (ert-get-test ',test))
+ (result (ert-test-most-recent-result ert-test))
+ (tramp-archive-test-file-archive
+ tramp-archive-test-cascaded-file-archive)
+ (tramp-archive-test-archive tramp-archive-test-cascaded-archive)
+ (tramp-archive-test-cascaded t))
+ (progn
+ (skip-unless (< (ert-test-result-duration result) 300))
+ (funcall (ert-test-body ert-test)))
+ (ert-skip (format "Test `%s' must run before" ',test)))))
+
(ert-deftest tramp-archive-test01-file-name-syntax ()
"Check archive file name syntax."
- (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive))
+ (unless tramp-archive-test-cascaded
+ (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive)))
(should (tramp-archive-file-name-p tramp-archive-test-archive))
(should
(string-equal
@@ -136,6 +167,8 @@ the origin of the temporary TMPFILE, have no write
permissions."
(concat tramp-archive-test-archive "baz.tar/"))
"/")))
+(tramp-archive--test-deftest-cascaded tramp-archive-test01-file-name-syntax)
+
(ert-deftest tramp-archive-test02-file-name-dissect ()
"Check archive file name components."
(skip-unless tramp-archive-enabled)
@@ -250,10 +283,13 @@ the origin of the temporary TMPFILE, have no write
permissions."
(string-equal
(expand-file-name (concat tramp-archive-test-archive "./file"))
(concat tramp-archive-test-archive "file")))
- (should
- (string-equal
- (expand-file-name (concat tramp-archive-test-archive "../file"))
- (concat (ert-resource-directory) "file"))))
+ (unless tramp-archive-test-cascaded
+ (should
+ (string-equal
+ (expand-file-name (concat tramp-archive-test-archive "../file"))
+ (concat (ert-resource-directory) "file")))))
+
+(tramp-archive--test-deftest-cascaded tramp-archive-test05-expand-file-name)
;; This test is inspired by Bug#30293.
(ert-deftest tramp-archive-test05-expand-file-name-non-archive-directory ()
@@ -332,6 +368,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
(unhandled-file-name-directory
(concat tramp-archive-test-archive "path/to/file"))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test06-directory-file-name)
+
(ert-deftest tramp-archive-test07-file-exists-p ()
"Check `file-exist-p', `write-region' and `delete-file'."
:tags '(:expensive-test)
@@ -355,6 +393,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
;; Cleanup.
(tramp-archive-cleanup-hash)))
+(tramp-archive--test-deftest-cascaded tramp-archive-test07-file-exists-p)
+
(ert-deftest tramp-archive-test08-file-local-copy ()
"Check `file-local-copy'."
:tags '(:expensive-test)
@@ -382,6 +422,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
(ignore-errors (tramp-archive--test-delete tmp-name))
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test08-file-local-copy)
+
(ert-deftest tramp-archive-test09-insert-file-contents ()
"Check `insert-file-contents'."
:tags '(:expensive-test)
@@ -409,6 +451,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded
tramp-archive-test09-insert-file-contents)
+
(ert-deftest tramp-archive-test11-copy-file ()
"Check `copy-file'."
:tags '(:expensive-test)
@@ -475,6 +519,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
(ignore-errors (tramp-archive--test-delete tmp-name2))
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test11-copy-file)
+
(ert-deftest tramp-archive-test15-copy-directory ()
"Check `copy-directory'."
:tags '(:expensive-test)
@@ -528,6 +574,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
(ignore-errors (tramp-archive--test-delete tmp-name2))
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test15-copy-directory)
+
(ert-deftest tramp-archive-test16-directory-files ()
"Check `directory-files'."
:tags '(:expensive-test)
@@ -552,6 +600,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test16-directory-files)
+
(ert-deftest tramp-archive-test17-insert-directory ()
"Check `insert-directory'."
:tags '(:expensive-test)
@@ -600,6 +650,8 @@ This checks also `file-name-as-directory',
`file-name-directory',
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test17-insert-directory)
+
(ert-deftest tramp-archive-test18-file-attributes ()
"Check `file-attributes'.
This tests also `access-file', `file-readable-p' and `file-regular-p'."
@@ -661,6 +713,8 @@ This tests also `access-file', `file-readable-p' and
`file-regular-p'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test18-file-attributes)
+
(ert-deftest tramp-archive-test19-directory-files-and-attributes ()
"Check `directory-files-and-attributes'."
:tags '(:expensive-test)
@@ -686,6 +740,9 @@ This tests also `access-file', `file-readable-p' and
`file-regular-p'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded
+ tramp-archive-test19-directory-files-and-attributes)
+
(ert-deftest tramp-archive-test20-file-modes ()
"Check `file-modes'.
This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
@@ -717,6 +774,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test20-file-modes)
+
(ert-deftest tramp-archive-test21-file-links ()
"Check `file-symlink-p' and `file-truename'"
:tags '(:expensive-test)
@@ -758,6 +817,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test21-file-links)
+
(ert-deftest tramp-archive-test26-file-name-completion ()
"Check `file-name-completion' and `file-name-all-completions'."
:tags '(:expensive-test)
@@ -797,6 +858,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
+(tramp-archive--test-deftest-cascaded
tramp-archive-test26-file-name-completion)
+
(ert-deftest tramp-archive-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless tramp-archive-enabled)
@@ -824,6 +887,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
(delete-directory tmp-file)
(should-not (file-exists-p tmp-file))))
+(tramp-archive--test-deftest-cascaded
tramp-archive-test40-make-nearby-temp-file)
+
(ert-deftest tramp-archive-test43-file-system-info ()
"Check that `file-system-info' returns proper values."
(skip-unless tramp-archive-enabled)
@@ -837,6 +902,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
(zerop (nth 1 fsi))
(zerop (nth 2 fsi))))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test43-file-system-info)
+
;; `file-user-uid' and `file-group-gid' were introduced in Emacs 30.1.
(ert-deftest tramp-archive-test44-user-group-ids ()
"Check results of user/group functions.
@@ -856,6 +923,8 @@ This tests also `file-executable-p', `file-writable-p' and
`set-file-modes'."
(should (equal uid (with-no-warnings (file-user-uid))))
(should (equal gid (with-no-warnings (file-group-gid)))))))
+(tramp-archive--test-deftest-cascaded tramp-archive-test44-user-group-ids)
+
(ert-deftest tramp-archive-test50-auto-load ()
"Check that `tramp-archive' autoloads properly."
:tags '(:expensive-test)
diff --git a/test/tramp-tests.el b/test/tramp-tests.el
index 3432e6eb70..7099a614a4 100644
--- a/test/tramp-tests.el
+++ b/test/tramp-tests.el
@@ -181,8 +181,11 @@ The temporary file is not created."
`(condition-case err
(progn ,@body)
(file-error
- (unless (string-equal (error-message-string err)
- "make-symbolic-link not supported")
+ (unless (string-match-p
+ (rx bol (| "make-symbolic-link not supported"
+ (: "Making symbolic link"
+ (? ":") " Operation not permitted")))
+ (error-message-string err))
(signal (car err) (cdr err))))))
;; Don't print messages in nested `tramp--test-instrument-test-case' calls.
@@ -8540,8 +8543,7 @@ process sentinels. They shall not disturb each other."
(ert-deftest tramp-test48-session-timeout ()
"Check that Tramp handles a session timeout properly."
(skip-unless (tramp--test-enabled))
- (skip-unless
- (tramp-get-method-parameter tramp-test-vec 'tramp-session-timeout))
+ (skip-unless (tramp--test-sh-p))
;; We want to see the timeout message.
(tramp--test-instrument-test-case 3
@@ -8668,11 +8670,17 @@ process sentinels. They shall not disturb each other."
(let ((default-directory ert-remote-temporary-file-directory))
(should
(string-equal (tramp--test-operation)
- (tramp--handler-for-test-operation))))
+ (tramp--handler-for-test-operation)))
+ (should
+ (string-equal (tramp--test-operation "foo")
+ (tramp--handler-for-test-operation "foo"))))
(let ((default-directory temporary-file-directory))
(should-not
(string-equal (tramp--test-operation)
- (tramp--handler-for-test-operation))))
+ (tramp--handler-for-test-operation)))
+ (should-not
+ (string-equal (tramp--test-operation "foo")
+ (tramp--handler-for-test-operation "foo"))))
(tramp-remove-external-operation
#'tramp--test-operation backend)
@@ -8688,11 +8696,17 @@ process sentinels. They shall not disturb each other."
(let ((default-directory ert-remote-temporary-file-directory))
(should-not
(string-equal (tramp--test-operation)
- (tramp--handler-for-test-operation))))
+ (tramp--handler-for-test-operation)))
+ (should-not
+ (string-equal (tramp--test-operation "foo")
+ (tramp--handler-for-test-operation "foo"))))
(let ((default-directory temporary-file-directory))
(should-not
(string-equal (tramp--test-operation)
- (tramp--handler-for-test-operation))))))
+ (tramp--handler-for-test-operation)))
+ (should-not
+ (string-equal (tramp--test-operation "foo")
+ (tramp--handler-for-test-operation "foo"))))))
;; This test is inspired by Bug#29163.
(ert-deftest tramp-test50-auto-load ()
diff --git a/texi/tramp.texi b/texi/tramp.texi
index 5d281dc062..e46f7b9155 100644
--- a/texi/tramp.texi
+++ b/texi/tramp.texi
@@ -678,7 +678,10 @@ not auto loaded by Emacs. All examples require
@value{tramp} to be
installed and loaded:
@lisp
+@group
+(require 'tramp)
(customize-set-variable 'tramp-verbose 6 "Enable remote command traces")
+@end group
@end lisp
For functions used to configure @value{tramp}, the following clause
@@ -852,12 +855,20 @@ as the @option{rsh} method.
@cindex method @option{su}
@cindex @option{su} method
@item @option{su}
+@cindex method @option{surs}
+@cindex @option{surs} method
+@item @option{surs}
Instead of connecting to a remote host, @command{su} program allows
editing as another user. The host can be either @samp{localhost} or
the host returned by the function @command{(system-name)}.
@xref{Multi-hops}, for an exception to this behavior.
+Method @option{surs} is the same like method @option{su}, but it uses
+the modern @command{su-rs} program. It can be used instead wherever
+method @option{su} is mentioned in this manual. @option{surs} is an
+optional method, @pxref{Optional methods}.
+
@cindex method @option{androidsu}
@cindex @option{androidsu} method
@item @option{androidsu}
@@ -876,6 +887,9 @@ default on @code{android} systems only.
@cindex method @option{sudo}
@cindex @option{sudo} method
@item @option{sudo}
+@cindex method @option{sudors}
+@cindex @option{sudors} method
+@item @option{sudors}
Similar to @option{su} method, @option{sudo} uses @command{sudo}.
@command{sudo} must have sufficient rights to start a shell.
@@ -884,6 +898,11 @@ For security reasons, a @option{sudo} connection is
disabled after a
predefined timeout (5 minutes by default). This can be changed,
@pxref{Predefined connection information}.
+Method @option{sudors} is the same like method @option{sudo}, but it
+uses the modern @command{sudo-rs} program. It can be used instead
+wherever method @option{sudo} is mentioned in this manual.
+@option{sudors} is an optional method, @pxref{Optional methods}.
+
@cindex method @option{doas}
@cindex @option{doas} method
@item @option{doas}
@@ -4832,7 +4851,7 @@ for which no associated buffers exist (except for Tramp
internal
buffers).
This command is helpful to prune connections after you close remote-file
-buffers without having to either cherry pick via
+buffers without having to either cherry-pick via
@code{tramp-cleanup-connection} or clear them all via
@code{tramp-cleanup-all-connections}.
@end deffn
diff --git a/texi/trampver.texi b/texi/trampver.texi
index a2ff88cd29..2fbc047817 100644
--- a/texi/trampver.texi
+++ b/texi/trampver.texi
@@ -7,7 +7,7 @@
@c In the Tramp GIT, the version number and the bug report address
@c are auto-frobbed from configure.ac.
-@set trampver 2.8.0.3
+@set trampver 2.8.0.4
@set trampurl https://www.gnu.org/software/tramp/
@set tramp-bug-report-address tramp-devel@@gnu.org
@set emacsver 28.1
diff --git a/tramp-archive.el b/tramp-archive.el
index 3de909911b..a52b8be6e0 100644
--- a/tramp-archive.el
+++ b/tramp-archive.el
@@ -338,15 +338,16 @@ arguments to pass to the OPERATION."
(tramp-register-file-name-handlers)
(tramp-archive-run-real-handler operation args))
- (let* ((filename (apply #'tramp-archive-file-name-for-operation
+ (let* ((tramp-methods (cons `(,tramp-archive-method) tramp-methods))
+ (tramp-gvfs-methods tramp-archive-all-gvfs-methods)
+ (filename (apply #'tramp-archive-file-name-for-operation
operation args))
(archive (tramp-archive-file-name-archive filename)))
;; `filename' could be a quoted file name. Or the file
;; archive could be a directory, see Bug#30293.
(if (or (null archive)
- (not (tramp-archive-run-real-handler
- #'file-exists-p (list archive)))
+ (not (file-exists-p archive))
(tramp-archive-run-real-handler
#'file-directory-p (list archive)))
(tramp-archive-run-real-handler operation args)
@@ -358,9 +359,7 @@ arguments to pass to the OPERATION."
(tramp-get-buffer (tramp-archive-dissect-file-name filename))
(setq default-directory (file-name-as-directory archive)))
;; Now run the handler.
- (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods))
- (tramp-gvfs-methods tramp-archive-all-gvfs-methods)
- ;; Set uid and gid. gvfsd-archive could do it, but it doesn't.
+ (let (;; Set uid and gid. gvfsd-archive could do it, but it doesn't.
(tramp-unknown-id-integer (user-uid))
(tramp-unknown-id-string (user-login-name))
(fn (assoc operation tramp-archive-file-name-handler-alist)))
diff --git a/tramp-cache.el b/tramp-cache.el
index eedb5a3e9b..941c502fa8 100644
--- a/tramp-cache.el
+++ b/tramp-cache.el
@@ -90,6 +90,7 @@
(require 'time-stamp)
(declare-function tramp-get-method-parameter "tramp")
+(defvar tramp-verbose)
;;; -- Cache --
@@ -97,7 +98,6 @@
(defvar tramp-cache-data (make-hash-table :test #'equal)
"Hash table for remote files properties.")
-;;;###tramp-autoload
(defcustom tramp-connection-properties nil
"List of static connection properties.
Every entry has the form (REGEXP PROPERTY VALUE). The regexp
@@ -253,19 +253,19 @@ Return VALUE."
(defun tramp-flush-file-upper-properties (key file)
"Remove some properties of FILE's upper directory."
- (when (file-name-absolute-p file)
- ;; `file-name-directory' can return nil, for example for "~".
- (when-let* ((file (file-name-directory file))
- (file (directory-file-name file)))
- (setq key (tramp-file-name-unify key file))
- (unless (eq key tramp-cache-undefined)
- (dolist (property (hash-table-keys (tramp-get-hash-table key)))
- (when (string-match-p
- (rx
- bos (| "directory-" "file-name-all-completions"
- "file-entries"))
- property)
- (tramp-flush-file-property key file property)))))))
+ (when-let* (((file-name-absolute-p file))
+ ;; `file-name-directory' can return nil, for example for "~".
+ (file (file-name-directory file))
+ (file (directory-file-name file)))
+ (setq key (tramp-file-name-unify key file))
+ (unless (eq key tramp-cache-undefined)
+ (dolist (property (hash-table-keys (tramp-get-hash-table key)))
+ (when (string-match-p
+ (rx
+ bos (| "directory-" "file-name-all-completions"
+ "file-entries"))
+ property)
+ (tramp-flush-file-property key file property))))))
;;;###tramp-autoload
(defun tramp-flush-file-properties (key file)
diff --git a/tramp-cmds.el b/tramp-cmds.el
index 6042209d4f..db3737500e 100644
--- a/tramp-cmds.el
+++ b/tramp-cmds.el
@@ -631,14 +631,29 @@ For details, see `tramp-rename-files'."
(defcustom tramp-file-name-with-method "sudo"
"Which method to be used in `tramp-file-name-with-sudo'."
:group 'tramp
- :version "30.1"
- :type '(choice (const "su")
- (const "sudo")
+ :version "31.1"
+ ;; It should be a choice of constant strings. See
+ ;; `with-tramp-file-name-with-method'.
+ :type '(choice (const "su") (const "surs")
+ (const "sudo") (const "sudors")
(const "doas")
(const "run0")
(const "ksu"))
+ :initialize #'custom-initialize-default
+ :set #'tramp-set-file-name-with-method
:link '(tramp-info-link :tag "Tramp manual" tramp-file-name-with-method))
+(defun tramp-set-file-name-with-method (symbol value)
+ "Set SYMBOL to value VALUE.
+Used in user option `tramp-file-name-with-method'. If VALUE is an
+optional method, enable it."
+ (unless (string-equal (symbol-value symbol) value)
+ ;; Enable optional method.
+ (tramp-enable-method value)
+ ;; Set the value.
+ (when (assoc value tramp-methods)
+ (set-default symbol value))))
+
(defun tramp-get-file-name-with-method ()
"Return connection-local value of `tramp-file-name-with-method'."
(tramp-compat-connection-local-value tramp-file-name-with-method))
@@ -651,8 +666,11 @@ Run BODY."
(if current-prefix-arg
(completing-read
"Tramp method: "
- (mapcar
- #'cadr (cdr (get 'tramp-file-name-with-method 'custom-type)))
+ ;; Filter out enabled methods.
+ (seq-intersection
+ (mapcar #'car tramp-methods)
+ (mapcar
+ #'cadr (cdr (get 'tramp-file-name-with-method 'custom-type))))
nil t (tramp-get-file-name-with-method))
(tramp-get-file-name-with-method))))
,@body))
diff --git a/tramp-compat.el b/tramp-compat.el
index 5d463bc006..93190fec3a 100644
--- a/tramp-compat.el
+++ b/tramp-compat.el
@@ -259,5 +259,8 @@ value is the default binding of the variable."
;; instead of `condition-case' when the origin of an error shall be
;; kept, for example when the HANDLER propagates the error with
;; `(signal (car err) (cdr err)'.
+;;
+;; * Starting with Emacs 30.1, use '(_ VALUEFORM)' instead of
+;; '(VALUEFORM)' in 'if-let*/when-let*/and-let*'.
;;; tramp-compat.el ends here
diff --git a/tramp-gvfs.el b/tramp-gvfs.el
index c283c119b8..687cc7e1bc 100644
--- a/tramp-gvfs.el
+++ b/tramp-gvfs.el
@@ -123,7 +123,10 @@
(and (featurep 'dbusbind)
(tramp-compat-funcall 'dbus-get-unique-name :session)
(or (tramp-process-running-p "gvfs-fuse-daemon")
- (tramp-process-running-p "gvfsd-fuse"))))
+ (tramp-process-running-p "gvfsd-fuse")
+ ;; Gvfs may be built without fuse
+ ;; (cf.
https://lists.gnu.org/archive/html/tramp-devel/2025-10/msg00009.html).
+ (tramp-process-running-p "gvfsd"))))
"Non-nil when GVFS is available.")
;;;###tramp-autoload
diff --git a/tramp-message.el b/tramp-message.el
index a328183e18..d349179d0e 100644
--- a/tramp-message.el
+++ b/tramp-message.el
@@ -56,7 +56,6 @@
(defvar tramp-repository-branch)
(defvar tramp-repository-version)
-;;;###tramp-autoload
(defcustom tramp-verbose 3
"Verbosity level for Tramp messages.
Any level x includes messages for all levels 1 .. x-1. The levels are
diff --git a/tramp-sh.el b/tramp-sh.el
index 8922adb758..61f64e4c02 100644
--- a/tramp-sh.el
+++ b/tramp-sh.el
@@ -521,6 +521,42 @@ The string is used in `tramp-methods'.")
(tramp-set-completion-function "nc" tramp-completion-function-alist-telnet))
+;;;###tramp-autoload
+(defun tramp-enable-surs-method ()
+ "Enable \"surs\" method."
+ (add-to-list 'tramp-methods
+ `("surs"
+ (tramp-login-program "su-rs")
+ (tramp-login-args (("-") ("%u")))
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-c"))
+ (tramp-connection-timeout 10)))
+
+ (add-to-list 'tramp-default-user-alist
+ `(,(rx bos "surs" eos) nil ,tramp-root-id-string))
+
+ (tramp-set-completion-function "surs" tramp-completion-function-alist-su))
+
+;;;###tramp-autoload
+(defun tramp-enable-sudors-method ()
+ "Enable \"sudors\" method."
+ (add-to-list 'tramp-methods
+ `("sudors"
+ (tramp-login-program "sudo-rs")
+ (tramp-login-args (("-u" "%u") ("-s") ("%l")))
+ (tramp-remote-shell ,tramp-default-remote-shell)
+ (tramp-remote-shell-login ("-l"))
+ (tramp-remote-shell-args ("-c"))
+ (tramp-connection-timeout 10)
+ (tramp-session-timeout 300)
+ (tramp-password-previous-hop t)))
+
+ (add-to-list 'tramp-default-user-alist
+ `(,(rx bos "sudors" eos) nil ,tramp-root-id-string))
+
+ (tramp-set-completion-function "sudors" tramp-completion-function-alist-su))
+
;;;###tramp-autoload
(defun tramp-enable-run0-method ()
"Enable \"run0\" method."
@@ -2898,15 +2934,15 @@ The method used must be an out-of-band method."
;; Try to insert the amount of free space.
(goto-char (point-min))
;; First find the line to put it on.
- (when (and (search-forward-regexp
- (rx bol (group (* blank) "total")) nil t)
- ;; Emacs 29.1 or later.
- (not (fboundp 'dired--insert-disk-space)))
- (when-let* ((available (get-free-disk-space ".")))
- ;; Replace "total" with "total used", to avoid confusion.
- (replace-match "\\1 used in directory")
- (end-of-line)
- (insert " available " available))))
+ (when-let* (((search-forward-regexp
+ (rx bol (group (* blank) "total")) nil t))
+ ;; Emacs 29.1 or later.
+ ((not (fboundp 'dired--insert-disk-space)))
+ (available (get-free-disk-space ".")))
+ ;; Replace "total" with "total used", to avoid confusion.
+ (replace-match "\\1 used in directory")
+ (end-of-line)
+ (insert " available " available)))
(prog1 (goto-char end-marker)
(set-marker beg-marker nil)
@@ -2964,7 +3000,10 @@ the result will be a local, non-Tramp, file name."
;; use a user name from the config file.
(when (and (tramp-string-empty-or-nil-p uname)
(string-match-p
- (rx bos (| "su" "sudo" "doas" "run0" "ksu") eos)
method))
+ (rx bos
+ (| "su" "surs" "sudo" "sudors" "doas" "run0" "ksu")
+ eos)
+ method))
(setq uname user))
(when (setq hname (tramp-get-home-directory v uname))
(setq localname (concat hname fname)))))
diff --git a/tramp.el b/tramp.el
index ce6c6ee63b..18991666f4 100644
--- a/tramp.el
+++ b/tramp.el
@@ -7,7 +7,7 @@
;; Maintainer: Michael Albinus <[email protected]>
;; Keywords: comm, processes
;; Package: tramp
-;; Version: 2.8.0.3
+;; Version: 2.8.0.4
;; Package-Requires: ((emacs "28.1"))
;; Package-Type: multi
;; URL: https://www.gnu.org/software/tramp/
@@ -418,12 +418,12 @@ Notes:
All these arguments can be overwritten by connection properties.
See Info node `(tramp) Predefined connection information'.
-When using `su', `sudo' or `doas' the phrase \"open connection to
-a remote host\" sounds strange, but it is used nevertheless, for
-consistency. No connection is opened to a remote host, but `su',
-`sudo' or `doas' is started on the local host. You should
-specify a remote host `localhost' or the name of the local host.
-Another host name is useful only in combination with
+When using `su', `surs', `sg', `sudo', `sudors', `doas', `run0' or `ksu'
+the phrase \"open connection to a remote host\" sounds strange, but it
+is used nevertheless, for consistency. No connection is opened to a
+remote host, but the respective command is started on the local host.
+You should specify a remote host `localhost' or the name of the local
+host. Another host name is useful only in combination with
`tramp-default-proxies-alist'.")
(defcustom tramp-default-method
@@ -927,6 +927,7 @@ Customize. See also `tramp-change-syntax'."
(const :tag "Ange-FTP" simplified)
(const :tag "XEmacs" separate))
:require 'tramp
+ ;; Starting with Emacs 31.1, we can use `custom-initialize-after-file'
instead.
:initialize #'custom-initialize-default
:set #'tramp-set-syntax
:link '(info-link :tag "Tramp manual" "(tramp) Change file name syntax"))
@@ -941,7 +942,7 @@ to be set, depending on VALUE."
;; Cleanup existing buffers.
(unless (eq (symbol-value symbol) value)
(tramp-cleanup-all-buffers))
- ;; Set the value:
+ ;; Set the value.
(set-default symbol value)
;; Reset the depending variables.
(setq tramp-prefix-format (tramp-build-prefix-format)
@@ -970,6 +971,7 @@ to be set, depending on VALUE."
;; Initialize the Tramp syntax variables. We want to override initial
;; value of `tramp-file-name-regexp'. We do not call
;; `custom-set-variable', this would load Tramp via custom.el.
+;; Starting with Emacs 31.1, we can use `custom-initialize-after-file' instead.
(tramp--with-startup
(tramp-set-syntax 'tramp-syntax tramp-syntax))
@@ -1939,6 +1941,9 @@ expected to be a string, which will be used."
(when (cadr args)
(setq localname (and (stringp (cadr args)) (cadr args))))
(when hop
+ ;; Do not keep the hop for the "archive" method.
+ (when (string-equal method tramp-archive-method)
+ (setq hop nil))
;; Keep hop in file name for completion or when indicated.
(unless (or minibuffer-completing-file-name tramp-show-ad-hoc-proxies)
(setq hop nil))
@@ -2553,7 +2558,9 @@ packages like `tramp-sh' (except `tramp-ftp')."
`(lambda (orig-fun &rest args)
(if-let* ((handler
(find-file-name-handler
- (or (car args) default-directory) #',operation)))
+ (if (and (car args) (file-name-absolute-p (car args)))
+ (car args) default-directory)
+ #',operation)))
(apply handler #',operation args)
(apply orig-fun args)))
`((name . ,(concat "tramp-advice-" (symbol-name operation))))))))
@@ -4085,17 +4092,17 @@ BODY is the backend specific code."
(let (last-coding-system-used (need-chown t))
;; Set file modification time.
- (when (or (eq ,visit t) (stringp ,visit))
- (when-let* ((file-attr (file-attributes filename 'integer)))
- (set-visited-file-modtime
- ;; We must pass modtime explicitly, because FILENAME
- ;; can be different from (buffer-file-name), f.e. if
- ;; `file-precious-flag' is set.
- (or (file-attribute-modification-time file-attr)
- (current-time)))
- (when (and (= (file-attribute-user-id file-attr) uid)
- (= (file-attribute-group-id file-attr) gid))
- (setq need-chown nil))))
+ (when-let* (((or (eq ,visit t) (stringp ,visit)))
+ (file-attr (file-attributes filename 'integer)))
+ (set-visited-file-modtime
+ ;; We must pass modtime explicitly, because FILENAME
+ ;; can be different from (buffer-file-name), f.e. if
+ ;; `file-precious-flag' is set.
+ (or (file-attribute-modification-time file-attr)
+ (current-time)))
+ (when (and (= (file-attribute-user-id file-attr) uid)
+ (= (file-attribute-group-id file-attr) gid))
+ (setq need-chown nil)))
;; Set the ownership.
(when need-chown
@@ -5236,10 +5243,11 @@ Do not set it manually, it is used buffer-local in
`tramp-get-lock-pid'.")
vec "Method `%s' is not supported for multi-hops"
(tramp-file-name-method item)))))
- ;; Some methods ("su", "sg", "sudo", "doas", "run0", "ksu") do
- ;; not use the host name in their command template. In this
- ;; case, the remote file name must use either a local host name
- ;; (first hop), or a host name matching the previous hop.
+ ;; Some methods ("su", "surs", "sg", "sudo", "sudors", "doas",
+ ;; "run0", "ksu") do not use the host name in their command
+ ;; template. In this case, the remote file name must use either
+ ;; a local host name (first hop), or a host name matching the
+ ;; previous hop.
(let ((previous-host (or tramp-local-host-regexp "")))
(setq choices target-alist)
(while (setq item (pop choices))
@@ -7160,7 +7168,7 @@ verbosity of 6."
;; The returned command name could be truncated
;; to 15 characters. Therefore, we cannot check
;; for `string-equal'.
- ((string-prefix-p comm process-name))
+ ((eq t (compare-strings comm 0 15 process-name 0 15)))
((throw 'result t)))))))))
;; When calling "emacs -Q", `auth-source-search' won't be called. If
@@ -7217,6 +7225,7 @@ Consults the auth-source package."
(tramp-compat-auth-info-password auth-info))))
;; Try the password cache.
+ ;; Starting with Emacs 31.1, this isn't needed anymore.
(with-tramp-suspended-timers
(setq auth-passwd
(password-read
diff --git a/trampver.el b/trampver.el
index cbd8e30e53..3af36b32b5 100644
--- a/trampver.el
+++ b/trampver.el
@@ -7,7 +7,7 @@
;; Maintainer: Michael Albinus <[email protected]>
;; Keywords: comm, processes
;; Package: tramp
-;; Version: 2.8.0.3
+;; Version: 2.8.0.4
;; Package-Requires: ((emacs "28.1"))
;; Package-Type: multi
;; URL: https://www.gnu.org/software/tramp/
@@ -40,7 +40,7 @@
;; ./configure" to change them.
;;;###tramp-autoload
-(defconst tramp-version "2.8.0.3"
+(defconst tramp-version "2.8.0.4"
"This version of Tramp.")
;;;###tramp-autoload
@@ -76,7 +76,7 @@
;; Check for Emacs version.
(let ((x (if (not (string-version-lessp emacs-version "28.1"))
"ok"
- (format "Tramp 2.8.0.3 is not fit for %s"
+ (format "Tramp 2.8.0.4 is not fit for %s"
(replace-regexp-in-string "\n" "" (emacs-version))))))
(unless (string-equal "ok" x) (error "%s" x)))