Remove Emacs 25 compatibility from Tramp

* doc/misc/tramp.texi (Remote programs, Remote processes)
(Frequently Asked Questions): Adapt Emacs versions.

* doc/misc/trampver.texi:
* lisp/net/trampver.el: Change version to "2.6.0-pre".

* lisp/net/tramp-adb.el (top): Don't use `tramp-compat-funcall' for
connection-local functions.

* lisp/net/tramp-compat.el (tramp-unload-file-name-handlers)
(tramp-handle-temporary-file-directory)
(tramp-compat-temporary-file-directory-function)
(tramp-compat-file-attribute-type)
(tramp-compat-file-attribute-link-number)
(tramp-compat-file-attribute-user-id)
(tramp-compat-file-attribute-group-id)
(tramp-compat-file-attribute-access-time)
(tramp-compat-file-attribute-modification-time)
(tramp-compat-file-attribute-status-change-time)
(tramp-compat-file-attribute-size)
(tramp-compat-file-attribute-modes, tramp-file-missing)
(tramp-compat-file-missing, tramp-compat-file-local-name): Remove.
(tramp-compat-file-name-quoted-p, tramp-compat-file-name-quote)
(tramp-compat-file-name-unquote)
(tramp-compat-progress-reporter-update)
(tramp-compat-file-modes, tramp-compat-set-file-modes)
(tramp-compat-set-file-times, tramp-compat-directory-files)
(tramp-compat-directory-files-and-attributes): Adapt implementation.

* lisp/net/tramp.el:
* lisp/net/tramp-adb.el:
* lisp/net/tramp-archive.el:
* lisp/net/tramp-crypt.el:
* lisp/net/tramp-fuse.el:
* lisp/net/tramp-gvfs.el:
* lisp/net/tramp-rclone.el:
* lisp/net/tramp-sh.el:
* lisp/net/tramp-smb.el:
* lisp/net/tramp-sudoedit.el: Adapt callees.

* lisp/net/tramp-crypt.el (tramp-crypt-config-file-name):
Expand file name.

* lisp/net/tramp-fuse.el (tramp-fuse-handle-file-readable-p): Remove.

* lisp/net/tramp-gvfs.el (tramp-gvfs-enabled): Don't check Emacs version.
(tramp-gvfs-handler-mounted-unmounted): Use `make-tramp-file-name'.

* lisp/net/tramp-integration.el (rfn-eshadow-overlay):
Remove declaration.
(top): Don't use `tramp-compat-funcall' for connection-local functions.

* lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
Use `tramp-rclone-handle-file-readable-p'.
(tramp-rclone-handle-file-readable-p): New defun.

* lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
Use `tramp-handle-file-readable-p'.

* lisp/net/tramp.el (tramp-temp-name-prefix, tramp-lookup-syntax):
Adapt docstring.
(tramp-set-connection-local-variables)
(tramp-set-connection-local-variables-for-buffer): Don't use
`tramp-compat-funcall' for connection-local functions.
(tramp-file-name-for-operation): Reorder list.
(tramp-handle-make-symbolic-link): Don't handle TARGET and
OK-IF-ALREADY-EXISTS.
(tramp-read-passwd): Don't use `read-passwd' any longer.
(top): Don't check for `interrupt-process-functions'.

* test/lisp/net/tramp-archive-tests.el (tramp-archive--test-emacs26-p):
Remove.
(tramp-archive-test02-file-name-dissect): Use `make-tramp-file-name'.
(all): Replace Emacs 26 compatibility functions with their
original name.
(tramp-archive-test46-auto-load)
(tramp-archive-test46-delay-load): Rename.

* test/lisp/net/tramp-tests.el (dired-aux, seq): Require them.
(dired-compress, connection-local-criteria-alist)
(connection-local-profile-alist, async-shell-command-width):
Don't declare.
(all): Replace Emacs 26 compatibility functions with their
original name.
(tramp-test04-substitute-in-file-name)
(tramp-test10-write-region, tramp-test11-copy-file)
(tramp-test12-rename-file, tramp-test15-copy-directory)
(tramp-test17-insert-directory)
(tramp-test17-dired-with-wildcards, tramp-test21-file-links)
(tramp-test31-interrupt-process)
(tramp-test34-connection-local-variables)
(tramp-test34-explicit-shell-file-name)
(tramp-test40-make-nearby-temp-file)
(tramp-test41-special-characters, tramp-test42-utf8)
(tramp-test46-delay-load, tramp-test46-remote-load-path)
(tramp-test47-unload): Don't check for Emacs 26 special features.
(tramp--test-emacs26-p): Remove.
(tramp--test-emacs29-p): New defun.
(tramp-test45-dired-compress-file)
(tramp-test45-dired-compress-dir): Use it.
(tramp-test44-asynchronous-requests): Use `seq-random-elt'.
This commit is contained in:
Michael Albinus 2021-11-12 18:17:32 +01:00
parent 12d554e5c5
commit 2c5be6ddca
18 changed files with 398 additions and 689 deletions

View file

@ -2238,8 +2238,7 @@ preserves the path value, which can be used to update
shell supports the login argument @samp{-l}.
@end defopt
Starting with @w{Emacs 26}, @code{tramp-remote-path} can be set per
host via connection-local
@code{tramp-remote-path} can also be set per host via connection-local
@ifinfo
variables, @xref{Connection Variables, , , emacs}.
@end ifinfo
@ -3533,9 +3532,8 @@ ensures the correct name of the remote shell program.
When @code{explicit-shell-file-name} is equal to @code{nil}, calling
@code{shell} interactively will prompt for a shell name.
Starting with @w{Emacs 26}, you could use connection-local variables
for setting different values of @code{explicit-shell-file-name} for
different remote hosts.
You could use connection-local variables for setting different values
of @code{explicit-shell-file-name} for different remote hosts.
@ifinfo
@xref{Connection Variables, , , emacs}.
@end ifinfo
@ -4347,8 +4345,8 @@ Where is the latest @value{tramp}?
@item
Which systems does it work on?
The package works successfully on @w{Emacs 25}, @w{Emacs 26}, @w{Emacs
27}, and @w{Emacs 28}.
The package works successfully on @w{Emacs 26}, @w{Emacs 27}, @w{Emacs
28}, and @w{Emacs 29}.
While Unix and Unix-like systems are the primary remote targets,
@value{tramp} has equal success connecting to other platforms, such as

View file

@ -8,10 +8,10 @@
@c In the Tramp GIT, the version numbers are auto-frobbed from
@c tramp.el, and the bug report address is auto-frobbed from
@c configure.ac.
@set trampver 2.5.2-pre
@set trampver 2.6.0-pre
@set trampurl https://www.gnu.org/software/tramp/
@set tramp-bug-report-address tramp-devel@@gnu.org
@set emacsver 25.1
@set emacsver 26.1
@c Other flags from configuration.
@set instprefix /usr/local

View file

@ -119,6 +119,7 @@ It is used for TCP/IP devices."
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-adb-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . tramp-adb-handle-exec-path)
@ -305,7 +306,7 @@ arguments to pass to the OPERATION."
(directory &optional full match nosort id-format count)
"Like `directory-files-and-attributes' for Tramp files."
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(with-parsed-tramp-file-name (expand-file-name directory) nil
(copy-tree
@ -498,7 +499,7 @@ Emacs dired can't find files."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p (file-truename filename))
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(with-tramp-progress-reporter
v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@ -590,8 +591,7 @@ Emacs dired can't find files."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
(or (tramp-compat-file-attribute-modification-time
(file-attributes filename))
(or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Unlock file.
@ -659,7 +659,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(jka-compr-inhibit t))
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -719,8 +719,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(when keep-date
(tramp-compat-set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))
(file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-adb-handle-rename-file
@ -741,7 +740,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(jka-compr-inhibit t))
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -1348,22 +1347,18 @@ connection if a previous connection has died for some reason."
;; Mark it as connected.
(tramp-set-connection-property p "connected" t)))))))
;;; Default connection-local variables for Tramp:
;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exists since Emacs 26.1.
;;; Default connection-local variables for Tramp.
(defconst tramp-adb-connection-local-default-shell-variables
'((shell-file-name . "/system/bin/sh")
(shell-command-switch . "-c"))
"Default connection-local shell variables for remote adb connections.")
(tramp-compat-funcall
'connection-local-set-profile-variables
(connection-local-set-profile-variables
'tramp-adb-connection-local-default-shell-profile
tramp-adb-connection-local-default-shell-variables)
(with-eval-after-load 'shell
(tramp-compat-funcall
'connection-local-set-profiles
(connection-local-set-profiles
`(:application tramp :protocol ,tramp-adb-method)
'tramp-adb-connection-local-default-shell-profile))

View file

@ -223,6 +223,7 @@ It must be supported by libarchive(3).")
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . tramp-archive-handle-not-implemented)
(dired-uncache . tramp-archive-handle-dired-uncache)
(exec-path . ignore)
@ -618,7 +619,7 @@ offered."
(defun tramp-archive-handle-file-system-info (filename)
"Like `file-system-info' for file archives."
(with-parsed-tramp-archive-file-name filename nil
(list (tramp-compat-file-attribute-size (file-attributes archive)) 0 0)))
(list (file-attribute-size (file-attributes archive)) 0 0)))
(defun tramp-archive-handle-file-truename (filename)
"Like `file-truename' for file archives."
@ -658,7 +659,7 @@ offered."
;; mounted directory, it is returned as it. Not what we want.
(with-parsed-tramp-archive-file-name default-directory nil
(let ((default-directory (file-name-directory archive)))
(tramp-compat-temporary-file-directory-function))))
(temporary-file-directory))))
(defun tramp-archive-handle-not-implemented (operation &rest args)
"Generic handler for operations not implemented for file archives."

View file

@ -23,17 +23,12 @@
;;; Commentary:
;; Tramp's main Emacs version for development is Emacs 28. This
;; package provides compatibility functions for Emacs 25, Emacs 26 and
;; Emacs 27.
;; Tramp's main Emacs version for development is Emacs 29. This
;; package provides compatibility functions for Emacs 26, Emacs 27 and
;; Emacs 28.
;;; Code:
;; In Emacs 25, `tramp-unload-file-name-handlers' is not autoloaded.
;; So we declare it here in order to avoid recursive load. This will
;; be overwritten in tramp.el.
(defun tramp-unload-file-name-handlers () ".")
(require 'auth-source)
(require 'format-spec)
(require 'ls-lisp) ;; Due to `tramp-handle-insert-directory'.
@ -42,8 +37,6 @@
(require 'subr-x)
(declare-function tramp-error "tramp")
;; `temporary-file-directory' as function is introduced with Emacs 26.1.
(declare-function tramp-handle-temporary-file-directory "tramp")
(declare-function tramp-tramp-file-p "tramp")
(defvar tramp-temp-name-prefix)
@ -83,133 +76,19 @@ Add the extension of F, if existing."
tramp-temp-name-prefix tramp-compat-temporary-file-directory)
dir-flag (file-name-extension f t)))
;; `temporary-file-directory' as function is introduced with Emacs 26.1.
(defalias 'tramp-compat-temporary-file-directory-function
(if (fboundp 'temporary-file-directory)
#'temporary-file-directory
#'tramp-handle-temporary-file-directory))
;; `file-attribute-*' are introduced in Emacs 26.1.
(defalias 'tramp-compat-file-attribute-type
(if (fboundp 'file-attribute-type)
#'file-attribute-type
(lambda (attributes)
"The type field in ATTRIBUTES returned by `file-attributes'.
The value is either t for directory, string (name linked to) for
symbolic link, or nil."
(nth 0 attributes))))
(defalias 'tramp-compat-file-attribute-link-number
(if (fboundp 'file-attribute-link-number)
#'file-attribute-link-number
(lambda (attributes)
"Return the number of links in ATTRIBUTES returned by `file-attributes'."
(nth 1 attributes))))
(defalias 'tramp-compat-file-attribute-user-id
(if (fboundp 'file-attribute-user-id)
#'file-attribute-user-id
(lambda (attributes)
"The UID field in ATTRIBUTES returned by `file-attributes'.
This is either a string or a number. If a string value cannot be
looked up, a numeric value, either an integer or a float, is
returned."
(nth 2 attributes))))
(defalias 'tramp-compat-file-attribute-group-id
(if (fboundp 'file-attribute-group-id)
#'file-attribute-group-id
(lambda (attributes)
"The GID field in ATTRIBUTES returned by `file-attributes'.
This is either a string or a number. If a string value cannot be
looked up, a numeric value, either an integer or a float, is
returned."
(nth 3 attributes))))
(defalias 'tramp-compat-file-attribute-access-time
(if (fboundp 'file-attribute-access-time)
#'file-attribute-access-time
(lambda (attributes)
"The last access time in ATTRIBUTES returned by `file-attributes'.
This a Lisp timestamp in the style of `current-time'."
(nth 4 attributes))))
(defalias 'tramp-compat-file-attribute-modification-time
(if (fboundp 'file-attribute-modification-time)
#'file-attribute-modification-time
(lambda (attributes)
"The modification time in ATTRIBUTES returned by `file-attributes'.
This is the time of the last change to the file's contents, and
is a Lisp timestamp in the style of `current-time'."
(nth 5 attributes))))
(defalias 'tramp-compat-file-attribute-status-change-time
(if (fboundp 'file-attribute-status-change-time)
#'file-attribute-status-change-time
(lambda (attributes)
"The status modification time in ATTRIBUTES returned by `file-attributes'.
This is the time of last change to the file's attributes: owner
and group, access mode bits, etc., and is a Lisp timestamp in the
style of `current-time'."
(nth 6 attributes))))
(defalias 'tramp-compat-file-attribute-size
(if (fboundp 'file-attribute-size)
#'file-attribute-size
(lambda (attributes)
"The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
If the size is too large for a fixnum, this is a bignum in Emacs 27
and later, and is a float in Emacs 26 and earlier."
(nth 7 attributes))))
(defalias 'tramp-compat-file-attribute-modes
(if (fboundp 'file-attribute-modes)
#'file-attribute-modes
(lambda (attributes)
"The file modes in ATTRIBUTES returned by `file-attributes'.
This is a string of ten letters or dashes as in ls -l."
(nth 8 attributes))))
;; `file-missing' is introduced in Emacs 26.1.
(defconst tramp-file-missing
(if (get 'file-missing 'error-conditions) 'file-missing 'file-error)
"The error symbol for the `file-missing' error.")
(defsubst tramp-compat-file-missing (vec file)
"Emit the `file-missing' error."
(if (get 'file-missing 'error-conditions)
(tramp-error vec tramp-file-missing file)
(tramp-error vec tramp-file-missing "No such file or directory: %s" file)))
;; `file-local-name', `file-name-quoted-p', `file-name-quote' and
;; `file-name-unquote' are introduced in Emacs 26.1.
(defalias 'tramp-compat-file-local-name
(if (fboundp 'file-local-name)
#'file-local-name
(lambda (name)
"Return the local name component of NAME.
It returns a file name which can be used directly as argument of
`process-file', `start-file-process', or `shell-command'."
(or (file-remote-p name 'localname) name))))
;; `file-name-quoted-p', `file-name-quote' and `file-name-unquote' got
;; a second argument in Emacs 27.1.
(defalias 'tramp-compat-file-name-quoted-p
(if (and
(fboundp 'file-name-quoted-p)
(equal (tramp-compat-funcall 'func-arity #'file-name-quoted-p) '(1 . 2)))
(if (equal (func-arity #'file-name-quoted-p) '(1 . 2))
#'file-name-quoted-p
(lambda (name &optional top)
"Whether NAME is quoted with prefix \"/:\".
If NAME is a remote file name and TOP is nil, check the local part of NAME."
(let ((file-name-handler-alist (unless top file-name-handler-alist)))
(string-prefix-p "/:" (tramp-compat-file-local-name name))))))
(string-prefix-p "/:" (file-local-name name))))))
(defalias 'tramp-compat-file-name-quote
(if (and
(fboundp 'file-name-quote)
(equal (tramp-compat-funcall 'func-arity #'file-name-quote) '(1 . 2)))
(if (equal (func-arity #'file-name-quote) '(1 . 2))
#'file-name-quote
(lambda (name &optional top)
"Add the quotation prefix \"/:\" to file NAME.
@ -217,20 +96,17 @@ If NAME is a remote file name and TOP is nil, the local part of NAME is quoted."
(let ((file-name-handler-alist (unless top file-name-handler-alist)))
(if (tramp-compat-file-name-quoted-p name top)
name
(concat
(file-remote-p name) "/:" (tramp-compat-file-local-name name)))))))
(concat (file-remote-p name) "/:" (file-local-name name)))))))
(defalias 'tramp-compat-file-name-unquote
(if (and
(fboundp 'file-name-unquote)
(equal (tramp-compat-funcall 'func-arity #'file-name-unquote) '(1 . 2)))
(if (equal (func-arity #'file-name-unquote) '(1 . 2))
#'file-name-unquote
(lambda (name &optional top)
"Remove quotation prefix \"/:\" from file NAME.
If NAME is a remote file name and TOP is nil, the local part of
NAME is unquoted."
(let* ((file-name-handler-alist (unless top file-name-handler-alist))
(localname (tramp-compat-file-local-name name)))
(localname (file-local-name name)))
(when (tramp-compat-file-name-quoted-p localname top)
(setq
localname (if (= (length localname) 2) "/" (substring localname 2))))
@ -288,8 +164,7 @@ A nil value for either argument stands for the current time."
;; `progress-reporter-update' got argument SUFFIX in Emacs 27.1.
(defalias 'tramp-compat-progress-reporter-update
(if (equal (tramp-compat-funcall 'func-arity #'progress-reporter-update)
'(1 . 3))
(if (equal (func-arity #'progress-reporter-update) '(1 . 3))
#'progress-reporter-update
(lambda (reporter &optional value _suffix)
(progress-reporter-update reporter value))))
@ -306,19 +181,19 @@ CONDITION can also be a list of error conditions."
;; `file-modes', `set-file-modes' and `set-file-times' got argument
;; FLAG in Emacs 28.1.
(defalias 'tramp-compat-file-modes
(if (equal (tramp-compat-funcall 'func-arity #'file-modes) '(1 . 2))
(if (equal (func-arity #'file-modes) '(1 . 2))
#'file-modes
(lambda (filename &optional _flag)
(file-modes filename))))
(defalias 'tramp-compat-set-file-modes
(if (equal (tramp-compat-funcall 'func-arity #'set-file-modes) '(2 . 3))
(if (equal (func-arity #'set-file-modes) '(2 . 3))
#'set-file-modes
(lambda (filename mode &optional _flag)
(set-file-modes filename mode))))
(defalias 'tramp-compat-set-file-times
(if (equal (tramp-compat-funcall 'func-arity #'set-file-times) '(1 . 3))
(if (equal (func-arity #'set-file-times) '(1 . 3))
#'set-file-times
(lambda (filename &optional timestamp _flag)
(set-file-times filename timestamp))))
@ -326,14 +201,13 @@ CONDITION can also be a list of error conditions."
;; `directory-files' and `directory-files-and-attributes' got argument
;; COUNT in Emacs 28.1.
(defalias 'tramp-compat-directory-files
(if (equal (tramp-compat-funcall 'func-arity #'directory-files) '(1 . 5))
(if (equal (func-arity #'directory-files) '(1 . 5))
#'directory-files
(lambda (directory &optional full match nosort _count)
(directory-files directory full match nosort))))
(defalias 'tramp-compat-directory-files-and-attributes
(if (equal (tramp-compat-funcall 'func-arity #'directory-files-and-attributes)
'(1 . 6))
(if (equal (func-arity #'directory-files-and-attributes) '(1 . 6))
#'directory-files-and-attributes
(lambda (directory &optional full match nosort id-format _count)
(directory-files-and-attributes directory full match nosort id-format))))
@ -410,8 +284,6 @@ CONDITION can also be a list of error conditions."
;;; TODO:
;;
;; * `func-arity' exists since Emacs 26.1.
;;
;; * Starting with Emacs 27.1, there's no need to escape open
;; parentheses with a backslash in docstrings anymore.
;;

View file

@ -169,6 +169,7 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
(directory-files . tramp-crypt-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . ignore)
@ -293,8 +294,9 @@ arguments to pass to the OPERATION."
(defun tramp-crypt-config-file-name (vec)
"Return the encfs config file name for VEC."
(locate-user-emacs-file
(concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config)))
(expand-file-name
(locate-user-emacs-file
(concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config))))
(defun tramp-crypt-maybe-open-connection (vec)
"Maybe open a connection VEC.
@ -595,7 +597,7 @@ absolute file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -697,7 +699,7 @@ absolute file names."
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(let* (tramp-crypt-enabled

View file

@ -48,7 +48,7 @@
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(with-parsed-tramp-file-name directory nil
@ -107,12 +107,6 @@
(unless (string-match-p elt item) (throw 'match nil)))
(setq result (cons (concat item "/") result))))))))))
(defun tramp-fuse-handle-file-readable-p (filename)
"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"
(file-readable-p (tramp-fuse-local-file-name filename)))))
;; This function isn't used.
(defun tramp-fuse-handle-insert-directory
(filename switches &optional wildcard full-directory-p)

View file

@ -122,10 +122,7 @@
(autoload 'zeroconf-init "zeroconf")
(tramp-compat-funcall 'dbus-get-unique-name :system)
(tramp-compat-funcall 'dbus-get-unique-name :session)
(or ;; Until Emacs 25, `process-attributes' could crash Emacs
;; for some processes. Better we don't check.
(<= emacs-major-version 25)
(tramp-process-running-p "gvfs-fuse-daemon")
(or (tramp-process-running-p "gvfs-fuse-daemon")
(tramp-process-running-p "gvfsd-fuse"))))
"Non-nil when GVFS is available.")
@ -471,8 +468,7 @@ It has been changed in GVFS 1.14.")
;; </method>
;; </interface>
;; The basic structure for GNOME Online Accounts. We use a list :type,
;; in order to be compatible with Emacs 25.
;; The basic structure for GNOME Online Accounts.
(cl-defstruct (tramp-goa-account (:type list) :named) method user host port)
;;;###tramp-autoload
@ -672,8 +668,7 @@ It has been changed in GVFS 1.14.")
;; STRING key (always-call-mount, is-removable, ...)
;; VARIANT value (boolean?)
;; The basic structure for media devices. We use a list :type, in
;; order to be compatible with Emacs 25.
;; The basic structure for media devices.
(cl-defstruct (tramp-media-device (:type list) :named) method host port)
;; "gvfs-<command>" utilities have been deprecated in GVFS 1.31.1. We
@ -761,6 +756,7 @@ It has been changed in GVFS 1.14.")
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . ignore)
@ -1001,7 +997,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -1101,8 +1097,7 @@ file names."
(tramp-skeleton-delete-directory directory recursive trash
(if (and recursive (not (file-symlink-p directory)))
(mapc (lambda (file)
(if (eq t (tramp-compat-file-attribute-type
(file-attributes file)))
(if (eq t (file-attribute-type (file-attributes file)))
(delete-directory file recursive)
(delete-file file)))
(directory-files
@ -1613,9 +1608,8 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-get-connection-property
(tramp-get-process vec) "share"
(tramp-get-connection-property vec "default-location" nil))))
(tramp-compat-file-attribute-user-id
(file-attributes
(tramp-make-tramp-file-name vec localname) id-format)))))
(file-attribute-user-id
(file-attributes (tramp-make-tramp-file-name vec localname) id-format)))))
(defun tramp-gvfs-handle-get-remote-gid (vec id-format)
"The gid of the remote connection VEC, in ID-FORMAT.
@ -1624,9 +1618,8 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-get-connection-property
(tramp-get-process vec) "share"
(tramp-get-connection-property vec "default-location" nil))))
(tramp-compat-file-attribute-group-id
(file-attributes
(tramp-make-tramp-file-name vec localname) id-format))))
(file-attribute-group-id
(file-attributes (tramp-make-tramp-file-name vec localname) id-format))))
(defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
@ -1864,9 +1857,9 @@ Their full names are \"org.gtk.vfs.MountTracker.mounted\" and
host (tramp-file-name-host v)
port (tramp-file-name-port v)))))
(when (member method tramp-gvfs-methods)
(let ((v (make-tramp-file-name
:method method :user user :domain domain
:host host :port port)))
(let ((v (make-tramp-file-name
:method method :user user :domain domain
:host host :port port)))
(tramp-message
v 6 "%s %s"
signal-name (tramp-gvfs-stringify-dbus-message mount-info))

View file

@ -85,13 +85,6 @@ special handling of `substitute-in-file-name'."
"An overlay covering the shadowed part of the filename."
(format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
;; Package rfn-eshadow is preloaded in Emacs, but for some reason,
;; it only did (defvar rfn-eshadow-overlay) without giving it a global
;; value, so it was only declared as dynamically-scoped within the
;; rfn-eshadow.el file. This is now fixed in Emacs>26.1 but we still need
;; this defvar here for older releases.
(defvar rfn-eshadow-overlay)
(defun tramp-rfn-eshadow-update-overlay ()
"Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
This is intended to be used as a minibuffer `post-command-hook' for
@ -281,22 +274,18 @@ NAME must be equal to `tramp-current-connection'."
(remove-hook 'compilation-start-hook
#'tramp-compile-disable-ssh-controlmaster-options))))
;;; Default connection-local variables for Tramp:
;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exists since Emacs 26.1.
;;; Default connection-local variables for Tramp.
(defconst tramp-connection-local-default-system-variables
'((path-separator . ":")
(null-device . "/dev/null"))
"Default connection-local system variables for remote connections.")
(tramp-compat-funcall
'connection-local-set-profile-variables
(connection-local-set-profile-variables
'tramp-connection-local-default-system-profile
tramp-connection-local-default-system-variables)
(tramp-compat-funcall
'connection-local-set-profiles
(connection-local-set-profiles
'(:application tramp)
'tramp-connection-local-default-system-profile)
@ -305,14 +294,12 @@ NAME must be equal to `tramp-current-connection'."
(shell-command-switch . "-c"))
"Default connection-local shell variables for remote connections.")
(tramp-compat-funcall
'connection-local-set-profile-variables
(connection-local-set-profile-variables
'tramp-connection-local-default-shell-profile
tramp-connection-local-default-shell-variables)
(with-eval-after-load 'shell
(tramp-compat-funcall
'connection-local-set-profiles
(connection-local-set-profiles
'(:application tramp)
'tramp-connection-local-default-shell-profile))

View file

@ -83,6 +83,7 @@
(directory-files . tramp-fuse-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . ignore)
@ -110,7 +111,7 @@
(file-notify-rm-watch . ignore)
(file-notify-valid-p . ignore)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-fuse-handle-file-readable-p)
(file-readable-p . tramp-rclone-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)
@ -222,7 +223,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -279,6 +280,12 @@ file names."
(list filename newname ok-if-already-exists keep-date
preserve-uid-gid preserve-extended-attributes))))
(defun tramp-rclone-handle-file-readable-p (filename)
"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"
(file-readable-p (tramp-fuse-local-file-name filename)))))
(defun tramp-rclone-handle-file-system-info (filename)
"Like `file-system-info' for Tramp files."
(ignore-errors

View file

@ -952,6 +952,7 @@ Format specifiers \"%s\" are replaced before the script is used.")
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-sh-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . tramp-sh-handle-dired-compress-file)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . tramp-sh-handle-exec-path)
@ -1334,7 +1335,7 @@ component is used as the target of the symlink."
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
(modtime (or (tramp-compat-file-attribute-modification-time attr)
(modtime (or (file-attribute-modification-time attr)
tramp-time-doesnt-exist)))
(setq coding-system-used last-coding-system-used)
(if (not (tramp-compat-time-equal-p modtime tramp-time-dont-know))
@ -1372,7 +1373,7 @@ of."
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
(modtime (tramp-compat-file-attribute-modification-time attr))
(modtime (file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
@ -1620,14 +1621,14 @@ ID-FORMAT valid values are `string' and `integer'."
;; information would be lost by an (attempted) delete and create.
(or (null attributes)
(and
(= (tramp-compat-file-attribute-user-id attributes)
(= (file-attribute-user-id attributes)
(tramp-get-remote-uid v 'integer))
(or (not group)
;; On BSD-derived systems files always inherit the
;; parent directory's group, so skip the group-gid
;; test.
(tramp-check-remote-uname v "BSD\\|DragonFly\\|Darwin")
(= (tramp-compat-file-attribute-group-id attributes)
(= (file-attribute-group-id attributes)
(tramp-get-remote-gid v 'integer)))))))))
;; Directory listings.
@ -1637,8 +1638,7 @@ ID-FORMAT valid values are `string' and `integer'."
"Like `directory-files-and-attributes' for Tramp files."
(unless id-format (setq id-format 'integer))
(unless (file-exists-p directory)
(tramp-compat-file-missing
(tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (expand-file-name directory))
(let* ((temp
@ -1858,7 +1858,7 @@ ID-FORMAT valid values are `string' and `integer'."
target)
(with-parsed-tramp-file-name (if t1 dirname newname) nil
(unless (file-exists-p dirname)
(tramp-compat-file-missing v dirname))
(tramp-error v 'file-missing dirname))
;; `copy-directory-create-symlink' exists since Emacs 28.1.
(if (and (bound-and-true-p copy-directory-create-symlink)
@ -1952,7 +1952,7 @@ file names."
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
(length (tramp-compat-file-attribute-size
(length (file-attribute-size
(file-attributes (file-truename filename))))
(attributes (and preserve-extended-attributes
(file-extended-attributes filename)))
@ -1960,7 +1960,7 @@ file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -2052,7 +2052,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
;; Check, whether file is too large. Emacs checks in `insert-file-1'
;; and `find-file-noselect', but that's not called here.
(abort-if-file-too-large
(tramp-compat-file-attribute-size (file-attributes (file-truename filename)))
(file-attribute-size (file-attributes (file-truename filename)))
(symbol-name op) filename)
;; We must disable multibyte, because binary data shall not be
;; converted. We don't want the target file to be compressed, so we
@ -2074,8 +2074,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
(when keep-date
(tramp-compat-set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))
(file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))
;; Set the mode.
(set-file-modes newname (tramp-default-file-modes filename))
@ -2094,7 +2093,7 @@ as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
the uid and gid from FILENAME."
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
(file-times (tramp-compat-file-attribute-modification-time
(file-times (file-attribute-modification-time
(file-attributes filename)))
(file-modes (tramp-default-file-modes filename)))
(with-parsed-tramp-file-name (if t1 filename newname) nil
@ -2419,8 +2418,7 @@ The method used must be an out-of-band method."
(when (and keep-date (not copy-keep-date))
(tramp-compat-set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))
(file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))
;; Set the mode.
@ -2474,6 +2472,7 @@ The method used must be an out-of-band method."
;; Dired.
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(defun tramp-sh-handle-dired-compress-file (file)
"Like `dired-compress-file' for Tramp files."
;; Code stolen mainly from dired-aux.el.
@ -3199,9 +3198,9 @@ implementation will be used."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p (file-truename filename))
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(let* ((size (tramp-compat-file-attribute-size
(let* ((size (file-attribute-size
(file-attributes (file-truename filename))))
(rem-enc (tramp-get-inline-coding v "remote-encoding" size))
(loc-dec (tramp-get-inline-coding v "local-decoding" size))
@ -3288,11 +3287,9 @@ implementation will be used."
(tramp-error v 'file-already-exists filename))
(let ((file-locked (eq (file-locked-p lockname) t))
(uid (or (tramp-compat-file-attribute-user-id
(file-attributes filename 'integer))
(uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
(gid (or (tramp-compat-file-attribute-group-id
(file-attributes filename 'integer))
(gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
;; Lock file.
@ -3371,8 +3368,7 @@ implementation will be used."
;; specified. However, if the method _also_ specifies an
;; encoding function, then that is used for encoding the
;; contents of the tmp file.
(let* ((size (tramp-compat-file-attribute-size
(file-attributes tmpfile)))
(let* ((size (file-attribute-size (file-attributes tmpfile)))
(rem-dec (tramp-get-inline-coding v "remote-decoding" size))
(loc-enc (tramp-get-inline-coding v "local-encoding" size)))
(cond
@ -3507,10 +3503,10 @@ implementation will be used."
;; We must pass modtime explicitly, because FILENAME can
;; be different from (buffer-file-name), f.e. if
;; `file-precious-flag' is set.
(or (tramp-compat-file-attribute-modification-time file-attr)
(or (file-attribute-modification-time file-attr)
(current-time)))
(when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
(= (tramp-compat-file-attribute-group-id file-attr) gid))
(when (and (= (file-attribute-user-id file-attr) uid)
(= (file-attribute-group-id file-attr) gid))
(setq need-chown nil))))
;; Set the ownership.

View file

@ -234,6 +234,7 @@ See `tramp-actions-before-shell' for more info.")
(directory-files . tramp-smb-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . ignore)
@ -418,7 +419,7 @@ arguments to pass to the OPERATION."
target)
(with-parsed-tramp-file-name (if t1 dirname newname) nil
(unless (file-exists-p dirname)
(tramp-compat-file-missing v dirname))
(tramp-error v 'file-missing dirname))
;; `copy-directory-create-symlink' exists since Emacs 28.1.
(if (and (bound-and-true-p copy-directory-create-symlink)
@ -441,7 +442,7 @@ arguments to pass to the OPERATION."
(with-tramp-progress-reporter
v 0 (format "Copying %s to %s" dirname newname)
(unless (file-exists-p dirname)
(tramp-compat-file-missing v dirname))
(tramp-error v 'file-missing dirname))
(when (and (file-directory-p newname)
(not (directory-name-p newname)))
(tramp-error v 'file-already-exists newname))
@ -566,8 +567,7 @@ arguments to pass to the OPERATION."
(when keep-date
(tramp-compat-set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes dirname))
(file-attribute-modification-time (file-attributes dirname))
(unless ok-if-already-exists 'nofollow)))
;; Set the mode.
@ -601,10 +601,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(copy-directory filename newname keep-date 'parents 'copy-contents)
(unless (file-exists-p filename)
(tramp-compat-file-missing
(tramp-error
(tramp-dissect-file-name
(if (tramp-tramp-file-p filename) filename newname))
filename))
'file-missing filename))
(if-let ((tmpfile (file-local-copy filename)))
;; Remote filename.
@ -644,8 +644,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(when keep-date
(tramp-compat-set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))
(file-attribute-modification-time (file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-smb-handle-delete-directory (directory &optional recursive trash)
@ -705,7 +704,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(let ((result (mapcar #'directory-file-name
(file-name-all-completions "" directory))))
;; Discriminate with regexp.
@ -975,7 +974,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name (file-truename filename) nil
(unless (file-exists-p (file-truename filename))
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(with-tramp-progress-reporter
v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@ -1040,8 +1039,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
"Like `file-writable-p' for Tramp files."
(if (file-exists-p filename)
(tramp-compat-string-search
"w"
(or (tramp-compat-file-attribute-modes (file-attributes filename)) ""))
"w" (or (file-attribute-modes (file-attributes filename)) ""))
(let ((dir (file-name-directory filename)))
(and (file-exists-p dir)
(file-writable-p dir)))))
@ -1144,11 +1142,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(insert
(format
"%10s %3d %-8s %-8s %8s %s "
(or (tramp-compat-file-attribute-modes attr) (nth 1 x))
(or (tramp-compat-file-attribute-link-number attr) 1)
(or (tramp-compat-file-attribute-user-id attr) "nobody")
(or (tramp-compat-file-attribute-group-id attr) "nogroup")
(or (tramp-compat-file-attribute-size attr) (nth 2 x))
(or (file-attribute-modes attr) (nth 1 x))
(or (file-attribute-link-number attr) 1)
(or (file-attribute-user-id attr) "nobody")
(or (file-attribute-group-id attr) "nogroup")
(or (file-attribute-size attr) (nth 2 x))
(format-time-string
(if (time-less-p
;; Half a year.
@ -1170,8 +1168,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; Insert symlink.
(when (and (tramp-compat-string-search "l" switches)
(stringp (tramp-compat-file-attribute-type attr)))
(insert " -> " (tramp-compat-file-attribute-type attr))))
(stringp (file-attribute-type attr)))
(insert " -> " (file-attribute-type attr))))
(insert "\n")
(beginning-of-line)))
@ -1393,7 +1391,7 @@ component is used as the target of the symlink."
(with-parsed-tramp-file-name
(if (tramp-tramp-file-p filename) filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -1646,8 +1644,7 @@ errors for shares like \"C$/\", which are common in Microsoft Windows."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
(or (tramp-compat-file-attribute-modification-time
(file-attributes filename))
(or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Unlock file.

View file

@ -83,6 +83,7 @@
(directory-files . tramp-fuse-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . tramp-sshfs-handle-exec-path)
@ -110,7 +111,7 @@
(file-notify-rm-watch . ignore)
(file-notify-valid-p . ignore)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-fuse-handle-file-readable-p)
(file-readable-p . tramp-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
(file-remote-p . tramp-handle-file-remote-p)
(file-selinux-context . tramp-handle-file-selinux-context)

View file

@ -75,6 +75,7 @@ See `tramp-actions-before-shell' for more info.")
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-handle-directory-files-and-attributes)
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(dired-compress-file . ignore)
(dired-uncache . tramp-handle-dired-uncache)
(exec-path . ignore)
@ -232,7 +233,7 @@ absolute file names."
(let ((t1 (tramp-sudoedit-file-name-p filename))
(t2 (tramp-sudoedit-file-name-p newname))
(file-times (tramp-compat-file-attribute-modification-time
(file-times (file-attribute-modification-time
(file-attributes filename)))
(file-modes (tramp-default-file-modes filename))
(attributes (and preserve-extended-attributes
@ -246,7 +247,7 @@ absolute file names."
(with-parsed-tramp-file-name (if t1 filename newname) nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(when (and (not ok-if-already-exists) (file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(when (and (file-directory-p newname)
@ -720,11 +721,9 @@ ID-FORMAT valid values are `string' and `integer'."
"Like `write-region' for Tramp files."
(setq filename (expand-file-name filename))
(with-parsed-tramp-file-name filename nil
(let* ((uid (or (tramp-compat-file-attribute-user-id
(file-attributes filename 'integer))
(let* ((uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
(gid (or (tramp-compat-file-attribute-group-id
(file-attributes filename 'integer))
(gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer)))
(flag (and (eq mustbenew 'excl) 'nofollow))
(modes (tramp-default-file-modes filename flag))
@ -735,10 +734,10 @@ ID-FORMAT valid values are `string' and `integer'."
;; Set the ownership, modes and extended attributes. This is
;; not performed in `tramp-handle-write-region'.
(unless (and (= (tramp-compat-file-attribute-user-id
(unless (and (= (file-attribute-user-id
(file-attributes filename 'integer))
uid)
(= (tramp-compat-file-attribute-group-id
(= (file-attribute-group-id
(file-attributes filename 'integer))
gid))
(tramp-set-file-uid-gid filename uid gid))

View file

@ -751,11 +751,11 @@ The answer will be provided by `tramp-action-process-alive',
(defconst tramp-temp-name-prefix "tramp."
"Prefix to use for temporary files.
If this is a relative file name (such as \"tramp.\"), it is considered
relative to the directory name returned by the function
`tramp-compat-temporary-file-directory' (which see). It may also be an
absolute file name; don't forget to include a prefix for the filename
part, though.")
If this is a relative file name (such as \"tramp.\"), it is
considered relative to the directory name returned by the
function `temporary-file-directory' (which see). It may also be
an absolute file name; don't forget to include a prefix for the
filename part, though.")
(defconst tramp-temp-buffer-name " *tramp temp*"
"Buffer name for a temporary buffer.
@ -822,11 +822,10 @@ to be set, depending on VALUE."
(tramp-register-file-name-handlers))
;; Initialize the Tramp syntax variables. We want to override initial
;; value of `tramp-file-name-regexp'. Other Tramp syntax variables
;; must be initialized as well to proper values. We do not call
;; value of `tramp-file-name-regexp'. We do not call
;; `custom-set-variable', this would load Tramp via custom.el.
(tramp--with-startup
(tramp-set-syntax 'tramp-syntax (tramp-compat-tramp-syntax)))
(tramp-set-syntax 'tramp-syntax tramp-syntax))
(defun tramp-syntax-values ()
"Return possible values of `tramp-syntax', a list."
@ -836,9 +835,9 @@ to be set, depending on VALUE."
values))
(defun tramp-lookup-syntax (alist)
"Look up a syntax string in ALIST according to `tramp-compat-tramp-syntax'.
Raise an error if `tramp-syntax' is invalid."
(or (cdr (assq (tramp-compat-tramp-syntax) alist))
"Look up a syntax string in ALIST according to `tramp-syntax'.
Raise an error if it is invalid."
(or (cdr (assq tramp-syntax alist))
(error "Wrong `tramp-syntax' %s" tramp-syntax)))
(defconst tramp-prefix-format-alist
@ -1409,8 +1408,7 @@ calling HANDLER.")
;; internal data structure. Convenience functions for internal
;; data structure.
;; The basic structure for remote file names. We use a list :type,
;; in order to be compatible with Emacs 25.
;; The basic structure for remote file names.
(cl-defstruct (tramp-file-name (:type list) :named)
method user domain host port localname hop)
@ -1522,7 +1520,7 @@ of `process-file', `start-file-process', or `shell-command'."
(or (and (tramp-tramp-file-p name)
(string-match (nth 0 tramp-file-name-structure) name)
(match-string (nth 4 tramp-file-name-structure) name))
(tramp-compat-file-local-name name)))
(file-local-name name)))
;; The localname can be quoted with "/:". Extract this.
(defun tramp-unquote-file-local-name (name)
@ -1849,9 +1847,7 @@ from the default one."
If connection-local variables are not supported by this Emacs
version, the function does nothing."
(with-current-buffer (tramp-get-connection-buffer vec)
;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
(tramp-compat-funcall
'hack-connection-local-variables-apply
(hack-connection-local-variables-apply
`(:application tramp
:protocol ,(tramp-file-name-method vec)
:user ,(tramp-file-name-user-domain vec)
@ -1862,9 +1858,7 @@ version, the function does nothing."
If connection-local variables are not supported by this Emacs
version, the function does nothing."
(when (tramp-tramp-file-p default-directory)
;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
(tramp-compat-funcall
'hack-connection-local-variables-apply
(hack-connection-local-variables-apply
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
@ -2482,35 +2476,34 @@ Must be handled by the callers."
'(access-file byte-compiler-base-file-name delete-directory
delete-file diff-latest-backup-file directory-file-name
directory-files directory-files-and-attributes
dired-compress-file dired-uncache file-acl
file-accessible-directory-p file-attributes
file-directory-p file-executable-p file-exists-p
file-local-copy file-modes file-name-as-directory
dired-uncache file-acl file-accessible-directory-p
file-attributes file-directory-p file-executable-p
file-exists-p file-local-copy file-modes
file-name-as-directory file-name-case-insensitive-p
file-name-directory file-name-nondirectory
file-name-sans-versions file-notify-add-watch
file-ownership-preserved-p file-readable-p
file-regular-p file-remote-p file-selinux-context
file-symlink-p file-truename file-writable-p
find-backup-file-name get-file-buffer
insert-directory insert-file-contents load
make-directory make-directory-internal set-file-acl
set-file-modes set-file-selinux-context set-file-times
find-backup-file-name get-file-buffer insert-directory
insert-file-contents load make-directory
make-directory-internal set-file-acl set-file-modes
set-file-selinux-context set-file-times
substitute-in-file-name unhandled-file-name-directory
vc-registered
;; Emacs 26+ only.
file-name-case-insensitive-p
;; Emacs 27+ only.
file-system-info
;; Emacs 28+ only.
file-locked-p lock-file make-lock-file-name unlock-file
;; Starting with Emacs 29.1, `dired-compress-file' isn't
;; magic anymore.
dired-compress-file
;; Tramp internal magic file name function.
tramp-set-file-uid-gid))
(if (file-name-absolute-p (nth 0 args))
(nth 0 args)
default-directory))
;; STRING FILE.
;; Starting with Emacs 26.1, just the 2nd argument of
;; `make-symbolic-link' matters.
((eq operation 'make-symbolic-link) (nth 1 args))
;; FILE DIRECTORY resp FILE1 FILE2.
((member operation
@ -2541,9 +2534,8 @@ Must be handled by the callers."
(if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
;; COMMAND.
((member operation
'(process-file shell-command start-file-process
;; Emacs 26+ only.
make-nearby-temp-file temporary-file-directory
'(make-nearby-temp-file process-file shell-command
start-file-process temporary-file-directory
;; Emacs 27+ only.
exec-path make-process))
default-directory)
@ -3298,8 +3290,9 @@ User is always nil."
filename)
(tramp-error
v 'file-error (format "%s: Permission denied, %s" string filename)))
(tramp-compat-file-missing
v (format "%s: No such file or directory, %s" string filename)))))
(tramp-error
v 'file-missing
(format "%s: No such file or directory, %s" string filename)))))
(defun tramp-handle-add-name-to-file
(filename newname &optional ok-if-already-exists)
@ -3333,7 +3326,7 @@ User is always nil."
;; `copy-directory' creates NEWNAME before running this check. So
;; we do it ourselves.
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
;; We must do it file-wise.
(tramp-run-real-handler
#'copy-directory
@ -3354,7 +3347,7 @@ User is always nil."
(defun tramp-handle-directory-files (directory &optional full match nosort count)
"Like `directory-files' for Tramp files."
(unless (file-exists-p directory)
(tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
(tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
(when (file-directory-p directory)
(setq directory (file-name-as-directory (expand-file-name directory)))
(let ((temp (nreverse (file-name-all-completions "" directory)))
@ -3420,9 +3413,7 @@ User is always nil."
(defun tramp-handle-file-directory-p (filename)
"Like `file-directory-p' for Tramp files."
(eq (tramp-compat-file-attribute-type
(file-attributes (file-truename filename)))
t))
(eq (file-attribute-type (file-attributes (file-truename filename))) t))
(defun tramp-handle-file-equal-p (filename1 filename2)
"Like `file-equalp-p' for Tramp files."
@ -3454,7 +3445,7 @@ User is always nil."
"Like `file-local-copy' for Tramp files."
(with-parsed-tramp-file-name filename nil
(unless (file-exists-p filename)
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(let ((tmpfile (tramp-compat-make-temp-file filename)))
(copy-file filename tmpfile 'ok-if-already-exists 'keep-time)
tmpfile)))
@ -3462,7 +3453,7 @@ User is always nil."
(defun tramp-handle-file-modes (filename &optional flag)
"Like `file-modes' for Tramp files."
(when-let ((attrs (file-attributes filename))
(mode-string (tramp-compat-file-attribute-modes attrs)))
(mode-string (file-attribute-modes attrs)))
(if (and (not (eq flag 'nofollow)) (eq ?l (aref mode-string 0)))
(file-modes (file-truename filename))
(tramp-mode-string-to-int mode-string))))
@ -3515,16 +3506,13 @@ User is always nil."
(directory-file-name
(file-name-directory candidate))))
;; Nothing found, so we must use a temporary file
;; for comparison. `make-nearby-temp-file' is added
;; to Emacs 26+ like `file-name-case-insensitive-p',
;; so there is no compatibility problem calling it.
;; for comparison.
(unless (string-match-p
"[[:lower:]]" (tramp-file-local-name candidate))
(setq tmpfile
(let ((default-directory
(file-name-directory filename)))
(tramp-compat-funcall
'make-nearby-temp-file "tramp."))
(file-name-directory filename)))
(make-nearby-temp-file "tramp."))
candidate tmpfile))
;; Check for the existence of the same file with
;; upper case letters.
@ -3585,9 +3573,8 @@ User is always nil."
((not (file-exists-p file1)) nil)
((not (file-exists-p file2)) t)
(t (time-less-p
(tramp-compat-file-attribute-modification-time (file-attributes file2))
(tramp-compat-file-attribute-modification-time
(file-attributes file1))))))
(file-attribute-modification-time (file-attributes file2))
(file-attribute-modification-time (file-attributes file1))))))
(defun tramp-handle-file-readable-p (filename)
"Like `file-readable-p' for Tramp files."
@ -3606,7 +3593,7 @@ User is always nil."
;; Sometimes, `file-attributes' does not return a proper value
;; even if `file-exists-p' does.
(when-let ((attr (file-attributes filename)))
(eq ?- (aref (tramp-compat-file-attribute-modes attr) 0)))))
(eq ?- (aref (file-attribute-modes attr) 0)))))
(defun tramp-handle-file-remote-p (filename &optional identification connected)
"Like `file-remote-p' for Tramp files."
@ -3638,7 +3625,7 @@ User is always nil."
(defun tramp-handle-file-symlink-p (filename)
"Like `file-symlink-p' for Tramp files."
(let ((x (tramp-compat-file-attribute-type (file-attributes filename))))
(let ((x (file-attribute-type (file-attributes filename))))
(and (stringp x) x)))
(defun tramp-handle-file-truename (filename)
@ -3727,7 +3714,7 @@ User is always nil."
(when (and (not tramp-allow-unsafe-temporary-files)
(not backup-inhibited)
(file-in-directory-p (car result) temporary-file-directory)
(zerop (or (tramp-compat-file-attribute-user-id
(zerop (or (file-attribute-user-id
(file-attributes filename 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@ -3784,7 +3771,7 @@ User is always nil."
(unwind-protect
(if (not (file-exists-p filename))
(let ((tramp-verbose (if visit 0 tramp-verbose)))
(tramp-compat-file-missing v filename))
(tramp-error v 'file-missing filename))
(with-tramp-progress-reporter
v 3 (format-message "Inserting `%s'" filename)
@ -3949,7 +3936,7 @@ Return nil when there is no lockfile."
(when (and (not tramp-allow-unsafe-temporary-files)
create-lockfiles
(file-in-directory-p lockname temporary-file-directory)
(zerop (or (tramp-compat-file-attribute-user-id
(zerop (or (file-attribute-user-id
(file-attributes file 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@ -4001,7 +3988,7 @@ Return nil when there is no lockfile."
v 'file-error
"File `%s' does not include a `.el' or `.elc' suffix" file)))
(unless (or noerror (file-exists-p file))
(tramp-compat-file-missing v file))
(tramp-error v 'file-missing file))
(if (not (file-exists-p file))
nil
(let ((signal-hook-function (unless noerror signal-hook-function))
@ -4263,18 +4250,13 @@ substitution. SPEC-LIST is a list of char/value pairs used for
p))))))
(defun tramp-handle-make-symbolic-link
(target linkname &optional ok-if-already-exists)
(_target linkname &optional _ok-if-already-exists)
"Like `make-symbolic-link' for Tramp files.
This is the fallback implementation for backends which do not
support symbolic links."
(if (tramp-tramp-file-p (expand-file-name linkname))
(tramp-error
(tramp-dissect-file-name (expand-file-name linkname)) 'file-error
"make-symbolic-link not supported")
;; This is needed prior Emacs 26.1, where TARGET has also be
;; checked for a file name handler.
(tramp-run-real-handler
#'make-symbolic-link (list target linkname ok-if-already-exists))))
(tramp-error
(tramp-dissect-file-name (expand-file-name linkname)) 'file-error
"make-symbolic-link not supported"))
(defun tramp-handle-shell-command (command &optional output-buffer error-buffer)
"Like `shell-command' for Tramp files."
@ -4492,7 +4474,7 @@ BUFFER might be a list, in this case STDERR is separated."
(unless time-list
(let ((remote-file-name-inhibit-cache t))
(setq time-list
(or (tramp-compat-file-attribute-modification-time
(or (file-attribute-modification-time
(file-attributes (buffer-file-name)))
tramp-time-doesnt-exist))))
(unless (tramp-compat-time-equal-p time-list tramp-time-dont-know)
@ -4516,7 +4498,7 @@ of."
t
(let* ((remote-file-name-inhibit-cache t)
(attr (file-attributes f))
(modtime (tramp-compat-file-attribute-modification-time attr))
(modtime (file-attribute-modification-time attr))
(mt (visited-file-modtime)))
(cond
@ -4547,11 +4529,9 @@ of."
(tmpfile (tramp-compat-make-temp-file filename))
(modes (tramp-default-file-modes
filename (and (eq mustbenew 'excl) 'nofollow)))
(uid (or (tramp-compat-file-attribute-user-id
(file-attributes filename 'integer))
(uid (or (file-attribute-user-id (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
(gid (or (tramp-compat-file-attribute-group-id
(file-attributes filename 'integer))
(gid (or (file-attribute-group-id (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
;; Lock file.
@ -4587,8 +4567,7 @@ of."
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
(set-visited-file-modtime
(or (tramp-compat-file-attribute-modification-time
(file-attributes filename))
(or (file-attribute-modification-time (file-attributes filename))
(current-time))))
;; Set the ownership.
@ -5255,7 +5234,7 @@ If FILENAME is remote, a file name handler is called."
(let* ((dir (file-name-directory filename))
(modes (file-modes dir)))
(when (and modes (not (zerop (logand modes #o2000))))
(setq gid (tramp-compat-file-attribute-group-id (file-attributes dir)))))
(setq gid (file-attribute-group-id (file-attributes dir)))))
(if-let ((handler (find-file-name-handler filename 'tramp-set-file-uid-gid)))
(funcall handler #'tramp-set-file-uid-gid filename uid gid)
@ -5284,8 +5263,7 @@ ID-FORMAT valid values are `string' and `integer'."
;; `group-name' has been introduced with Emacs 27.1.
((and (fboundp 'group-name) (equal id-format 'string))
(tramp-compat-funcall 'group-name (group-gid)))
((tramp-compat-file-attribute-group-id
(file-attributes "~/" id-format))))))
((file-attribute-group-id (file-attributes "~/" id-format))))))
(defun tramp-get-local-locale (&optional vec)
"Determine locale, supporting UTF8 if possible.
@ -5340,31 +5318,22 @@ be granted."
file-attr
(or
;; Not a symlink.
(eq t (tramp-compat-file-attribute-type file-attr))
(null (tramp-compat-file-attribute-type file-attr)))
(eq t (file-attribute-type file-attr))
(null (file-attribute-type file-attr)))
(or
;; World accessible.
(eq access
(aref (tramp-compat-file-attribute-modes file-attr)
(+ offset 6)))
(eq access (aref (file-attribute-modes file-attr) (+ offset 6)))
;; User accessible and owned by user.
(and
(eq access
(aref (tramp-compat-file-attribute-modes file-attr) offset))
(or (equal remote-uid
(tramp-compat-file-attribute-user-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-user-id file-attr))))
(eq access (aref (file-attribute-modes file-attr) offset))
(or (equal remote-uid (file-attribute-user-id file-attr))
(equal unknown-id (file-attribute-user-id file-attr))))
;; Group accessible and owned by user's principal group.
(and
(eq access
(aref (tramp-compat-file-attribute-modes file-attr)
(+ offset 3)))
(or (equal remote-gid
(tramp-compat-file-attribute-group-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-group-id
file-attr))))))))))))
(aref (file-attribute-modes file-attr) (+ offset 3)))
(or (equal remote-gid (file-attribute-group-id file-attr))
(equal unknown-id (file-attribute-group-id file-attr))))))))))))
(defun tramp-get-remote-uid (vec id-format)
"The uid of the remote connection VEC, in ID-FORMAT.
@ -5505,7 +5474,7 @@ this file, if that variable is non-nil."
(when (and (not tramp-allow-unsafe-temporary-files)
auto-save-default
(file-in-directory-p result temporary-file-directory)
(zerop (or (tramp-compat-file-attribute-user-id
(zerop (or (file-attribute-user-id
(file-attributes filename 'integer))
tramp-unknown-id-integer))
(not (with-tramp-connection-property
@ -5541,8 +5510,7 @@ ALIST is of the form ((FROM . TO) ...)."
(defun tramp-handle-make-nearby-temp-file (prefix &optional dir-flag suffix)
"Like `make-nearby-temp-file' for Tramp files."
(let ((temporary-file-directory
(tramp-compat-temporary-file-directory-function)))
(let ((temporary-file-directory (temporary-file-directory)))
(make-temp-file prefix dir-flag suffix)))
;;; Compatibility functions section:
@ -5712,15 +5680,12 @@ Invokes `password-read' if available, `read-passwd' else."
(setq auth-passwd (funcall auth-passwd)))
auth-passwd)
;; Try the password cache. Exists since Emacs 26.1.
;; Try the password cache.
(progn
(setq auth-passwd (password-read pw-prompt key)
tramp-password-save-function
(lambda () (password-cache-add key auth-passwd)))
auth-passwd)
;; Else, get the password interactively w/o cache.
(read-passwd pw-prompt))
auth-passwd))
;; Workaround. Prior Emacs 28.1, auth-source has saved
;; empty passwords. See discussion in Bug#50399.
@ -5832,13 +5797,11 @@ name of a process or buffer, or nil to default to the current buffer."
(while (tramp-accept-process-output proc 0))
(not (process-live-p proc))))))
;; `interrupt-process-functions' exists since Emacs 26.1.
(when (boundp 'interrupt-process-functions)
(add-hook 'interrupt-process-functions #'tramp-interrupt-process)
(add-hook
'tramp-unload-hook
(lambda ()
(remove-hook 'interrupt-process-functions #'tramp-interrupt-process))))
(add-hook 'interrupt-process-functions #'tramp-interrupt-process)
(add-hook
'tramp-unload-hook
(lambda ()
(remove-hook 'interrupt-process-functions #'tramp-interrupt-process)))
(defun tramp-get-remote-null-device (vec)
"Return null device on the remote host identified by VEC.

View file

@ -7,8 +7,8 @@
;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
;; Keywords: comm, processes
;; Package: tramp
;; Version: 2.5.2-pre
;; Package-Requires: ((emacs "25.1"))
;; Version: 2.6.0-pre
;; Package-Requires: ((emacs "26.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.5.2-pre"
(defconst tramp-version "2.6.0-pre"
"This version of Tramp.")
;;;###tramp-autoload
@ -74,9 +74,9 @@
"The repository revision of the Tramp sources.")
;; Check for Emacs version.
(let ((x (if (not (string-lessp emacs-version "25.1"))
(let ((x (if (not (string-version-lessp emacs-version "26.1"))
"ok"
(format "Tramp 2.5.2-pre is not fit for %s"
(format "Tramp 2.6.0-pre is not fit for %s"
(replace-regexp-in-string "\n" "" (emacs-version))))))
(unless (string-equal "ok" x) (error "%s" x)))

View file

@ -122,12 +122,6 @@ the origin of the temporary TMPFILE, have no write permissions."
(directory-files tmpfile 'full directory-files-no-dot-files-regexp))
(delete-directory tmpfile)))
(defun tramp-archive--test-emacs26-p ()
"Check for Emacs version >= 26.1.
Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 26))
(defun tramp-archive--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@ -265,21 +259,20 @@ variables, so we check the Emacs version directly."
(concat
(tramp-gvfs-url-file-name
(tramp-make-tramp-file-name
tramp-archive-method
;; User and Domain.
nil nil
;; Host.
(url-hexify-string
(concat
"file://"
;; `directory-file-name' does not leave file
;; archive boundaries. So we must cut the
;; trailing slash ourselves.
(substring
(file-name-directory
(tramp-archive-test-file-archive-hexlified))
0 -1)))
nil "/"))
(make-tramp-file-name
:method tramp-archive-method
:host
(url-hexify-string
(concat
"file://"
;; `directory-file-name' does not leave file
;; archive boundaries. So we must cut the
;; trailing slash ourselves.
(substring
(file-name-directory
(tramp-archive-test-file-archive-hexlified))
0 -1)))
:localname "/")))
(file-name-nondirectory tramp-archive-test-file-archive)))))
(should-not port)
(should (string-equal localname "/bar"))
@ -434,7 +427,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(setq tmp-name
(file-local-copy
(expand-file-name "what" tramp-archive-test-archive)))
:type tramp-file-missing))
:type 'file-missing))
;; Cleanup.
(ignore-errors (tramp-archive--test-delete tmp-name))
@ -462,7 +455,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-file-contents
(expand-file-name "what" tramp-archive-test-archive))
:type tramp-file-missing))
:type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@ -553,11 +546,9 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name4))
;; Target directory does exist already.
;; This has been changed in Emacs 26.1.
(when (tramp-archive--test-emacs26-p)
(should-error
(copy-directory tmp-name1 tmp-name2)
:type 'file-error))
(should-error
(copy-directory tmp-name1 tmp-name2)
:type 'file-error)
(tramp-archive--test-delete tmp-name4)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
@ -622,13 +613,11 @@ This checks also `file-name-as-directory', `file-name-directory',
(append '("LANG=C" "LANGUAGE=C" "LC_ALL=C") process-environment)))
(unwind-protect
(progn
;; Due to Bug#29423, this works only since for Emacs 26.1.
(when nil ;; TODO (tramp-archive--test-emacs26-p)
(with-temp-buffer
(insert-directory tramp-archive-test-archive nil)
(goto-char (point-min))
(should
(looking-at-p (regexp-quote tramp-archive-test-archive)))))
(with-temp-buffer
(insert-directory tramp-archive-test-archive nil)
(goto-char (point-min))
(should
(looking-at-p (regexp-quote tramp-archive-test-archive))))
(with-temp-buffer
(insert-directory tramp-archive-test-archive "-al")
(goto-char (point-min))
@ -656,7 +645,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should-error
(insert-directory
(expand-file-name "baz" tramp-archive-test-archive) nil)
:type tramp-file-missing)))
:type 'file-missing)))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@ -716,7 +705,7 @@ This tests also `access-file', `file-readable-p' and `file-regular-p'."
;; Check error case.
(should-error
(access-file tmp-name4 "error")
:type tramp-file-missing))
:type 'file-missing))
;; Cleanup.
(tramp-archive-cleanup-hash))))
@ -855,38 +844,27 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
;; Cleanup.
(tramp-archive-cleanup-hash))))
;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-archive-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless tramp-archive-enabled)
;; Since Emacs 26.1.
(skip-unless
(and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
;; `make-nearby-temp-file' and `temporary-file-directory' exists
;; since Emacs 26.1. We don't want to see compiler warnings for
;; older Emacsen.
(let ((default-directory tramp-archive-test-archive)
tmp-file)
;; The file archive shall know a temporary file directory. It is
;; not in the archive itself.
(should
(stringp (with-no-warnings (with-no-warnings (temporary-file-directory)))))
(should-not
(tramp-archive-file-name-p (with-no-warnings (temporary-file-directory))))
(should (stringp (temporary-file-directory)))
(should-not (tramp-archive-file-name-p (temporary-file-directory)))
;; A temporary file or directory shall not be located in the
;; archive itself.
(setq tmp-file
(with-no-warnings (make-nearby-temp-file "tramp-archive-test")))
(setq tmp-file (make-nearby-temp-file "tramp-archive-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
(setq tmp-file
(with-no-warnings (make-nearby-temp-file "tramp-archive-test" 'dir)))
(setq tmp-file (make-nearby-temp-file "tramp-archive-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(should-not (tramp-archive-file-name-p tmp-file))
@ -910,7 +888,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(zerop (nth 1 fsi))
(zerop (nth 2 fsi))))))
(ert-deftest tramp-archive-test45-auto-load ()
(ert-deftest tramp-archive-test46-auto-load ()
"Check that `tramp-archive' autoloads properly."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)
@ -950,7 +928,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(mapconcat #'shell-quote-argument load-path " -L ")
(shell-quote-argument (format code file))))))))))
(ert-deftest tramp-archive-test45-delay-load ()
(ert-deftest tramp-archive-test46-delay-load ()
"Check that `tramp-archive' is loaded lazily, only when needed."
:tags '(:expensive-test)
(skip-unless tramp-archive-enabled)

View file

@ -43,8 +43,10 @@
(require 'cl-lib)
(require 'dired)
(require 'dired-aux)
(require 'ert)
(require 'ert-x)
(require 'seq) ; For `seq-random-elt', autoloaded since Emacs 28.1
(require 'trace)
(require 'tramp)
(require 'vc)
@ -62,7 +64,6 @@
(declare-function tramp-list-tramp-buffers "tramp-cmds")
(declare-function tramp-method-out-of-band-p "tramp-sh")
(declare-function tramp-smb-get-localname "tramp-smb")
(declare-function dired-compress "dired-aux")
(defvar ange-ftp-make-backup-files)
(defvar auto-save-file-name-transforms)
(defvar lock-file-name-transforms)
@ -76,11 +77,6 @@
(defvar tramp-remote-path)
(defvar tramp-remote-process-environment)
;; Needed for Emacs 25.
(defvar connection-local-criteria-alist)
(defvar connection-local-profile-alist)
;; Needed for Emacs 26.
(defvar async-shell-command-width)
;; Needed for Emacs 27.
(defvar process-file-return-signal-string)
(defvar shell-command-dont-erase-buffer)
@ -2085,44 +2081,41 @@ Also see `ignore'."
(substitute-in-file-name "/method:host:/:/path//foo")
"/method:host:/:/path//foo"))
;; Forwhatever reasons, the following tests let Emacs crash for
;; Emacs 25, occasionally. No idea what's up.
(when (tramp--test-emacs26-p)
(should
(string-equal
(substitute-in-file-name (concat "/method:host://~" foo))
(concat "/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/~" foo))
(concat "/method:host:/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/path//~" foo))
(concat "/~" foo)))
;; (substitute-in-file-name "/path/~foo") expands only for a local
;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/path/~" foo))
(concat "/method:host:/path/~" foo)))
;; Quoting local part.
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/://~" foo))
(concat "/method:host:/://~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/~" foo))
(concat "/method:host:/:/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/path//~" foo))
(concat "/method:host:/:/path//~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/path/~" foo))
(concat "/method:host:/:/path/~" foo))))
(should
(string-equal
(substitute-in-file-name (concat "/method:host://~" foo))
(concat "/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/~" foo))
(concat "/method:host:/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/path//~" foo))
(concat "/~" foo)))
;; (substitute-in-file-name "/path/~foo") expands only for a local
;; user "foo" to "/~foo"". Otherwise, it doesn't expand.
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/path/~" foo))
(concat "/method:host:/path/~" foo)))
;; Quoting local part.
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/://~" foo))
(concat "/method:host:/://~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/~" foo))
(concat "/method:host:/:/~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/path//~" foo))
(concat "/method:host:/:/path//~" foo)))
(should
(string-equal
(substitute-in-file-name (concat "/method:host:/:/path/~" foo))
(concat "/method:host:/:/path/~" foo)))
(let (process-environment)
(should
@ -2354,7 +2347,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name2)
(should-error
(setq tmp-name2 (file-local-copy tmp-name1))
:type tramp-file-missing))
:type 'file-missing))
;; Cleanup.
(ignore-errors
@ -2393,7 +2386,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name)
(should-error
(insert-file-contents tmp-name)
:type tramp-file-missing))
:type 'file-missing))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@ -2464,23 +2457,20 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (buffer-string) "34")))
;; Check message.
;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
(with-no-warnings (when (symbol-plist 'ert-with-message-capture)
(let (inhibit-message)
(dolist
(noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
(dolist (visit '(nil t "string" no-message))
(ert-with-message-capture tramp--test-messages
(write-region "foo" nil tmp-name nil visit)
;; We must check the last line. There could be
;; other messages from the progress reporter.
(should
(string-match-p
(if (and (null noninteractive)
(or (eq visit t) (null visit) (stringp visit)))
(format "^Wrote %s\n\\'" (regexp-quote tmp-name))
"^\\'")
tramp--test-messages))))))))
(let (inhibit-message)
(dolist (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
(dolist (visit '(nil t "string" no-message))
(ert-with-message-capture tramp--test-messages
(write-region "foo" nil tmp-name nil visit)
;; We must check the last line. There could be
;; other messages from the progress reporter.
(should
(string-match-p
(if (and (null noninteractive)
(or (eq visit t) (null visit) (stringp visit)))
(format "^Wrote %s\n\\'" (regexp-quote tmp-name))
"^\\'")
tramp--test-messages))))))
;; We do not test lockname here. See
;; `tramp-test39-make-lock-file-name'.
@ -2490,17 +2480,15 @@ This checks also `file-name-as-directory', `file-name-directory',
;; Ange-FTP.
((symbol-function 'yes-or-no-p) #'tramp--test-always))
(write-region "foo" nil tmp-name nil nil nil 'mustbenew))
;; `mustbenew' is passed to Tramp since Emacs 26.1.
(when (tramp--test-emacs26-p)
(should-error
(cl-letf (((symbol-function #'y-or-n-p) #'ignore)
;; Ange-FTP.
((symbol-function #'yes-or-no-p) #'ignore))
(write-region "foo" nil tmp-name nil nil nil 'mustbenew))
:type 'file-already-exists)
(should-error
(write-region "foo" nil tmp-name nil nil nil 'excl)
:type 'file-already-exists)))
(should-error
(cl-letf (((symbol-function #'y-or-n-p) #'ignore)
;; Ange-FTP.
((symbol-function #'yes-or-no-p) #'ignore))
(write-region "foo" nil tmp-name nil nil nil 'mustbenew))
:type 'file-already-exists)
(should-error
(write-region "foo" nil tmp-name nil nil nil 'excl)
:type 'file-already-exists))
;; Cleanup.
(ignore-errors (delete-file tmp-name))))))
@ -2563,7 +2551,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(copy-file source target)
:type tramp-file-missing)
:type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(copy-file source target)
@ -2589,8 +2577,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
;; This has been changed in Emacs 26.1.
(when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
(when (tramp--test-expensive-test)
(should-error
(copy-file source target)
:type 'file-already-exists)
@ -2675,7 +2662,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(progn
(should-error
(rename-file source target)
:type tramp-file-missing)
:type 'file-missing)
(write-region "foo" nil source)
(should (file-exists-p source))
(rename-file source target)
@ -2704,8 +2691,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (file-exists-p source))
(make-directory target)
(should (file-directory-p target))
;; This has been changed in Emacs 26.1.
(when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
(when (tramp--test-expensive-test)
(should-error
(rename-file source target)
:type 'file-already-exists)
@ -2883,7 +2869,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(ert-deftest tramp-test15-copy-directory ()
"Check `copy-directory'."
(skip-unless (tramp--test-enabled))
(skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
(skip-unless (not (tramp--test-rclone-p)))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@ -2900,7 +2886,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(progn
(should-error
(copy-directory tmp-name1 tmp-name2)
:type tramp-file-missing)
:type 'file-missing)
;; Copy empty directory.
(make-directory tmp-name1)
(write-region "foo" nil tmp-name4)
@ -2910,11 +2896,9 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(should (file-directory-p tmp-name2))
(should (file-exists-p tmp-name5))
;; Target directory does exist already.
;; This has been changed in Emacs 26.1.
(when (tramp--test-emacs26-p)
(should-error
(copy-directory tmp-name1 tmp-name2)
:type 'file-already-exists))
(should-error
(copy-directory tmp-name1 tmp-name2)
:type 'file-already-exists)
(copy-directory tmp-name1 (file-name-as-directory tmp-name2))
(should (file-directory-p tmp-name3))
(should (file-exists-p tmp-name6)))
@ -3004,7 +2988,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(progn
(should-error
(directory-files tmp-name1)
:type tramp-file-missing)
:type 'file-missing)
(make-directory tmp-name1)
(write-region "foo" nil tmp-name2)
(write-region "bla" nil tmp-name3)
@ -3127,14 +3111,12 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(insert-directory tmp-name1 nil)
(goto-char (point-min))
(should (looking-at-p (regexp-quote tmp-name1))))
;; This has been fixed in Emacs 26.1. See Bug#29423.
(when (tramp--test-emacs26-p)
(with-temp-buffer
(insert-directory (file-name-as-directory tmp-name1) nil)
(goto-char (point-min))
(should
(looking-at-p
(regexp-quote (file-name-as-directory tmp-name1))))))
(with-temp-buffer
(insert-directory (file-name-as-directory tmp-name1) nil)
(goto-char (point-min))
(should
(looking-at-p
(regexp-quote (file-name-as-directory tmp-name1)))))
(with-temp-buffer
(insert-directory tmp-name1 "-al")
(goto-char (point-min))
@ -3166,7 +3148,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; modes are still "accessible".
(not (tramp--test-sshfs-p))
;; A directory is always accessible for user "root".
(not (zerop (tramp-compat-file-attribute-user-id
(not (zerop (file-attribute-user-id
(file-attributes tmp-name1)))))
(set-file-modes tmp-name1 0)
(with-temp-buffer
@ -3178,7 +3160,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(with-temp-buffer
(should-error
(insert-directory tmp-name1 nil)
:type tramp-file-missing)))
:type 'file-missing)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive))))))
@ -3192,8 +3174,6 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(skip-unless (not (tramp--test-rsync-p)))
;; Wildcards are not supported in tramp-crypt.el.
(skip-unless (not (tramp--test-crypt-p)))
;; Since Emacs 26.1.
(skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
(let* ((tmp-name1
@ -3381,15 +3361,14 @@ This tests also `access-file', `file-readable-p',
(file-modes tramp-test-temporary-file-directory))))
(write-region "foo" nil tmp-name1)
(setq test-file-ownership-preserved-p
(= (tramp-compat-file-attribute-group-id
(file-attributes tmp-name1))
(= (file-attribute-group-id (file-attributes tmp-name1))
(tramp-get-remote-gid tramp-test-vec 'integer)))
(delete-file tmp-name1))
(when (tramp--test-supports-set-file-modes-p)
(write-region "foo" nil tmp-name1)
;; A file is always accessible for user "root".
(when (not (zerop (tramp-compat-file-attribute-user-id
(when (not (zerop (file-attribute-user-id
(file-attributes tmp-name1))))
(set-file-modes tmp-name1 0)
(should-error
@ -3399,7 +3378,7 @@ This tests also `access-file', `file-readable-p',
(delete-file tmp-name1))
(should-error
(access-file tmp-name1 "error")
:type tramp-file-missing)
:type 'file-missing)
;; `file-ownership-preserved-p' should return t for
;; non-existing files.
@ -3416,33 +3395,29 @@ This tests also `access-file', `file-readable-p',
;; We do not test inodes and device numbers.
(setq attr (file-attributes tmp-name1))
(should (consp attr))
(should (null (tramp-compat-file-attribute-type attr)))
(should (numberp (tramp-compat-file-attribute-link-number attr)))
(should (numberp (tramp-compat-file-attribute-user-id attr)))
(should (numberp (tramp-compat-file-attribute-group-id attr)))
(should (null (file-attribute-type attr)))
(should (numberp (file-attribute-link-number attr)))
(should (numberp (file-attribute-user-id attr)))
(should (numberp (file-attribute-group-id attr)))
(should
(stringp (current-time-string (file-attribute-access-time attr))))
(should
(stringp
(current-time-string
(tramp-compat-file-attribute-access-time attr))))
(current-time-string (file-attribute-modification-time attr))))
(should
(stringp
(current-time-string
(tramp-compat-file-attribute-modification-time attr))))
(should
(stringp
(current-time-string
(tramp-compat-file-attribute-status-change-time attr))))
(should (numberp (tramp-compat-file-attribute-size attr)))
(should (stringp (tramp-compat-file-attribute-modes attr)))
(current-time-string (file-attribute-status-change-time attr))))
(should (numberp (file-attribute-size attr)))
(should (stringp (file-attribute-modes attr)))
(setq attr (file-attributes tmp-name1 'string))
(should (stringp (tramp-compat-file-attribute-user-id attr)))
(should (stringp (tramp-compat-file-attribute-group-id attr)))
(should (stringp (file-attribute-user-id attr)))
(should (stringp (file-attribute-group-id attr)))
(tramp--test-ignore-make-symbolic-link-error
(should-error
(access-file tmp-name2 "error")
:type tramp-file-missing)
:type 'file-missing)
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name2 'group)))
(make-symbolic-link tmp-name1 tmp-name2)
@ -3456,7 +3431,7 @@ This tests also `access-file', `file-readable-p',
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
(tramp-compat-file-attribute-type attr))
(file-attribute-type attr))
(file-remote-p (file-truename tmp-name1) 'localname)))
(delete-file tmp-name2))
@ -3475,7 +3450,7 @@ This tests also `access-file', `file-readable-p',
(setq attr (file-attributes tmp-name2))
(should
(string-equal
(tramp-compat-file-attribute-type attr)
(file-attribute-type attr)
(tramp-file-name-localname
(tramp-dissect-file-name tmp-name3))))
(delete-file tmp-name2))
@ -3491,7 +3466,7 @@ This tests also `access-file', `file-readable-p',
(when test-file-ownership-preserved-p
(should (file-ownership-preserved-p tmp-name1 'group)))
(setq attr (file-attributes tmp-name1))
(should (eq (tramp-compat-file-attribute-type attr) t)))
(should (eq (file-attribute-type attr) t)))
;; Cleanup.
(ignore-errors (delete-directory tmp-name1))
@ -3509,9 +3484,9 @@ They might differ only in time attributes or directory size."
(start-time (- tramp--test-start-time 10)))
;; Link number. For directories, it includes the number of
;; subdirectories. Set it to 1.
(when (eq (tramp-compat-file-attribute-type attr1) t)
(when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 1 attr1) 1))
(when (eq (tramp-compat-file-attribute-type attr2) t)
(when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 1 attr2) 1))
;; Access time.
(setcar (nthcdr 4 attr1) tramp-time-dont-know)
@ -3524,42 +3499,33 @@ They might differ only in time attributes or directory size."
;; order to compensate a possible timestamp resolution higher than
;; a second on the remote machine.
(when (or (tramp-compat-time-equal-p
(tramp-compat-file-attribute-modification-time attr1)
tramp-time-dont-know)
(file-attribute-modification-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
(tramp-compat-file-attribute-modification-time attr2)
tramp-time-dont-know))
(file-attribute-modification-time attr2) tramp-time-dont-know))
(setcar (nthcdr 5 attr1) tramp-time-dont-know)
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
(when (< start-time
(float-time (tramp-compat-file-attribute-modification-time attr1)))
(float-time (file-attribute-modification-time attr1)))
(setcar (nthcdr 5 attr1) tramp-time-dont-know))
(when (< start-time
(float-time (tramp-compat-file-attribute-modification-time attr2)))
(float-time (file-attribute-modification-time attr2)))
(setcar (nthcdr 5 attr2) tramp-time-dont-know))
;; Status change time. Ditto.
(when (or (tramp-compat-time-equal-p
(tramp-compat-file-attribute-status-change-time attr1)
tramp-time-dont-know)
(file-attribute-status-change-time attr1) tramp-time-dont-know)
(tramp-compat-time-equal-p
(tramp-compat-file-attribute-status-change-time attr2)
tramp-time-dont-know))
(file-attribute-status-change-time attr2) tramp-time-dont-know))
(setcar (nthcdr 6 attr1) tramp-time-dont-know)
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
(when
(< start-time
(float-time
(tramp-compat-file-attribute-status-change-time attr1)))
(when (< start-time (float-time (file-attribute-status-change-time attr1)))
(setcar (nthcdr 6 attr1) tramp-time-dont-know))
(when
(< start-time
(float-time (tramp-compat-file-attribute-status-change-time attr2)))
(when (< start-time (float-time (file-attribute-status-change-time attr2)))
(setcar (nthcdr 6 attr2) tramp-time-dont-know))
;; Size. Set it to 0 for directories, because it might have
;; changed. For example the upper directory "../".
(when (eq (tramp-compat-file-attribute-type attr1) t)
(when (eq (file-attribute-type attr1) t)
(setcar (nthcdr 7 attr1) 0))
(when (eq (tramp-compat-file-attribute-type attr2) t)
(when (eq (file-attribute-type attr2) t)
(setcar (nthcdr 7 attr2) 0))
;; The check.
(unless (equal attr1 attr2) (tramp--test-message "%S\n%S" attr1 attr2))
@ -3583,12 +3549,12 @@ They might differ only in time attributes or directory size."
(progn
(should-error
(directory-files-and-attributes tmp-name1)
:type tramp-file-missing)
:type 'file-missing)
(make-directory tmp-name1)
(should (file-directory-p tmp-name1))
(setq tramp--test-start-time
(float-time
(tramp-compat-file-attribute-modification-time
(file-attribute-modification-time
(file-attributes tmp-name1))))
(make-directory tmp-name2)
(should (file-directory-p tmp-name2))
@ -3646,8 +3612,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(should (= (file-modes tmp-name1) #o444))
(should-not (file-executable-p tmp-name1))
;; A file is always writable for user "root".
(unless (zerop (tramp-compat-file-attribute-user-id
(file-attributes tmp-name1)))
(unless (zerop (file-attribute-user-id (file-attributes tmp-name1)))
(should-not (file-writable-p tmp-name1)))
;; Check the NOFOLLOW arg. It exists since Emacs 28. For
;; regular files, there shouldn't be a difference.
@ -3721,9 +3686,6 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
"Check `file-symlink-p'.
This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (tramp--test-enabled))
;; The semantics have changed heavily in Emacs 26.1. We cannot test
;; older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
(dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
@ -3940,11 +3902,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(when (tramp--test-expensive-test)
(should-error
(with-temp-buffer (insert-file-contents tmp-name2))
:type tramp-file-missing))
:type 'file-missing))
(when (tramp--test-expensive-test)
(should-error
(with-temp-buffer (insert-file-contents tmp-name3))
:type tramp-file-missing))
:type 'file-missing))
;; `directory-files' does not show symlinks to
;; non-existing targets in the "smb" case. So we remove
;; the symlinks manually.
@ -4005,7 +3967,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(progn
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
(should (consp (tramp-compat-file-attribute-modification-time
(should (consp (file-attribute-modification-time
(file-attributes tmp-name1))))
;; Skip the test, if the remote handler is not able to set
;; the correct time.
@ -4013,13 +3975,12 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Dumb remote shells without perl(1) or stat(1) are not
;; able to return the date correctly. They say "don't know".
(unless (tramp-compat-time-equal-p
(tramp-compat-file-attribute-modification-time
(file-attribute-modification-time
(file-attributes tmp-name1))
tramp-time-dont-know)
(should
(tramp-compat-time-equal-p
(tramp-compat-file-attribute-modification-time
(file-attributes tmp-name1))
(file-attribute-modification-time (file-attributes tmp-name1))
(seconds-to-time 1)))
(write-region "bla" nil tmp-name2)
(should (file-exists-p tmp-name2))
@ -4034,7 +3995,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
(should
(tramp-compat-time-equal-p
(tramp-compat-file-attribute-modification-time
(file-attribute-modification-time
(file-attributes tmp-name1))
(seconds-to-time 1)))))))
@ -4948,8 +4909,6 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
;; Since Emacs 26.1.
(skip-unless (boundp 'interrupt-process-functions))
;; We must use `file-truename' for the temporary directory, in
;; order to establish the connection prior running an asynchronous
@ -5364,9 +5323,6 @@ Use direct async.")
;; Since Emacs 27.1.
(skip-unless (fboundp 'with-connection-local-variables))
;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
;; want to see compiler warnings for older Emacsen.
(let* ((default-directory tramp-test-temporary-file-directory)
(tmp-name1 (tramp--test-make-temp-name))
(tmp-name2 (expand-file-name "foo" tmp-name1))
@ -5382,23 +5338,22 @@ Use direct async.")
;; `local-variable' is buffer-local due to explicit setting.
(with-no-warnings
(defvar-local local-variable 'buffer))
(defvar-local local-variable 'buffer))
(with-temp-buffer
(should (eq local-variable 'buffer)))
;; `local-variable' is connection-local due to Tramp.
(write-region "foo" nil tmp-name2)
(should (file-exists-p tmp-name2))
(with-no-warnings
(connection-local-set-profile-variables
'local-variable-profile
'((local-variable . connect)))
(connection-local-set-profiles
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
:machine ,(file-remote-p default-directory 'host))
'local-variable-profile))
(connection-local-set-profile-variables
'local-variable-profile
'((local-variable . connect)))
(connection-local-set-profiles
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
:machine ,(file-remote-p default-directory 'host))
'local-variable-profile)
(with-current-buffer (find-file-noselect tmp-name2)
(should (eq local-variable 'connect))
(kill-buffer (current-buffer)))
@ -5423,7 +5378,6 @@ Use direct async.")
;; Cleanup.
(ignore-errors (delete-directory tmp-name1 'recursive)))))
;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test34-explicit-shell-file-name ()
"Check that connection-local `explicit-shell-file-name' is set."
:tags '(:expensive-test)
@ -5433,13 +5387,7 @@ Use direct async.")
;; remote processes in Emacs. That doesn't work for tramp-adb.el.
(when (tramp--test-adb-p)
(skip-unless (tramp--test-emacs27-p)))
;; Since Emacs 26.1.
(skip-unless (and (fboundp 'connection-local-set-profile-variables)
(fboundp 'connection-local-set-profiles)))
;; `connection-local-set-profile-variables' and
;; `connection-local-set-profiles' exist since Emacs 26.1. We don't
;; want to see compiler warnings for older Emacsen.
(let ((default-directory tramp-test-temporary-file-directory)
explicit-shell-file-name kill-buffer-query-functions
connection-local-profile-alist connection-local-criteria-alist)
@ -5448,19 +5396,16 @@ Use direct async.")
;; `shell-mode' would ruin our test, because it deletes all
;; buffer local variables. Not needed in Emacs 27.1.
(put 'explicit-shell-file-name 'permanent-local t)
;; Declare connection-local variables `explicit-shell-file-name'
;; and `explicit-sh-args'.
(with-no-warnings
(connection-local-set-profile-variables
'remote-sh
`((explicit-shell-file-name . ,(tramp--test-shell-file-name))
(explicit-sh-args . ("-c" "echo foo"))))
(connection-local-set-profiles
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
:machine ,(file-remote-p default-directory 'host))
'remote-sh))
(connection-local-set-profile-variables
'remote-sh
`((explicit-shell-file-name . ,(tramp--test-shell-file-name))
(explicit-sh-args . ("-c" "echo foo"))))
(connection-local-set-profiles
`(:application tramp
:protocol ,(file-remote-p default-directory 'method)
:user ,(file-remote-p default-directory 'user)
:machine ,(file-remote-p default-directory 'host))
'remote-sh)
(put 'explicit-shell-file-name 'safe-local-variable #'identity)
(put 'explicit-sh-args 'safe-local-variable #'identity)
@ -5763,7 +5708,7 @@ Use direct async.")
;; files, owned by root.
(let ((tramp-auto-save-directory temporary-file-directory))
(write-region "foo" nil tmp-name1)
(when (zerop (or (tramp-compat-file-attribute-user-id
(when (zerop (or (file-attribute-user-id
(file-attributes tmp-name1))
tramp-unknown-id-integer))
(with-temp-buffer
@ -5910,8 +5855,7 @@ Use direct async.")
(let ((backup-directory-alist `(("." . ,temporary-file-directory)))
tramp-backup-directory-alist)
(write-region "foo" nil tmp-name1)
(when (zerop (or (tramp-compat-file-attribute-user-id
(file-attributes tmp-name1))
(when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@ -6047,8 +5991,7 @@ Use direct async.")
;; files, owned by root.
(let ((lock-file-name-transforms auto-save-file-name-transforms))
(write-region "foo" nil tmp-name1)
(when (zerop (or (tramp-compat-file-attribute-user-id
(file-attributes tmp-name1))
(when (zerop (or (file-attribute-user-id (file-attributes tmp-name1))
tramp-unknown-id-integer))
(tramp-cleanup-connection
tramp-test-vec 'keep-debug 'keep-password)
@ -6066,29 +6009,22 @@ Use direct async.")
(ignore-errors (delete-file tmp-name1))
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-ange-ftp-p)))
;; Since Emacs 26.1.
(skip-unless
(and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
;; `make-nearby-temp-file' and `temporary-file-directory' exists
;; since Emacs 26.1. We don't want to see compiler warnings for
;; older Emacsen.
(let ((default-directory tramp-test-temporary-file-directory)
tmp-file)
;; The remote host shall know a temporary file directory.
(should (stringp (with-no-warnings (temporary-file-directory))))
(should (stringp (temporary-file-directory)))
(should
(string-equal
(file-remote-p default-directory)
(file-remote-p (with-no-warnings (temporary-file-directory)))))
(file-remote-p (temporary-file-directory))))
;; The temporary file shall be located on the remote host.
(setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test")))
(setq tmp-file (make-nearby-temp-file "tramp-test"))
(should (file-exists-p tmp-file))
(should (file-regular-p tmp-file))
(should
@ -6098,18 +6034,12 @@ Use direct async.")
(delete-file tmp-file)
(should-not (file-exists-p tmp-file))
(setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test" 'dir)))
(setq tmp-file (make-nearby-temp-file "tramp-test" 'dir))
(should (file-exists-p tmp-file))
(should (file-directory-p tmp-file))
(delete-directory tmp-file)
(should-not (file-exists-p tmp-file))))
(defun tramp--test-emacs26-p ()
"Check for Emacs version >= 26.1.
Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 26))
(defun tramp--test-emacs27-p ()
"Check for Emacs version >= 27.1.
Some semantics has been changed for there, w/o new functions or
@ -6122,6 +6052,12 @@ Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 28))
(defun tramp--test-emacs29-p ()
"Check for Emacs version >= 29.1.
Some semantics has been changed for there, w/o new functions or
variables, so we check the Emacs version directly."
(>= emacs-major-version 29))
(defun tramp--test-adb-p ()
"Check, whether the remote host runs Android.
This requires restrictions of file name syntax."
@ -6337,7 +6273,7 @@ This requires restrictions of file name syntax."
(string-equal
(funcall
(if quoted #'tramp-compat-file-name-quote #'identity)
(tramp-compat-file-attribute-type (file-attributes file3)))
(file-attribute-type (file-attributes file3)))
(file-remote-p (file-truename file1) 'localname)))
;; Check file contents.
(with-temp-buffer
@ -6538,7 +6474,7 @@ This requires restrictions of file name syntax."
(skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 245s
(skip-unless (tramp--test-enabled))
(skip-unless (not (tramp--test-rsync-p)))
(skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
(skip-unless (not (tramp--test-rclone-p)))
(tramp--test-special-characters))
@ -6661,7 +6597,7 @@ Use the \"ls\" command."
(skip-unless (not (tramp--test-ksh-p)))
(skip-unless (not (tramp--test-gdrive-p)))
(skip-unless (not (tramp--test-crypt-p)))
(skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
(skip-unless (not (tramp--test-rclone-p)))
(tramp--test-utf8))
@ -6873,11 +6809,7 @@ process sentinels. They shall not disturb each other."
(when buffers
(let ((time (float-time))
(default-directory tmp-name)
(file
(buffer-name
;; Use `seq-random-elt' once <26.1 support
;; is dropped.
(nth (random (length buffers)) buffers)))
(file (buffer-name (seq-random-elt buffers)))
;; A remote operation in a timer could
;; confuse Tramp heavily. So we ignore this
;; error here.
@ -6942,8 +6874,7 @@ process sentinels. They shall not disturb each other."
;; the buffers. Mix with regular operation.
(let ((buffers (copy-sequence buffers)))
(while buffers
;; Use `seq-random-elt' once <26.1 support is dropped.
(let* ((buf (nth (random (length buffers)) buffers))
(let* ((buf (seq-random-elt buffers))
(proc (get-buffer-process buf))
(file (process-get proc 'foo))
(count (process-get proc 'bar)))
@ -7003,6 +6934,10 @@ process sentinels. They shall not disturb each other."
"Check that Tramp (un)compresses normal files."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(skip-unless (not (tramp--test-emacs29-p)))
(let ((default-directory tramp-test-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name)))
(write-region "foo" nil tmp-name)
@ -7019,6 +6954,10 @@ process sentinels. They shall not disturb each other."
"Check that Tramp (un)compresses directories."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
(skip-unless (not (tramp--test-emacs29-p)))
(let ((default-directory tramp-test-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name)))
(make-directory tmp-name)
@ -7060,10 +6999,6 @@ process sentinels. They shall not disturb each other."
(ert-deftest tramp-test46-delay-load ()
"Check that Tramp is loaded lazily, only when needed."
;; The autoloaded Tramp objects are different since Emacs 26.1. We
;; cannot test older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
;; Tramp is neither loaded at Emacs startup, nor when completing a
;; non-Tramp file name like "/foo". Completing a Tramp-alike file
;; name like "/foo:" autoloads Tramp, when `tramp-mode' is t.
@ -7117,10 +7052,6 @@ process sentinels. They shall not disturb each other."
(ert-deftest tramp-test46-remote-load-path ()
"Check that Tramp autoloads its packages with remote `load-path'."
;; The autoloaded Tramp objects are different since Emacs 26.1. We
;; cannot test older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
;; It shall still work, when a remote file name is in the
;; `load-path'.
@ -7149,10 +7080,6 @@ process sentinels. They shall not disturb each other."
Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test)
(skip-unless noninteractive)
;; The autoloaded Tramp objects are different since Emacs 26.1. We
;; cannot test older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
;; We have autoloaded objects from tramp.el and tramp-archive.el.
;; In order to remove them, we first need to load both packages.
(require 'tramp)
@ -7212,8 +7139,7 @@ If INTERACTIVE is non-nil, the tests are run interactively."
;; TODO:
;; * dired-compress-file
;; * dired-uncache
;; * dired-uncache (partly done in other test functions)
;; * file-equal-p (partly done in `tramp-test21-file-links')
;; * file-in-directory-p
;; * file-name-case-insensitive-p