branch: externals/tramp
commit dbda6788b09afed1b2d3a7aedea93f76466bd7d1
Author: Michael Albinus <michael.albi...@gmx.de>
Commit: Michael Albinus <michael.albi...@gmx.de>

    Tramp ELPA version 2.5.0.4 released
---
 test/tramp-tests.el |  40 ++++-----
 texi/tramp.texi     |  53 ++++++-----
 texi/trampver.texi  |   2 +-
 tramp-archive.el    |   6 +-
 tramp-sh.el         | 247 +++++++++++++++++++++++-----------------------------
 tramp.el            | 115 ++++++++++++++----------
 trampver.el         |   6 +-
 7 files changed, 232 insertions(+), 237 deletions(-)

diff --git a/test/tramp-tests.el b/test/tramp-tests.el
index 3189fa1..99ea62e 100644
--- a/test/tramp-tests.el
+++ b/test/tramp-tests.el
@@ -59,6 +59,7 @@
 (declare-function tramp-get-remote-perl "tramp-sh")
 (declare-function tramp-get-remote-stat "tramp-sh")
 (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")
 (defvar ange-ftp-make-backup-files)
 (defvar auto-save-file-name-transforms)
@@ -3097,6 +3098,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-rsync-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-scp-p)))
   ;; Wildcards are not supported in tramp-crypt.el.
   (skip-unless (not (tramp--test-crypt-p)))
   ;; Since Emacs 26.1.
@@ -4369,7 +4371,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
          (delete-file tmp-name))))))
 
 (defun tramp--test-shell-file-name ()
-  "Return default remote shell.."
+  "Return default remote shell."
   (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
 
 (ert-deftest tramp-test28-process-file ()
@@ -5838,18 +5840,18 @@ This requires restrictions of file name syntax."
   "Check, whether the locale host runs MS Windows."
   (eq system-type 'windows-nt))
 
-(defun tramp--test-windows-nt-and-batch-p ()
-  "Check, whether the locale host runs MS Windows in batch mode.
-This does not support special characters."
-  (and (eq system-type 'windows-nt) noninteractive))
+(defun tramp--test-windows-nt-and-out-of-band-p ()
+  "Check, whether the locale host runs MS Windows and an out-of-band method.
+This does not support utf8 based file transfer."
+  (and (eq system-type 'windows-nt)
+       (tramp-method-out-of-band-p tramp-test-vec 1)))
 
-(defun tramp--test-windows-nt-and-pscp-psftp-p ()
-  "Check, whether the locale host runs MS Windows, and ps{cp,ftp} is used.
+(defun tramp--test-windows-nt-and-scp-p ()
+  "Check, whether the locale host runs MS Windows, and scpx? is used.
 This does not support utf8 based file transfer."
   (and (eq system-type 'windows-nt)
        (string-match-p
-       (regexp-opt '("pscp" "psftp"))
-       (file-remote-p tramp-test-temporary-file-directory 'method))))
+       "^scpx?" (file-remote-p tramp-test-temporary-file-directory 'method))))
 
 (defun tramp--test-windows-nt-or-smb-p ()
   "Check, whether the locale or remote host runs MS Windows.
@@ -6112,7 +6114,7 @@ This requires restrictions of file name syntax."
   "Check special characters in file names."
   (skip-unless (tramp--test-enabled))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-scp-p)))
   (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
 
   (tramp--test-special-characters))
@@ -6124,7 +6126,7 @@ Use the `stat' command."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-scp-p)))
   ;; We cannot use `tramp-test-vec', because this fails during compilation.
   (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
     (skip-unless (tramp-get-remote-stat v)))
@@ -6143,7 +6145,7 @@ Use the `perl' command."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-scp-p)))
   ;; We cannot use `tramp-test-vec', because this fails during compilation.
   (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil
     (skip-unless (tramp-get-remote-perl v)))
@@ -6165,7 +6167,7 @@ Use the `ls' command."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-scp-p)))
 
   (let ((tramp-connection-properties
         (append
@@ -6230,8 +6232,7 @@ Use the `ls' command."
   (skip-unless (tramp--test-enabled))
   (skip-unless (not (tramp--test-docker-p)))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-batch-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
   (skip-unless (not (tramp--test-ksh-p)))
   (skip-unless (not (tramp--test-gdrive-p)))
   (skip-unless (not (tramp--test-crypt-p)))
@@ -6247,8 +6248,7 @@ Use the `stat' command."
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-docker-p)))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-batch-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
   (skip-unless (not (tramp--test-ksh-p)))
   (skip-unless (not (tramp--test-crypt-p)))
   ;; We cannot use `tramp-test-vec', because this fails during compilation.
@@ -6270,8 +6270,7 @@ Use the `perl' command."
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-docker-p)))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-batch-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
   (skip-unless (not (tramp--test-ksh-p)))
   (skip-unless (not (tramp--test-crypt-p)))
   ;; We cannot use `tramp-test-vec', because this fails during compilation.
@@ -6296,8 +6295,7 @@ Use the `ls' command."
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-docker-p)))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-batch-p)))
-  (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p)))
+  (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p)))
   (skip-unless (not (tramp--test-ksh-p)))
   (skip-unless (not (tramp--test-crypt-p)))
 
diff --git a/texi/tramp.texi b/texi/tramp.texi
index 7baf26c..6319a2d 100644
--- a/texi/tramp.texi
+++ b/texi/tramp.texi
@@ -5067,33 +5067,46 @@ remote files}.
 
 
 @item
-I get a warning @samp{Tramp has been compiled with Emacs a.b, this is Emacs 
c.d}
+How to prevent @value{tramp} from clearing the @code{recentf-list}?
 
-@value{tramp} comes with compatibility code for different Emacs
-versions.  When you see this warning, you don't use the Emacs built-in
-version of @value{tramp}.  In case you have installed @value{tramp}
-from GNU ELPA, you must delete and reinstall it.
-@ifset installchapter
-In case you have installed it from its Git repository, @ref{Recompilation}.
-@end ifset
+When @value{tramp} cleans a connection, it removes the respective
+remote file name(s) from @code{recentf-list}.  This is needed, because
+an unresponsive remote host could trigger @code{recentf} to connect
+that host again and again.
+
+If you find the cleanup disturbing, because the file names in
+@code{recentf-list} are precious to you, you could add the following
+two forms in your @file{~/.emacs} after loading the @code{tramp} and
+@code{recentf} packages:
 
+@lisp
+@group
+(remove-hook
+ 'tramp-cleanup-connection-hook
+ #'tramp-recentf-cleanup)
+@end group
+@group
+(remove-hook
+ 'tramp-cleanup-all-connections-hook
+ #'tramp-recentf-cleanup-all)
+@end group
+@end lisp
 
+
+@item
+I get a warning @samp{Tramp has been compiled with Emacs a.b, this is Emacs 
c.d}
 @item
 I get an error @samp{tramp-file-name-handler: Invalid function:
 tramp-compat-with-mutex}
 
-Likely, you have a running Emacs session with loaded @value{tramp},
-and you try to upgrade it to another version from GNU ELPA.  Since
-@value{tramp} is not forward compatible, you must unload / reload it.
-Try the following steps:
-
-@example
-@kbd{M-x tramp-unload-tramp @key{RET}}
-@kbd{M-x load-library @key{RET} tramp @key{RET}}
-@end example
-
-If this doesn't work, you must restart Emacs with proper
-@code{load-path} for the new @value{tramp} version.
+@value{tramp} comes with compatibility code for different Emacs
+versions.  When you see such a message (the text might differ), you
+don't use the Emacs built-in version of @value{tramp}.  In case you
+have installed @value{tramp} from GNU ELPA, see the package README
+file for instructions how to recompile it.
+@ifset installchapter
+@xref{Recompilation}.
+@end ifset
 
 
 @item
diff --git a/texi/trampver.texi b/texi/trampver.texi
index dc41564..168fdb1 100644
--- a/texi/trampver.texi
+++ b/texi/trampver.texi
@@ -8,7 +8,7 @@
 @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.0.3
+@set trampver 2.5.0.4
 @set trampurl https://www.gnu.org/software/tramp/
 @set tramp-bug-report-address tramp-devel@@gnu.org
 @set emacsver 25.1
diff --git a/tramp-archive.el b/tramp-archive.el
index 0bbd927..61c40ff 100644
--- a/tramp-archive.el
+++ b/tramp-archive.el
@@ -628,10 +628,8 @@ offered."
   (let ((result
         (insert-file-contents
          (tramp-archive-gvfs-file-name filename) visit beg end replace)))
-    (prog1
-       (list (expand-file-name filename)
-             (cadr result))
-      (when visit (setq buffer-file-name filename)))))
+    (when visit (setq buffer-file-name filename))
+    (cons (expand-file-name filename) (cdr result))))
 
 (defun tramp-archive-handle-load
     (file &optional noerror nomessage nosuffix must-suffix)
diff --git a/tramp-sh.el b/tramp-sh.el
index 1764f2e..b51ba11 100644
--- a/tramp-sh.el
+++ b/tramp-sh.el
@@ -103,12 +103,12 @@ detected as prompt when being sent on echoing hosts, 
therefore.")
 (defconst tramp-end-of-heredoc (md5 tramp-end-of-output)
   "String used to recognize end of heredoc strings.")
 
-(defcustom tramp-use-ssh-controlmaster-options t
+(defcustom tramp-use-ssh-controlmaster-options (not (eq system-type 
'windows-nt))
   "Whether to use `tramp-ssh-controlmaster-options'.
 Set it to nil, if you use Control* or Proxy* options in your ssh
 configuration."
   :group 'tramp
-  :version "24.4"
+  :version "28.1"
   :type 'boolean)
 
 (defvar tramp-ssh-controlmaster-options nil
@@ -169,7 +169,8 @@ The string is used in `tramp-methods'.")
                 (tramp-login-program        "ssh")
                 (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
                                             ("-e" "none") ("-t" "-t")
-                                            ("-o" "RemoteCommand='%l'") 
("%h")))
+                                            ("-o" "RemoteCommand=\"%l\"")
+                                            ("%h")))
                 (tramp-async-args           (("-q")))
                 (tramp-remote-shell         ,tramp-default-remote-shell)
                 (tramp-remote-shell-login   ("-l"))
@@ -225,7 +226,8 @@ The string is used in `tramp-methods'.")
                 (tramp-login-program        "ssh")
                 (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
                                             ("-e" "none") ("-t" "-t")
-                                            ("-o" "RemoteCommand='%l'") 
("%h")))
+                                            ("-o" "RemoteCommand=\"%l\"")
+                                            ("%h")))
                 (tramp-async-args           (("-q")))
                 (tramp-remote-shell         ,tramp-default-remote-shell)
                 (tramp-remote-shell-login   ("-l"))
@@ -399,16 +401,34 @@ The string is used in `tramp-methods'.")
 
 ;;;###tramp-autoload
 (defconst tramp-completion-function-alist-ssh
-  '((tramp-parse-rhosts      "/etc/hosts.equiv")
+  `((tramp-parse-rhosts      "/etc/hosts.equiv")
     (tramp-parse-rhosts      "/etc/shosts.equiv")
-    (tramp-parse-shosts      "/etc/ssh_known_hosts")
-    (tramp-parse-sconfig     "/etc/ssh_config")
+    ;; On W32 systems, the ssh directory is located somewhere else.
+    (tramp-parse-shosts      ,(expand-file-name
+                              "ssh/ssh_known_hosts"
+                              (or (and (eq system-type 'windows-nt)
+                                       (getenv "ProgramData"))
+                                  "/etc/")))
+    (tramp-parse-sconfig     ,(expand-file-name
+                              "ssh/ssh_config"
+                              (or (and (eq system-type 'windows-nt)
+                                       (getenv "ProgramData"))
+                                  "/etc/")))
     (tramp-parse-shostkeys   "/etc/ssh2/hostkeys")
     (tramp-parse-sknownhosts "/etc/ssh2/knownhosts")
     (tramp-parse-rhosts      "~/.rhosts")
     (tramp-parse-rhosts      "~/.shosts")
-    (tramp-parse-shosts      "~/.ssh/known_hosts")
-    (tramp-parse-sconfig     "~/.ssh/config")
+    ;; On W32 systems, the .ssh directory is located somewhere else.
+    (tramp-parse-shosts      ,(expand-file-name
+                              ".ssh/known_hosts"
+                              (or (and (eq system-type 'windows-nt)
+                                       (getenv "USERPROFILE"))
+                                  "~/")))
+    (tramp-parse-sconfig     ,(expand-file-name
+                              ".ssh/config"
+                              (or (and (eq system-type 'windows-nt)
+                                       (getenv "USERPROFILE"))
+                                  "~/")))
     (tramp-parse-shostkeys   "~/.ssh2/hostkeys")
     (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
   "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
@@ -431,7 +451,7 @@ The string is used in `tramp-methods'.")
 ;;;###tramp-autoload
 (defconst tramp-completion-function-alist-putty
   `((tramp-parse-putty
-     ,(if (memq system-type '(windows-nt))
+     ,(if (eq system-type 'windows-nt)
          "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"
        "~/.putty/sessions")))
  "Default list of (FUNCTION REGISTRY) pairs to be examined for putty 
sessions.")
@@ -941,7 +961,7 @@ Format specifiers \"%s\" are replaced before the script is 
used.")
     (file-name-directory . tramp-handle-file-name-directory)
     (file-name-nondirectory . tramp-handle-file-name-nondirectory)
     ;; `file-name-sans-versions' performed by default handler.
-    (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
+    (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
     (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
     (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
     (file-notify-valid-p . tramp-handle-file-notify-valid-p)
@@ -1549,49 +1569,6 @@ ID-FORMAT valid values are `string' and `integer'."
       (or (tramp-check-cached-permissions v ?r)
          (tramp-run-test "-r" filename)))))
 
-;; When the remote shell is started, it looks for a shell which groks
-;; tilde expansion.  Here, we assume that all shells which grok tilde
-;; expansion will also provide a `test' command which groks `-nt' (for
-;; newer than).  If this breaks, tell me about it and I'll try to do
-;; something smarter about it.
-(defun tramp-sh-handle-file-newer-than-file-p (file1 file2)
-  "Like `file-newer-than-file-p' for Tramp files."
-  (cond ((not (file-exists-p file1)) nil)
-        ((not (file-exists-p file2)) t)
-        (t ;; We are sure both files exist at this point.  We try to
-           ;; get the mtime of both files.  If they are not equal to
-           ;; the "dont-know" value, then we subtract the times and
-           ;; obtain the result.
-          (let ((fa1 (file-attributes file1))
-                (fa2 (file-attributes file2)))
-            (if (and
-                 (not
-                  (tramp-compat-time-equal-p
-                   (tramp-compat-file-attribute-modification-time fa1)
-                   tramp-time-dont-know))
-                 (not
-                  (tramp-compat-time-equal-p
-                   (tramp-compat-file-attribute-modification-time fa2)
-                   tramp-time-dont-know)))
-                (time-less-p
-                 (tramp-compat-file-attribute-modification-time fa2)
-                 (tramp-compat-file-attribute-modification-time fa1))
-              ;; If one of them is the dont-know value, then we can
-              ;; still try to run a shell command on the remote host.
-              ;; However, this only works if both files are Tramp
-              ;; files and both have the same method, same user, same
-              ;; host.
-              (unless (tramp-equal-remote file1 file2)
-                (with-parsed-tramp-file-name
-                    (if (tramp-tramp-file-p file1) file1 file2) nil
-                  (tramp-error
-                   v 'file-error
-                   "Files %s and %s must have same method, user, host"
-                   file1 file2)))
-              (with-parsed-tramp-file-name file1 nil
-                (tramp-run-test2
-                 (tramp-get-test-nt-command v) file1 file2)))))))
-
 ;; Functions implemented using the basic functions above.
 
 (defun tramp-sh-handle-file-directory-p (filename)
@@ -2241,7 +2218,7 @@ The method used must be an out-of-band method."
         (t2 (tramp-tramp-file-p newname))
         (orig-vec (tramp-dissect-file-name (if t1 filename newname)))
         copy-program copy-args copy-env copy-keep-date listener spec
-        options source target remote-copy-program remote-copy-args)
+        options source target remote-copy-program remote-copy-args p)
 
     (with-parsed-tramp-file-name (if t1 filename newname) nil
       (if (and t1 t2)
@@ -2276,10 +2253,10 @@ The method used must be an out-of-band method."
                        #'identity)
                      (if t1
                          (tramp-make-copy-program-file-name v)
-                       (tramp-unquote-shell-quote-argument filename)))
+                       (tramp-compat-file-name-unquote filename)))
              target (if t2
                         (tramp-make-copy-program-file-name v)
-                      (tramp-unquote-shell-quote-argument newname)))
+                      (tramp-compat-file-name-unquote newname)))
 
        ;; Check for user.  There might be an interactive setting.
        (setq user (or (tramp-file-name-user v)
@@ -2311,6 +2288,13 @@ The method used must be an out-of-band method."
              ;; 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))
+             ;; `tramp-ssh-controlmaster-options' is a string instead
+             ;; of a list.  Unflatten it.
+             copy-args
+             (tramp-compat-flatten-tree
+              (mapcar
+               (lambda (x) (if (string-match-p " " x) (split-string x) x))
+               copy-args))
              copy-env (apply #'tramp-expand-args v 'tramp-copy-env spec)
              remote-copy-program
              (tramp-get-method-parameter v 'tramp-remote-copy-program)
@@ -2372,31 +2356,26 @@ The method used must be an out-of-band method."
                  copy-args
                  (if remote-copy-program
                      (list (if t1 (concat ">" target) (concat "<" source)))
-                   (list source target))))
-
-               ;; Use an asynchronous process.  By this, password can
-               ;; be handled.  We don't set a timeout, because the
-               ;; copying of large files can last longer than 60 secs.
-               (let* ((command
-                       (mapconcat
-                        #'identity (append (list copy-program) copy-args)
-                        " "))
-                      (p (let ((default-directory
-                                 (tramp-compat-temporary-file-directory)))
-                           (start-process-shell-command
-                            (tramp-get-connection-name v)
-                            (tramp-get-connection-buffer v)
-                            command))))
-                 (tramp-message orig-vec 6 "%s" command)
-                 (process-put p 'vector orig-vec)
-                 (process-put p 'adjust-window-size-function #'ignore)
-                 (set-process-query-on-exit-flag p nil)
-
-                 ;; We must adapt `tramp-local-end-of-line' for
-                 ;; sending the password.
-                 (let ((tramp-local-end-of-line tramp-rsh-end-of-line))
-                   (tramp-process-actions
-                    p v nil tramp-actions-copy-out-of-band))))
+                   (list source target)))
+                ;; Use an asynchronous process.  By this, password
+                ;; can be handled.  We don't set a timeout, because
+                ;; the copying of large files can last longer than 60
+                ;; secs.
+                p (apply
+                   #'start-process
+                   (tramp-get-connection-name v)
+                   (tramp-get-connection-buffer v)
+                   copy-program copy-args))
+               (tramp-message orig-vec 6 "%s" (string-join (process-command p) 
" "))
+               (process-put p 'vector orig-vec)
+               (process-put p 'adjust-window-size-function #'ignore)
+               (set-process-query-on-exit-flag p nil)
+
+               ;; We must adapt `tramp-local-end-of-line' for
+               ;; sending the password.
+               (let ((tramp-local-end-of-line tramp-rsh-end-of-line))
+                 (tramp-process-actions
+                  p v nil tramp-actions-copy-out-of-band)))
 
            ;; Reset the transfer process properties.
            (tramp-flush-connection-property v "process-name")
@@ -2584,12 +2563,9 @@ The method used must be an out-of-band method."
        (save-restriction
          (narrow-to-region beg-marker end-marker)
          ;; Check for "--dired" output.
-         (forward-line -2)
-         (when (looking-at-p "//SUBDIRED//")
-           (forward-line -1))
-         (when (looking-at "//DIRED//\\s-+")
-           (let ((beg (match-end 0))
-                 (end (point-at-eol)))
+         (when (re-search-backward "^//DIRED//\\s-+\\(.+\\)$" nil 'noerror)
+           (let ((beg (match-beginning 1))
+                 (end (match-end 0)))
              ;; Now read the numeric positions of file names.
              (goto-char beg)
              (while (< (point) end)
@@ -2599,7 +2575,7 @@ The method used must be an out-of-band method."
                      ;; End is followed by \n or by " -> ".
                      (put-text-property start end 'dired-filename t))))))
          ;; Remove trailing lines.
-         (goto-char (point-at-bol))
+         (beginning-of-line)
          (while (looking-at "//")
            (forward-line 1)
            (delete-region (match-beginning 0) (point))))
@@ -2947,15 +2923,19 @@ alternative implementation will be used."
                        ;; until the process is deleted.
                        (when (bufferp stderr)
                          (with-current-buffer stderr
-                           (insert-file-contents-literally remote-tmpstderr))
+                           ;; There's a mysterious error, see
+                           ;; <https://github.com/joaotavora/eglot/issues/662>.
+                           (ignore-errors
+                             (insert-file-contents-literally 
remote-tmpstderr)))
                          ;; Delete tmpstderr file.
                          (add-function
                           :after (process-sentinel p)
                           (lambda (_proc _msg)
                             (when (file-exists-p remote-tmpstderr)
                               (with-current-buffer stderr
-                                (insert-file-contents-literally
-                                 remote-tmpstderr nil nil nil 'replace))
+                                (ignore-errors
+                                  (insert-file-contents-literally
+                                   remote-tmpstderr nil nil nil 'replace)))
                               (delete-file remote-tmpstderr)))))
                        ;; Return process.
                        p)))
@@ -3728,7 +3708,8 @@ Fall back to normal file name handler if no Tramp handler 
exists."
        (remote-prefix
         (with-current-buffer (process-buffer proc)
           (file-remote-p default-directory)))
-       (rest-string (process-get proc 'rest-string)))
+       (rest-string (process-get proc 'rest-string))
+       pos)
     (when rest-string
       (tramp-message proc 10 "Previous string:\n%s" rest-string))
     (tramp-message proc 6 "%S\n%s" proc string)
@@ -3750,23 +3731,27 @@ Fall back to normal file name handler if no Tramp 
handler exists."
 
       ;; Determine monitor name.
       (unless (tramp-connection-property-p proc "gio-file-monitor")
-        (cond
-         ;; We have seen this only on cygwin gio, which uses the
-         ;; GPollFileMonitor.
-         ((string-match
-           "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string)
-          (tramp-set-connection-property
-           proc "gio-file-monitor" 'GPollFileMonitor))
-         ;; TODO: What happens, if several monitor names are reported?
-         ((string-match "\
+        (tramp-set-connection-property
+         proc "gio-file-monitor"
+         (cond
+          ;; We have seen this on cygwin gio and on emba.  Let's make
+          ;; some assumptions.
+          ((string-match
+            "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" 
string)
+          (setq pos (match-end 0))
+           (cond
+            ((getenv "EMACS_EMBA_CI") 'GInotifyFileMonitor)
+            ((eq system-type 'cygwin) 'GPollFileMonitor)
+            (t nil)))
+          ;; TODO: What happens, if several monitor names are reported?
+          ((string-match "\
 Supported arguments for GIO_USE_FILE_MONITOR environment variable:
 \\s-*\\([[:alpha:]]+\\) - 20" string)
-          (tramp-set-connection-property
-           proc "gio-file-monitor"
+          (setq pos (match-end 0))
            (intern
-            (format "G%sFileMonitor" (capitalize (match-string 1 string))))))
-         (t (throw 'doesnt-work nil)))
-        (setq string (replace-match "" nil nil string)))
+           (format "G%sFileMonitor" (capitalize (match-string 1 string)))))
+          (t (setq pos (length string)) nil)))
+       (setq string (substring string pos)))
 
       ;; Delete empty lines.
       (setq string (tramp-compat-string-replace "\n\n" "\n" string))
@@ -3800,6 +3785,8 @@ Supported arguments for GIO_USE_FILE_MONITOR environment 
variable:
             `(file-notify ,object file-notify-callback))))))
 
     ;; Save rest of the string.
+    (while (string-match "^\n" string)
+      (setq string (replace-match "" nil nil string)))
     (when (zerop (length string)) (setq string nil))
     (when string (tramp-message proc 10 "Rest string:\n%s" string))
     (process-put proc 'rest-string string)))
@@ -3949,24 +3936,6 @@ Returns the exit code of the `test' program."
       switch
       (tramp-shell-quote-argument localname)))))
 
-(defun tramp-run-test2 (format-string file1 file2)
-  "Run `test'-like program on the remote system, given FILE1, FILE2.
-FORMAT-STRING contains the program name, switches, and place holders.
-Returns the exit code of the `test' program.  Barfs if the methods,
-hosts, or files, disagree."
-  (unless (tramp-equal-remote file1 file2)
-    (with-parsed-tramp-file-name (if (tramp-tramp-file-p file1) file1 file2) 
nil
-      (tramp-error
-       v 'file-error
-       "tramp-run-test2 only implemented for same method, user, host")))
-  (with-parsed-tramp-file-name file1 v1
-    (with-parsed-tramp-file-name file1 v2
-      (tramp-send-command-and-check
-       v1
-       (format format-string
-              (tramp-shell-quote-argument v1-localname)
-              (tramp-shell-quote-argument v2-localname))))))
-
 (defconst tramp-sunos-unames (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
   "Regexp to determine remote SunOS.")
 
@@ -4972,11 +4941,7 @@ connection if a previous connection has died for some 
reason."
                        ?h (or l-host "") ?u (or l-user "") ?p (or l-port "")
                        ?c (format-spec options (format-spec-make ?t tmpfile))
                        ?l (concat remote-shell " " extra-args " -i"))
-                      ;; Local shell could be a Windows COMSPEC.  It
-                      ;; doesn't know the ";" syntax, but we must
-                      ;; exit always for `start-file-process'.  It
-                      ;; could also be a restricted shell, which does
-                      ;; not allow "exec".
+                      ;; A restricted shell does not allow "exec".
                       (when r-shell '("&&" "exit" "||" "exit")))
                      " "))
 
@@ -5264,15 +5229,17 @@ Return ATTR."
         (directory-file-name (tramp-file-name-unquote-localname vec))))
     (when (string-match-p tramp-ipv6-regexp host)
       (setq host (format "[%s]" host)))
+    ;; This does not work yet for MS Windows scp, if there are
+    ;; characters to be quoted.  Win32 OpenSSH 7.9 is said to support
+    ;; this, see
+    ;; 
<https://github.com/PowerShell/Win32-OpenSSH/releases/tag/v7.9.0.0p1-Beta>
     (unless (string-match-p "ftp$" method)
       (setq localname (tramp-shell-quote-argument localname)))
     (cond
      ((tramp-get-method-parameter vec 'tramp-remote-copy-program)
       localname)
-     ((not (zerop (length user)))
-      (format
-       "%s@%s:%s" user host (tramp-unquote-shell-quote-argument localname)))
-     (t (format "%s:%s" host (tramp-unquote-shell-quote-argument 
localname))))))
+     ((zerop (length user)) (format "%s:%s" host localname))
+     (t (format "%s@%s:%s" user host localname)))))
 
 (defun tramp-method-out-of-band-p (vec size)
   "Return t if this is an out-of-band method, nil otherwise."
@@ -5523,15 +5490,15 @@ Nonexistent directories are removed from spec."
        ;; Check whether stat(1) returns usable syntax.  "%s" does not
        ;; work on older AIX systems.  Recent GNU stat versions
        ;; (8.24?)  use shell quoted format for "%N", we check the
-       ;; boundaries "`" and "'", therefore.  See Bug#23422 in
-       ;; coreutils.  Since GNU stat 8.26, environment variable
-       ;; QUOTING_STYLE is supported.
+       ;; boundaries "`" and "'" and their localized variants,
+       ;; therefore.  See Bug#23422 in coreutils.  Since GNU stat
+       ;; 8.26, environment variable QUOTING_STYLE is supported.
        (when result
          (setq result (concat "env QUOTING_STYLE=locale " result)
                tmp (tramp-send-command-and-read
                     vec (format "%s -c '(\"%%N\" %%s)' /" result) 'noerror))
          (unless (and (listp tmp) (stringp (car tmp))
-                      (string-match-p "^\\(`/'\\|‘/’\\)$" (car tmp))
+                      (string-match-p "^[\"`‘„”«「]/[\"'’“”»」]$" (car tmp))
                       (integerp (cadr tmp)))
            (setq result nil)))
        result))))
@@ -5825,7 +5792,7 @@ function cell is returned to be applied on a buffer."
           ;; slashes as directory separators.
           (cond
            ((and (string-match-p "local" prop)
-                 (memq system-type '(windows-nt)))
+                 (eq system-type 'windows-nt))
               "(%s | \"%s\")")
            ((string-match-p "local" prop) "(%s | %s)")
            (t "(%s | %s >%%s)"))
@@ -5836,7 +5803,7 @@ function cell is returned to be applied on a buffer."
           ;; the pipe symbol be quoted if they use forward
           ;; slashes as directory separators.
           (if (and (string-match-p "local" prop)
-                   (memq system-type '(windows-nt)))
+                   (eq system-type 'windows-nt))
               "(%s <%%s | \"%s\")"
             "(%s <%%s | %s)")
           compress coding))
diff --git a/tramp.el b/tramp.el
index de7d758..499789b 100644
--- a/tramp.el
+++ b/tramp.el
@@ -64,8 +64,7 @@
 (declare-function netrc-parse "netrc")
 (defvar auto-save-file-name-transforms)
 
-;; Reload `tramp-compat` when we reload `tramp-autoloads' of the GNU
-;; ELPA package.
+;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU ELPA 
package.
 ;;;###autoload (when (featurep 'tramp-compat)
 ;;;###autoload   (load "tramp-compat" 'noerror 'nomessage))
 
@@ -359,12 +358,13 @@ Notes:
 All these arguments can be overwritten by connection properties.
 See Info node `(tramp) Predefined connection information'.
 
-When using `su' or `sudo' the phrase \"open connection to a remote
-host\" sounds strange, but it is used nevertheless, for consistency.
-No connection is opened to a remote host, but `su' or `sudo' is
-started on the local host.  You should specify a remote host
-`localhost' or the name of the local host.  Another host name is
-useful only in combination with `tramp-default-proxies-alist'.")
+When using `su', `sudo' or `doas' the phrase \"open connection to
+a remote host\" sounds strange, but it is used nevertheless, for
+consistency.  No connection is opened to a remote host, but `su',
+`sudo' or `doas' is started on the local host.  You should
+specify a remote host `localhost' or the name of the local host.
+Another host name is useful only in combination with
+`tramp-default-proxies-alist'.")
 
 (defcustom tramp-default-method
   ;; An external copy method seems to be preferred, because it performs
@@ -492,7 +492,7 @@ interpreted as a regular expression which always matches."
 ;; either lower case or upper case letters.  See
 ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=38079#20>.
 (defcustom tramp-restricted-shell-hosts-alist
-  (when (memq system-type '(windows-nt))
+  (when (eq system-type 'windows-nt)
     (list (format "\\`\\(%s\\|%s\\)\\'"
                  (regexp-quote (downcase tramp-system-name))
                  (regexp-quote (upcase tramp-system-name)))))
@@ -562,7 +562,7 @@ usually suffice.")
 the remote shell.")
 
 (defcustom tramp-local-end-of-line
-  (if (memq system-type '(windows-nt)) "\r\n" "\n")
+  (if (eq system-type 'windows-nt) "\r\n" "\n")
   "String used for end of line in local processes."
   :version "24.1"
   :type 'string)
@@ -1082,7 +1082,13 @@ initial value is overwritten by the car of 
`tramp-file-name-structure'.")
 
 (defconst tramp-completion-file-name-regexp-default
   (concat
-   "\\`/\\("
+   "\\`"
+   ;; `file-name-completion' uses absolute paths for matching.  This
+   ;; means that on W32 systems, something like "/ssh:host:~/path"
+   ;; becomes "c:/ssh:host:~/path".  See also `tramp-drop-volume-letter'.
+   (when (eq system-type 'windows-nt)
+       "\\(?:[[:alpha:]]:\\)?")
+   "/\\("
    ;; Optional multi hop.
    "\\([^/|:]+:[^/|:]*|\\)*"
    ;; Last hop.
@@ -1101,7 +1107,13 @@ On W32 systems, the volume letter must be ignored.")
 
 (defconst tramp-completion-file-name-regexp-simplified
   (concat
-   "\\`/\\("
+   "\\`"
+   ;; Allow the volume letter at the beginning of the path.  See the
+   ;; comment in `tramp-completion-file-name-regexp-default' for more
+   ;; details.
+   (when (eq system-type 'windows-nt)
+     "\\(?:[[:alpha:]]:\\)?")
+   "/\\("
    ;; Optional multi hop.
    "\\([^/|:]*|\\)*"
    ;; Last hop.
@@ -1117,7 +1129,14 @@ See `tramp-file-name-structure' for more explanations.
 On W32 systems, the volume letter must be ignored.")
 
 (defconst tramp-completion-file-name-regexp-separate
-  "\\`/\\(\\[[^]]*\\)?\\'"
+  (concat
+   "\\`"
+   ;; Allow the volume letter at the beginning of the path.  See the
+   ;; comment in `tramp-completion-file-name-regexp-default' for more
+   ;; details.
+   (when (eq system-type 'windows-nt)
+     "\\(?:[[:alpha:]]:\\)?")
+   "/\\(\\[[^]]*\\)?\\'")
   "Value for `tramp-completion-file-name-regexp' for separate remoting.
 See `tramp-file-name-structure' for more explanations.")
 
@@ -1813,6 +1832,7 @@ The outline level is equal to the verbosity of the Tramp 
message."
   "Get the debug buffer for VEC."
   (with-current-buffer (get-buffer-create (tramp-debug-buffer-name vec))
     (when (bobp)
+      (set-buffer-file-coding-system 'utf-8)
       (setq buffer-undo-list t)
       ;; Activate `outline-mode'.  This runs `text-mode-hook' and
       ;; `outline-mode-hook'.  We must prevent that local processes
@@ -1853,7 +1873,7 @@ ARGUMENTS to actually emit the message (if applicable)."
        (when (bobp)
          (insert
           (format
-           ";; Emacs: %s Tramp: %s -*- mode: outline; -*-"
+           ";; Emacs: %s Tramp: %s -*- mode: outline; coding: utf-8; -*-"
            emacs-version tramp-version))
          (when (>= tramp-verbose 10)
            (let ((tramp-verbose 0))
@@ -2176,14 +2196,15 @@ without a visible progress reporter."
 FILE must be a local file name on a connection identified via VEC."
   (declare (indent 3) (debug t))
   `(if (file-name-absolute-p ,file)
-      (let ((value (tramp-get-file-property ,vec ,file ,property 'undef)))
-       (when (eq value 'undef)
-         ;; We cannot pass @body as parameter to
-         ;; `tramp-set-file-property' because it mangles our
-         ;; debug messages.
-         (setq value (progn ,@body))
-         (tramp-set-file-property ,vec ,file ,property value))
-       value)
+       (let ((value (tramp-get-file-property
+                    ,vec ,file ,property tramp-cache-undefined)))
+        (when (eq value tramp-cache-undefined)
+          ;; We cannot pass @body as parameter to
+          ;; `tramp-set-file-property' because it mangles our debug
+          ;; messages.
+          (setq value (progn ,@body))
+          (tramp-set-file-property ,vec ,file ,property value))
+        value)
      ,@body))
 
 (font-lock-add-keywords 'emacs-lisp-mode '("\\<with-tramp-file-property\\>"))
@@ -2191,14 +2212,15 @@ FILE must be a local file name on a connection 
identified via VEC."
 (defmacro with-tramp-connection-property (key property &rest body)
   "Check in Tramp for property PROPERTY, otherwise execute BODY and set."
   (declare (indent 2) (debug t))
-  `(let ((value (tramp-get-connection-property ,key ,property 'undef)))
-    (when (eq value 'undef)
-      ;; We cannot pass ,@body as parameter to
-      ;; `tramp-set-connection-property' because it mangles our debug
-      ;; messages.
-      (setq value (progn ,@body))
-      (tramp-set-connection-property ,key ,property value))
-    value))
+  `(let ((value (tramp-get-connection-property
+                ,key ,property tramp-cache-undefined)))
+     (when (eq value tramp-cache-undefined)
+       ;; We cannot pass ,@body as parameter to
+       ;; `tramp-set-connection-property' because it mangles our debug
+       ;; messages.
+       (setq value (progn ,@body))
+       (tramp-set-connection-property ,key ,property value))
+     value))
 
 (font-lock-add-keywords
  'emacs-lisp-mode '("\\<with-tramp-connection-property\\>"))
@@ -3158,7 +3180,7 @@ User may be nil."
 (defun tramp-parse-putty (registry-or-dirname)
   "Return a list of (user host) tuples allowed to access.
 User is always nil."
-  (if (memq system-type '(windows-nt))
+  (if (eq system-type 'windows-nt)
       (with-tramp-connection-property nil "parse-putty"
        (with-temp-buffer
          (when (zerop (tramp-call-process
@@ -3733,21 +3755,19 @@ User is always nil."
                 (signal (car err) (cdr err))))))
 
        ;; Save exit.
-       (progn
-         (when visit
-           (setq buffer-file-name filename
-                 buffer-read-only (not (file-writable-p filename)))
-           (set-visited-file-modtime)
-           (set-buffer-modified-p nil))
-         (when (and (stringp local-copy)
-                    (or remote-copy (null tramp-temp-buffer-file-name)))
-           (delete-file local-copy))
-         (when (stringp remote-copy)
-           (delete-file (tramp-make-tramp-file-name v remote-copy 'nohop)))))
+       (when visit
+         (setq buffer-file-name filename
+               buffer-read-only (not (file-writable-p filename)))
+         (set-visited-file-modtime)
+         (set-buffer-modified-p nil))
+       (when (and (stringp local-copy)
+                  (or remote-copy (null tramp-temp-buffer-file-name)))
+         (delete-file local-copy))
+       (when (stringp remote-copy)
+         (delete-file (tramp-make-tramp-file-name v remote-copy 'nohop))))
 
       ;; Result.
-      (list (expand-file-name filename)
-           (cadr result)))))
+      (cons (expand-file-name filename) (cdr result)))))
 
 (defun tramp-handle-load (file &optional noerror nomessage nosuffix 
must-suffix)
   "Like `load' for Tramp files."
@@ -3908,8 +3928,7 @@ substitution.  SPEC-LIST is a list of char/value pairs 
used for
         (or (not (stringp stderr)) (not (tramp-tramp-file-p stderr))))))
 
 (defun tramp-handle-make-process (&rest args)
-  "An alternative `make-process' implementation for Tramp files.
-It does not support `:stderr'."
+  "An alternative `make-process' implementation for Tramp files."
   (when args
     (with-parsed-tramp-file-name (expand-file-name default-directory) nil
       (let ((default-directory (tramp-compat-temporary-file-directory))
@@ -5010,7 +5029,7 @@ VEC is used for tracing."
     (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8"))
          locale)
       (with-temp-buffer
-       (unless (or (memq system-type '(windows-nt))
+       (unless (or (eq system-type 'windows-nt)
                     (not (zerop (tramp-call-process
                                  nil "locale" nil t nil "-a"))))
          (while candidates
@@ -5101,7 +5120,7 @@ ID-FORMAT valid values are `string' and `integer'."
     (or (when-let
            ((handler
              (find-file-name-handler
-              (tramp-make-tramp-file-name vec) 'tramp-get-remote-uid)))
+              (tramp-make-tramp-file-name vec) 'tramp-get-remote-gid)))
          (funcall handler #'tramp-get-remote-gid vec id-format))
        ;; Ensure there is a valid result.
        (and (equal id-format 'integer) tramp-unknown-id-integer)
diff --git a/trampver.el b/trampver.el
index 34032c0..ecf730d 100644
--- a/trampver.el
+++ b/trampver.el
@@ -7,7 +7,7 @@
 ;; Maintainer: Michael Albinus <michael.albi...@gmx.de>
 ;; Keywords: comm, processes
 ;; Package: tramp
-;; Version: 2.5.0.3
+;; Version: 2.5.0.4
 ;; Package-Requires: ((emacs "25.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.0.3"
+(defconst tramp-version "2.5.0.4"
   "This version of Tramp.")
 
 ;;;###tramp-autoload
@@ -76,7 +76,7 @@
 ;; Check for Emacs version.
 (let ((x   (if (not (string-lessp emacs-version "25.1"))
       "ok"
-    (format "Tramp 2.5.0.3 is not fit for %s"
+    (format "Tramp 2.5.0.4 is not fit for %s"
             (replace-regexp-in-string "\n" "" (emacs-version))))))
   (unless (string-equal "ok" x) (error "%s" x)))
 

Reply via email to