Add Tramp methods dockercp and podmancp

* doc/misc/tramp.texi (External methods):  Add dockercp and podmancp.

* etc/NEWS: Add Tramp methods "dockercp" and "podmancp".

* lisp/net/tramp.el (tramp-handle-make-process):
* lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection):
* lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band)
(tramp-maybe-open-connection):
* lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file)
(tramp-sshfs-maybe-open-connection):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-send-command): Adapt
`tramp-expand-args' calls.

* lisp/net/tramp-container.el (tramp-dockercp-method)
(tramp-podmancp-method): New defconst.
(tramp-methods) <dockercp, podmancp>: Add new methods.
(tramp-container--completion-function): Adapt docstring.  Use it
for "dockercp" and "podmancp" completion.

* lisp/net/tramp.el (tramp-get-remote-tmpdir):
* lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection):
* lisp/net/tramp-sh.el (tramp-maybe-open-connection): Use a default
value with `tramp-get-method-parameter'.

* lisp/net/tramp-sh.el (tramp-methods) <nc>: Add `tramp-copy-file-name'.
(tramp-default-copy-file-name): New defconst.
(tramp-make-copy-file-name): Rename from
`tramp-make-copy-program-file-name'.  Use method parameter
`tramp-copy-file-name'.  (Bug#69085)
(tramp-do-copy-or-rename-file-out-of-band): Adapt callees.

* lisp/net/tramp.el (tramp-methods): Adapt docstring.
(tramp-get-method-parameter, tramp-expand-args): New optional
argument DEFAULT.

* test/lisp/net/tramp-tests.el (tramp--test-container-p): Adapt.
(tramp--test-container-oob-p): New defun.
(tramp-test17-dired-with-wildcards, tramp-test35-remote-path)
(tramp-test41-special-characters): Use it.
(tramp--test-set-ert-test-documentation): Use `split-string'.
This commit is contained in:
Michael Albinus 2024-02-20 12:52:40 +01:00
parent a1cbc4d810
commit 4e9993cada
10 changed files with 182 additions and 74 deletions

View file

@ -1059,6 +1059,20 @@ session.
These methods support the @samp{-P} argument.
@item @option{dockercp}
@item @option{podmancp}
@cindex method @option{dockercp}
@cindex @option{dockercp} method
@cindex method @option{podmancp}
@cindex @option{podmancp} method
These methods are similar to @option{docker} or @option{podman}, but
they use the command @command{docker cp} or @command{podman cp} for
transferring large files.
These copy commands do not support file globs, and they ignore a user
name.
@item @option{fcp}
@cindex method @option{fcp}
@cindex @option{fcp} method

View file

@ -884,6 +884,10 @@ mode line. 'header' will display in the header line;
** Tramp
+++
*** New connection methods "dockercp" and "podmancp".
These are the external methods counterparts of "docker" and "podman".
+++
*** New connection methods "toolbox" and "flatpak".
They allow accessing system containers provided by Toolbox or
@ -1121,7 +1125,7 @@ the user option 'nnweb-type' to 'gmane'.
*** New user option 'gnus-mode-line-logo'.
This allows the user to either disable the display of any logo or
specify which logo will be displayed as part of the
buffer-identification in the mode-line of Gnus-buffers.
buffer-identification in the mode-line of Gnus buffers.
** Rmail
@ -1333,7 +1337,7 @@ chat buffers use by default.
This command toggles the display of internal buffers in Buffer Menu mode;
that is, buffers not visiting a file and whose names start with a space.
Previously, such buffers were never shown. This command is bound to 'I'
in Buffer menu mode.
in Buffer Menu mode.
** Customize
@ -1429,7 +1433,7 @@ current project configuration, and later updates it as you edit the
files and save the changes.
+++
** New package Compat
** New package Compat.
Emacs now comes with a stub implementation of the
forwards-compatibility Compat package from GNU ELPA. This allows
built-in packages to use the library more effectively, and helps
@ -1560,7 +1564,7 @@ values.
+++
** Pcase's functions (in 'pred' and 'app') can specify the argument position.
For example, instead of (pred (< 5)) you can write (pred (> _ 5)).
For example, instead of '(pred (< 5))' you can write '(pred (> _ 5))'.
+++
** 'define-advice' now sets the new advice's 'name' property to NAME.

View file

@ -1230,7 +1230,7 @@ connection if a previous connection has died for some reason."
(let* ((coding-system-for-read 'utf-8-dos) ; Is this correct?
(process-connection-type tramp-process-connection-type)
(args (tramp-expand-args
vec 'tramp-login-args ?d (or device "")))
vec 'tramp-login-args nil ?d (or device "")))
(p (let ((default-directory
tramp-compat-temporary-file-directory))
(apply

View file

@ -31,15 +31,20 @@
;; Open a file on a running Docker container:
;;
;; C-x C-f /docker:USER@CONTAINER:/path/to/file
;; C-x C-f /dockercp:USER@CONTAINER:/path/to/file
;;
;; or Podman:
;;
;; C-x C-f /podman:USER@CONTAINER:/path/to/file
;; C-x C-f /podmancp:USER@CONTAINER:/path/to/file
;;
;; Where:
;; USER is the user on the container to connect as (optional).
;; CONTAINER is the container to connect to.
;;
;; "docker" and "podman" are inline methods, "dockercp" and "podmancp"
;; are out-of-band methods.
;;
;;
;;
;; Open file in a Kubernetes container:
@ -141,10 +146,20 @@ If it is nil, the default context will be used."
(defconst tramp-docker-method "docker"
"Tramp method name to use to connect to Docker containers.")
;;;###tramp-autoload
(defconst tramp-dockercp-method "dockercp"
"Tramp method name to use to connect to Docker containers.
This is for out-of-band connections.")
;;;###tramp-autoload
(defconst tramp-podman-method "podman"
"Tramp method name to use to connect to Podman containers.")
;;;###tramp-autoload
(defconst tramp-podmancp-method "podmancp"
"Tramp method name to use to connect to Podman containers.
This is for out-of-band connections.")
;;;###tramp-autoload
(defconst tramp-kubernetes-method "kubernetes"
"Tramp method name to use to connect to Kubernetes containers.")
@ -183,7 +198,8 @@ BODY is the backend specific code."
(defun tramp-container--completion-function (method)
"List running containers available for connection.
METHOD is the Tramp method to be used for \"ps\", either
`tramp-docker-method' or `tramp-podman-method'.
`tramp-docker-method', `tramp-dockercp-method', `tramp-podman-method',
or `tramp-podmancp-method'.
This function is used by `tramp-set-completion-function', please
see its function help for a description of the format."
@ -375,6 +391,23 @@ see its function help for a description of the format."
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-i" "-c"))))
(add-to-list 'tramp-methods
`(,tramp-dockercp-method
(tramp-login-program ,tramp-docker-program)
(tramp-login-args (("exec")
("-it")
("-u" "%u")
("%h")
("%l")))
(tramp-direct-async (,tramp-default-remote-shell "-c"))
(tramp-remote-shell ,tramp-default-remote-shell)
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-i" "-c"))
(tramp-copy-program ,tramp-docker-program)
(tramp-copy-args (("cp")))
(tramp-copy-file-name (("%h" ":") ("%f")))
(tramp-copy-recursive t)))
(add-to-list 'tramp-methods
`(,tramp-podman-method
(tramp-login-program ,tramp-podman-program)
@ -388,6 +421,23 @@ see its function help for a description of the format."
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-i" "-c"))))
(add-to-list 'tramp-methods
`(,tramp-podmancp-method
(tramp-login-program ,tramp-podman-program)
(tramp-login-args (("exec")
("-it")
("-u" "%u")
("%h")
("%l")))
(tramp-direct-async (,tramp-default-remote-shell "-c"))
(tramp-remote-shell ,tramp-default-remote-shell)
(tramp-remote-shell-login ("-l"))
(tramp-remote-shell-args ("-i" "-c"))
(tramp-copy-program ,tramp-podman-program)
(tramp-copy-args (("cp")))
(tramp-copy-file-name (("%h" ":") ("%f")))
(tramp-copy-recursive t)))
(add-to-list 'tramp-methods
`(,tramp-kubernetes-method
(tramp-login-program ,tramp-kubernetes-program)
@ -431,10 +481,18 @@ see its function help for a description of the format."
tramp-docker-method
`((tramp-container--completion-function ,tramp-docker-method)))
(tramp-set-completion-function
tramp-dockercp-method
`((tramp-container--completion-function ,tramp-dockercp-method)))
(tramp-set-completion-function
tramp-podman-method
`((tramp-container--completion-function ,tramp-podman-method)))
(tramp-set-completion-function
tramp-podmancp-method
`((tramp-container--completion-function ,tramp-podmancp-method)))
(tramp-set-completion-function
tramp-kubernetes-method
`((tramp-kubernetes--completion-function ,tramp-kubernetes-method)))

View file

@ -2294,8 +2294,8 @@ connection if a previous connection has died for some reason."
;; indicated by the "mounted" signal, i.e. the
;; "fuse-mountpoint" file property.
(with-timeout
((or (tramp-get-method-parameter vec 'tramp-connection-timeout)
tramp-connection-timeout)
((tramp-get-method-parameter
vec 'tramp-connection-timeout tramp-connection-timeout)
(if (tramp-string-empty-or-nil-p (tramp-file-name-user vec))
(tramp-error
vec 'file-error

View file

@ -282,6 +282,7 @@ The string is used in `tramp-methods'.")
(tramp-copy-program "nc")
;; We use "-v" for better error tracking.
(tramp-copy-args (("-w" "1") ("-v") ("%h") ("%r")))
(tramp-copy-file-name (("%f")))
(tramp-remote-copy-program "nc")
;; We use "-p" as required for newer busyboxes. For older
;; busybox/nc versions, the value must be (("-l") ("%r")). This
@ -428,6 +429,9 @@ The string is used in `tramp-methods'.")
eos)
nil ,(user-login-name))))
(defconst tramp-default-copy-file-name '(("%u" "@") ("%h" ":") ("%f"))
"Default `tramp-copy-file-name' entry for out-of-band methods.")
;;;###tramp-autoload
(defconst tramp-completion-function-alist-rsh
'((tramp-parse-rhosts "/etc/hosts.equiv")
@ -2399,10 +2403,10 @@ The method used must be an out-of-band method."
#'file-name-as-directory
#'identity)
(if v1
(tramp-make-copy-program-file-name v1)
(tramp-make-copy-file-name v1)
(file-name-unquote filename)))
target (if v2
(tramp-make-copy-program-file-name v2)
(tramp-make-copy-file-name v2)
(file-name-unquote newname)))
;; Check for listener port.
@ -2441,7 +2445,7 @@ The method used must be an out-of-band method."
;; " " has either been a replacement of "%k" (when
;; KEEP-DATE argument is non-nil), or a replacement for
;; the whole keep-date sublist.
(delete " " (apply #'tramp-expand-args v 'tramp-copy-args spec))
(delete " " (apply #'tramp-expand-args v 'tramp-copy-args nil spec))
;; `tramp-ssh-controlmaster-options' is a string instead
;; of a list. Unflatten it.
copy-args
@ -2450,11 +2454,11 @@ The method used must be an out-of-band method."
(lambda (x) (if (tramp-compat-string-search " " x)
(split-string x) x))
copy-args))
copy-env (apply #'tramp-expand-args v 'tramp-copy-env spec)
copy-env (apply #'tramp-expand-args v 'tramp-copy-env nil spec)
remote-copy-program
(tramp-get-method-parameter v 'tramp-remote-copy-program)
remote-copy-args
(apply #'tramp-expand-args v 'tramp-remote-copy-args spec))
(apply #'tramp-expand-args v 'tramp-remote-copy-args nil spec))
;; Check for local copy program.
(unless (executable-find copy-program)
@ -5290,7 +5294,8 @@ connection if a previous connection has died for some reason."
(tramp-get-method-parameter hop 'tramp-async-args)))
(connection-timeout
(tramp-get-method-parameter
hop 'tramp-connection-timeout))
hop 'tramp-connection-timeout
tramp-connection-timeout))
(command
(tramp-get-method-parameter
hop 'tramp-login-program))
@ -5348,7 +5353,7 @@ connection if a previous connection has died for some reason."
;; Add arguments for asynchronous processes.
(when process-name async-args)
(tramp-expand-args
hop 'tramp-login-args
hop 'tramp-login-args nil
?h (or l-host "") ?u (or l-user "") ?p (or l-port "")
?c (format-spec options (format-spec-make ?t tmpfile))
?n (concat
@ -5365,8 +5370,7 @@ connection if a previous connection has died for some reason."
p vec
(min
pos (with-current-buffer (process-buffer p) (point-max)))
tramp-actions-before-shell
(or connection-timeout tramp-connection-timeout))
tramp-actions-before-shell connection-timeout)
(tramp-message
vec 3 "Found remote shell prompt on `%s'" l-host)
@ -5559,8 +5563,8 @@ raises an error."
string
""))
(defun tramp-make-copy-program-file-name (vec)
"Create a file name suitable for `scp', `pscp', or `nc' and workalikes."
(defun tramp-make-copy-file-name (vec)
"Create a file name suitable for out-of-band methods."
(let ((method (tramp-file-name-method vec))
(user (tramp-file-name-user vec))
(host (tramp-file-name-host vec))
@ -5571,13 +5575,13 @@ raises an error."
;; This does not work for MS Windows scp, if there are characters
;; to be quoted. OpenSSH 8 supports disabling of strict file name
;; checking in scp, we use it when available.
(unless (string-match-p (rx "ftp" eos) method)
(unless (string-match-p (rx (| "dockercp" "podmancp" "ftp") eos) method)
(setq localname (tramp-unquote-shell-quote-argument localname)))
(cond
((tramp-get-method-parameter vec 'tramp-remote-copy-program)
localname)
((tramp-string-empty-or-nil-p user) (format "%s:%s" host localname))
(t (format "%s@%s:%s" user host localname)))))
(string-join
(apply #'tramp-expand-args vec
'tramp-copy-file-name tramp-default-copy-file-name
(list ?h (or host "") ?u (or user "") ?f localname))
"")))
(defun tramp-method-out-of-band-p (vec size)
"Return t if this is an out-of-band method, nil otherwise."

View file

@ -322,7 +322,7 @@ arguments to pass to the OPERATION."
v (tramp-get-method-parameter v 'tramp-login-program)
nil outbuf display
(tramp-expand-args
v 'tramp-login-args
v 'tramp-login-args nil
?h (or (tramp-file-name-host v) "")
?u (or (tramp-file-name-user v) "")
?p (or (tramp-file-name-port v) "")
@ -424,7 +424,7 @@ connection if a previous connection has died for some reason."
(tramp-fuse-mount-spec vec)
(tramp-fuse-mount-point vec)
(tramp-expand-args
vec 'tramp-mount-args
vec 'tramp-mount-args nil
?p (or (tramp-file-name-port vec) ""))))))
(tramp-error
vec 'file-error "Error mounting %s" (tramp-fuse-mount-spec vec)))

View file

@ -771,7 +771,7 @@ in case of error, t otherwise."
(tramp-get-connection-name vec) (current-buffer)
(append
(tramp-expand-args
vec 'tramp-sudo-login
vec 'tramp-sudo-login nil
?h (or (tramp-file-name-host vec) "")
?u (or (tramp-file-name-user vec) ""))
(flatten-tree args))))

View file

@ -301,6 +301,15 @@ pair of the form (KEY VALUE). The following KEYs are defined:
This specifies the list of parameters to pass to the above mentioned
program, the hints for `tramp-login-args' also apply here.
* `tramp-copy-file-name'
The remote source or destination file name for out-of-band methods.
You can use \"%u\" and \"%h\" like in `tramp-login-args'.
Additionally, \"%f\" denotes the local file name part. This list
will be expanded to a string without spaces between the elements of
the list.
The default value is `tramp-default-copy-file-name'.
* `tramp-copy-env'
A list of environment variables and their values, which will
be set when calling `tramp-copy-program'.
@ -1545,21 +1554,23 @@ LOCALNAME and HOP do not count."
(equal (tramp-file-name-unify vec1)
(tramp-file-name-unify vec2))))
(defun tramp-get-method-parameter (vec param)
(defun tramp-get-method-parameter (vec param &optional default)
"Return the method parameter PARAM.
If VEC is a vector, check first in connection properties.
Afterwards, check in `tramp-methods'. If the `tramp-methods'
entry does not exist, return nil."
entry does not exist, return DEFAULT."
(let ((hash-entry
(replace-regexp-in-string (rx bos "tramp-") "" (symbol-name param))))
(if (tramp-connection-property-p vec hash-entry)
;; We use the cached property.
(tramp-get-connection-property vec hash-entry)
;; Use the static value from `tramp-methods'.
(when-let ((methods-entry
(if-let ((methods-entry
(assoc
param (assoc (tramp-file-name-method vec) tramp-methods))))
(cadr methods-entry)))))
(cadr methods-entry)
;; Return the default value.
default))))
;; The localname can be quoted with "/:". Extract this.
(defun tramp-file-name-unquote-localname (vec)
@ -3943,6 +3954,9 @@ Let-bind it when necessary.")
(tramp-get-method-parameter v 'tramp-case-insensitive)
;; There isn't. So we must check, in case there's a connection already.
;; Note: We cannot use it as DEFAULT value of
;; `tramp-get-method-parameter', because it would be evalled
;; during the call.
(and (let ((non-essential t)) (tramp-connectable-p v))
(with-tramp-connection-property v "case-insensitive"
(ignore-errors
@ -4752,15 +4766,15 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
(defvar tramp-extra-expand-args nil
"Method specific arguments.")
(defun tramp-expand-args (vec parameter &rest spec-list)
(defun tramp-expand-args (vec parameter default &rest spec-list)
"Expand login arguments as given by PARAMETER in `tramp-methods'.
PARAMETER is a symbol like `tramp-login-args', denoting a list of
list of strings from `tramp-methods', containing %-sequences for
substitution.
substitution. DEFAULT is used when PARAMETER is not specified.
SPEC-LIST is a list of char/value pairs used for
`format-spec-make'. It is appended by `tramp-extra-expand-args',
a connection-local variable."
(let ((args (tramp-get-method-parameter vec parameter))
(let ((args (tramp-get-method-parameter vec parameter default))
(extra-spec-list
(mapcar
#'eval
@ -4939,7 +4953,7 @@ a connection-local variable."
(mapcar
(lambda (x) (split-string x " "))
(tramp-expand-args
v 'tramp-login-args
v 'tramp-login-args nil
?h (or host "") ?u (or user "") ?p (or port "")
?c (format-spec (or options "") (format-spec-make ?t tmpfile))
?d (or device "") ?a (or pta "") ?l ""))))
@ -6326,9 +6340,8 @@ This handles also chrooted environments, which are not regarded as local."
(defun tramp-get-remote-tmpdir (vec)
"Return directory for temporary files on the remote host identified by VEC."
(with-tramp-connection-property (tramp-get-process vec) "remote-tmpdir"
(let ((dir
(tramp-make-tramp-file-name
vec (or (tramp-get-method-parameter vec 'tramp-tmpdir) "/tmp"))))
(let ((dir (tramp-make-tramp-file-name
vec (tramp-get-method-parameter vec 'tramp-tmpdir "/tmp"))))
(or (and (file-directory-p dir) (file-writable-p dir)
(tramp-file-local-name dir))
(tramp-error vec 'file-error "Directory %s not accessible" dir))

View file

@ -3493,6 +3493,8 @@ 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)))
;; Wildcards are not supported with "docker cp ..." or "podman cp ...".
(skip-unless (not (tramp--test-container-oob-p)))
(dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1
@ -3819,7 +3821,7 @@ This tests also `access-file', `file-readable-p',
"Set the documentation string for a derived test.
The test is derived from TEST and COMMAND."
(let ((test-doc
(string-split (ert-test-documentation (get test 'ert--test)) "\n")))
(split-string (ert-test-documentation (get test 'ert--test)) "\n")))
;; The first line must be extended.
(setcar
test-doc (format "%s Use the \"%s\" command." (car test-doc) command))
@ -6379,33 +6381,35 @@ INPUT, if non-nil, is a string sent to the process."
(setq tramp-remote-path orig-tramp-remote-path)
;; We make a super long `tramp-remote-path'.
(make-directory tmp-name)
(should (file-directory-p tmp-name))
(while (tramp-compat-length< (string-join orig-exec-path ":") 5000)
(let ((dir (make-temp-file (file-name-as-directory tmp-name) 'dir)))
(should (file-directory-p dir))
(setq tramp-remote-path
(append
tramp-remote-path `(,(file-remote-p dir 'localname)))
orig-exec-path
(append
(butlast orig-exec-path)
`(,(file-remote-p dir 'localname))
(last orig-exec-path)))))
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
(should (equal (exec-path) orig-exec-path))
;; Ignore trailing newline.
(setq path (substring (shell-command-to-string "echo $PATH") nil -1))
;; The shell doesn't handle such long strings.
(unless (tramp-compat-length>
path
(tramp-get-connection-property
tramp-test-vec "pipe-buf" 4096))
;; The last element of `exec-path' is `exec-directory'.
(should
(string-equal path (string-join (butlast orig-exec-path) ":"))))
;; The shell "sh" shall always exist.
(should (executable-find "sh" 'remote)))
(unless (tramp--test-container-oob-p)
(make-directory tmp-name)
(should (file-directory-p tmp-name))
(while (tramp-compat-length< (string-join orig-exec-path ":") 5000)
(let ((dir (make-temp-file
(file-name-as-directory tmp-name) 'dir)))
(should (file-directory-p dir))
(setq tramp-remote-path
(append
tramp-remote-path `(,(file-remote-p dir 'localname)))
orig-exec-path
(append
(butlast orig-exec-path)
`(,(file-remote-p dir 'localname))
(last orig-exec-path)))))
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
(should (equal (exec-path) orig-exec-path))
;; Ignore trailing newline.
(setq path (substring (shell-command-to-string "echo $PATH") nil -1))
;; The shell doesn't handle such long strings.
(unless (tramp-compat-length>
path
(tramp-get-connection-property
tramp-test-vec "pipe-buf" 4096))
;; The last element of `exec-path' is `exec-directory'.
(should
(string-equal path (string-join (butlast orig-exec-path) ":"))))
;; The shell "sh" shall always exist.
(should (executable-find "sh" 'remote))))
;; Cleanup.
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)
@ -7056,17 +7060,24 @@ This is used in tests which we don't want to tag
(not (and (tramp--test-adb-p)
(string-match-p (rx multibyte) default-directory)))))
(defun tramp--test-crypt-p ()
"Check, whether the remote directory is encrypted."
(tramp-crypt-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-container-p ()
"Check, whether a container method is used.
This does not support some special file names."
(string-match-p
(rx bol (| "docker" "podman") eol)
(rx bol (| "docker" "podman"))
(file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-container-oob-p ()
"Check, whether the dockercp or podmancp method is used.
They does not support wildcard copy."
(string-match-p
(rx bol (| "dockercp" "podmancp") eol)
(file-remote-p ert-remote-temporary-file-directory 'method)))
(defun tramp--test-crypt-p ()
"Check, whether the remote directory is encrypted."
(tramp-crypt-file-name-p ert-remote-temporary-file-directory))
(defun tramp--test-expensive-test-p ()
"Whether expensive tests are run.
This is used in tests which we don't want to tag `:expensive'
@ -7483,7 +7494,8 @@ This requires restrictions of file name syntax."
(tramp--test-gvfs-p)
(tramp--test-windows-nt-or-smb-p))
"?foo?bar?baz?")
(unless (or (tramp--test-ftp-p)
(unless (or (tramp--test-container-oob-p)
(tramp--test-ftp-p)
(tramp--test-gvfs-p)
(tramp--test-windows-nt-or-smb-p))
"*foo+bar*baz+")
@ -7503,7 +7515,10 @@ This requires restrictions of file name syntax."
(unless (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
"<foo>bar<baz>")
"(foo)bar(baz)"
(unless (or (tramp--test-ftp-p) (tramp--test-gvfs-p)) "[foo]bar[baz]")
(unless (or (tramp--test-container-oob-p)
(tramp--test-ftp-p)
(tramp--test-gvfs-p))
"[foo]bar[baz]")
"{foo}bar{baz}")))
;; Simplify test in order to speed up.
(apply #'tramp--test-check-files