branch: externals/tramp commit 23851d6b391bbccdaba12e6165070cac476b5524 Author: Michael Albinus <michael.albi...@gmx.de> Commit: Michael Albinus <michael.albi...@gmx.de>
Tramp ELPA version 2.5.0.5 released --- test/tramp-tests.el | 112 +++++++++++++++++--------------------- texi/tramp.texi | 30 ++++------ texi/trampver.texi | 2 +- tramp-archive.el | 13 ++++- tramp-cache.el | 3 +- tramp-cmds.el | 6 +- tramp-compat.el | 5 +- tramp-gvfs.el | 2 +- tramp-integration.el | 16 +++--- tramp-sh.el | 151 ++++++++++++++++++++++++++++++--------------------- tramp-sudoedit.el | 2 +- tramp.el | 75 +++++++++++++++++++++++-- trampver.el | 6 +- 13 files changed, 254 insertions(+), 169 deletions(-) diff --git a/test/tramp-tests.el b/test/tramp-tests.el index 99ea62e..66bfe73 100644 --- a/test/tramp-tests.el +++ b/test/tramp-tests.el @@ -179,6 +179,11 @@ The temporary file is not created." "Whether `tramp--test-instrument-test-case' run. This shall used dynamically bound only.") +;; When `tramp-verbose' is greater than 10, and you want to trace +;; other functions as well, do something like +;; (let ((tramp-trace-functions '(file-name-non-special))) +;; (tramp--test-instrument-test-case 11 +;; ...)) (defmacro tramp--test-instrument-test-case (verbose &rest body) "Run BODY with `tramp-verbose' equal VERBOSE. Print the content of the Tramp connection and debug buffers, if @@ -187,31 +192,22 @@ is greater than 10. `should-error' is not handled properly. BODY shall not contain a timeout." (declare (indent 1) (debug (natnump body))) `(let* ((tramp-verbose (max (or ,verbose 0) (or tramp-verbose 0))) - (trace-buffer - (when (> tramp-verbose 10) (generate-new-buffer " *temp*"))) + (trace-buffer (tramp-trace-buffer-name tramp-test-vec)) (debug-ignored-errors (append '("^make-symbolic-link not supported$" "^error with add-name-to-file") debug-ignored-errors)) inhibit-message) - (when trace-buffer - (dolist (elt (all-completions "tramp-" obarray 'functionp)) - (trace-function-background (intern elt)))) (unwind-protect (let ((tramp--test-instrument-test-case-p t)) ,@body) ;; Unwind forms. - (when trace-buffer - (untrace-all)) (when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 3)) - (dolist - (buf (if trace-buffer - (cons (get-buffer trace-buffer) (tramp-list-tramp-buffers)) - (tramp-list-tramp-buffers))) + (untrace-all) + (dolist (buf (tramp-list-tramp-buffers)) (with-current-buffer buf - (message ";; %s\n%s" buf (buffer-string))))) - (when trace-buffer - (kill-buffer trace-buffer))))) + (message ";; %s\n%s" buf (buffer-string))) + (kill-buffer buf)))))) (defsubst tramp--test-message (fmt-string &rest arguments) "Emit a message into ERT *Messages*." @@ -3098,7 +3094,6 @@ 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. @@ -4586,8 +4581,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil))) (let ((default-directory tramp-test-temporary-file-directory) - (tmp-name1 (tramp--test-make-temp-name nil quoted)) - (tmp-name2 (tramp--test-make-temp-name 'local quoted)) + (tmp-name (tramp--test-make-temp-name nil quoted)) kill-buffer-query-functions proc) (with-no-warnings (should-not (make-process))) @@ -4615,13 +4609,13 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." ;; Simple process using a file. (unwind-protect (with-temp-buffer - (write-region "foo" nil tmp-name1) - (should (file-exists-p tmp-name1)) + (write-region "foo" nil tmp-name) + (should (file-exists-p tmp-name)) (setq proc (with-no-warnings (make-process :name "test2" :buffer (current-buffer) - :command `("cat" ,(file-name-nondirectory tmp-name1)) + :command `("cat" ,(file-name-nondirectory tmp-name)) :file-handler t))) (should (processp proc)) ;; Read output. @@ -4633,7 +4627,7 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." ;; Cleanup. (ignore-errors (delete-process proc) - (delete-file tmp-name1))) + (delete-file tmp-name))) ;; Process filter. (unwind-protect @@ -4697,11 +4691,17 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." :stderr stderr :file-handler t))) (should (processp proc)) - ;; Read stderr. + ;; Read output. (with-timeout (10 (tramp--test-timeout-handler)) (while (accept-process-output proc 0 nil t))) - (delete-process proc) + ;; Read stderr. (with-current-buffer stderr + (with-timeout (10 (tramp--test-timeout-handler)) + (while (not (string-match-p + "No such file or directory" (buffer-string))) + (while (accept-process-output + (get-buffer-process stderr) 0 nil t)))) + (delete-process proc) (should (string-match-p "cat:.* No such file or directory" (buffer-string))))) @@ -4712,30 +4712,29 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." ;; Process with stderr file. (unless (tramp-direct-async-process-p) - (dolist (tmpfile `(,tmp-name1 ,tmp-name2)) - (unwind-protect + (unwind-protect + (with-temp-buffer + (setq proc + (with-no-warnings + (make-process + :name "test6" :buffer (current-buffer) + :command '("cat" "/does-not-exist") + :stderr tmp-name + :file-handler t))) + (should (processp proc)) + ;; Read stderr. + (with-timeout (10 (tramp--test-timeout-handler)) + (while (accept-process-output proc nil nil t))) + (delete-process proc) (with-temp-buffer - (setq proc - (with-no-warnings - (make-process - :name "test6" :buffer (current-buffer) - :command '("cat" "/does-not-exist") - :stderr tmpfile - :file-handler t))) - (should (processp proc)) - ;; Read stderr. - (with-timeout (10 (tramp--test-timeout-handler)) - (while (accept-process-output proc nil nil t))) - (delete-process proc) - (with-temp-buffer - (insert-file-contents tmpfile) - (should - (string-match-p - "cat:.* No such file or directory" (buffer-string))))) + (insert-file-contents tmp-name) + (should + (string-match-p + "cat:.* No such file or directory" (buffer-string))))) - ;; Cleanup. - (ignore-errors (delete-process proc)) - (ignore-errors (delete-file tmpfile)))))))) + ;; Cleanup. + (ignore-errors (delete-process proc)) + (ignore-errors (delete-file tmp-name))))))) (tramp--test--deftest-direct-async-process tramp-test30-make-process "Check direct async `make-process'.") @@ -5846,13 +5845,6 @@ 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-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 - "^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. This requires restrictions of file name syntax." @@ -5886,6 +5878,7 @@ This requires restrictions of file name syntax." (make-directory tmp-name2) (dolist (elt files) + ;(tramp--test-message "%s" elt) (let* ((file1 (expand-file-name elt tmp-name1)) (file2 (expand-file-name elt tmp-name2)) (file3 (expand-file-name (concat elt "foo") tmp-name1))) @@ -6075,9 +6068,9 @@ This requires restrictions of file name syntax." "\tfoo bar baz\t") (t " foo\tbar baz\t")) "@foo@bar@baz@" - "$foo$bar$$baz$" + (unless (tramp--test-windows-nt-and-out-of-band-p) "$foo$bar$$baz$") "-foo-bar-baz-" - "%foo%bar%baz%" + (unless (tramp--test-windows-nt-and-out-of-band-p) "%foo%bar%baz%") "&foo&bar&baz&" (unless (or (tramp--test-ftp-p) (tramp--test-gvfs-p) @@ -6091,9 +6084,10 @@ This requires restrictions of file name syntax." "'foo'bar'baz'" "'foo\"bar'baz\"") "#foo~bar#baz~" - (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p)) - "!foo!bar!baz!" - "!foo|bar!baz|") + (unless (tramp--test-windows-nt-and-out-of-band-p) + (if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p)) + "!foo!bar!baz!" + "!foo|bar!baz|")) (if (or (tramp--test-gvfs-p) (tramp--test-rclone-p) (tramp--test-windows-nt-or-smb-p)) @@ -6114,7 +6108,6 @@ 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-scp-p))) (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (tramp--test-special-characters)) @@ -6126,7 +6119,6 @@ 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-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))) @@ -6145,7 +6137,6 @@ 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-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))) @@ -6167,7 +6158,6 @@ 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-scp-p))) (let ((tramp-connection-properties (append diff --git a/texi/tramp.texi b/texi/tramp.texi index 6319a2d..63b6eb8 100644 --- a/texi/tramp.texi +++ b/texi/tramp.texi @@ -2166,7 +2166,7 @@ commands for those hosts, the property @t{"posix"} should be set to The default value of this property is @code{t} (not specified in @code{tramp-methods}). If the remote host runs native MS Windows, -this propery has no effect. +this property has no effect. @item @t{"mount-point"} @@ -4504,9 +4504,9 @@ Note how @samp{%r}, @samp{%h} and @samp{%p} must be encoded as @samp{%%r}, @samp{%%h} and @samp{%%p}. @vindex tramp-use-ssh-controlmaster-options -If the @file{~/.ssh/config} is configured appropriately for the above -behavior, then any changes to @command{ssh} can be suppressed with -this @code{nil} setting: +If the @file{~/.ssh/config} file is configured appropriately for the +above behavior, then any changes to @command{ssh} can be suppressed +with this @code{nil} setting: @lisp (customize-set-variable 'tramp-use-ssh-controlmaster-options nil) @@ -4518,6 +4518,10 @@ This should also be set to @code{nil} if you use the @option{ProxyCommand} or @option{ProxyJump} options in your @command{ssh} configuration. +On MS Windows, @code{tramp-use-ssh-controlmaster-options} is set to +@code{nil} by default, because the MS Windows and MSYS2 +implementations of @command{OpenSSH} do not support this option properly. + @item On multi-hop connections, @value{tramp} does not use @command{ssh} @@ -5336,6 +5340,7 @@ The verbosity levels are @*@indent @w{ 8} connection properties @*@indent @w{ 9} test commands @*@indent @w{10} traces (huge) +@*@indent @w{11} call traces (maintainer only) With @code{tramp-verbose} greater than or equal to 4, messages are also written to a @value{tramp} debug buffer. Such debug buffers are @@ -5384,21 +5389,8 @@ The debug buffer is written as a file in your this option with care, because it could decrease the performance of @value{tramp} actions. -To enable stepping through @value{tramp} function call traces, they -have to be specifically enabled as shown in this code: - -@lisp -@group -(require 'trace) -(dolist (elt (all-completions "tramp-" obarray 'functionp)) - (trace-function-background (intern elt))) -(untrace-function 'tramp-read-passwd) -@end group -@end lisp - -The buffer @file{*trace-output*} contains the output from the function -call traces. Disable @code{tramp-read-passwd} to stop password -strings from being written to @file{*trace-output*}. +If @code{tramp-verbose} is greater than or equal to 11, @value{tramp} +function call traces are written to the buffer @file{*trace-output*}. @node GNU Free Documentation License diff --git a/texi/trampver.texi b/texi/trampver.texi index 168fdb1..c48d07b 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.4 +@set trampver 2.5.0.5 @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 61c40ff..d2ee729 100644 --- a/tramp-archive.el +++ b/tramp-archive.el @@ -345,8 +345,17 @@ arguments to pass to the OPERATION." (tramp-archive-run-real-handler operation args))))))) ;;;###autoload -(defalias - 'tramp-archive-autoload-file-name-handler #'tramp-autoload-file-name-handler) +(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args) + "Load Tramp archive file name handler, and perform OPERATION." + (when tramp-archive-enabled + ;; We cannot use `tramp-compat-temporary-file-directory' here due + ;; to autoload. When installing Tramp's GNU ELPA package, there + ;; might be an older, incompatible version active. We try to + ;; overload this. + (let ((default-directory temporary-file-directory) + (tramp-archive-autoload t)) + tramp-archive-autoload ; Silence byte compiler. + (apply #'tramp-autoload-file-name-handler operation args))))) ;;;###autoload (progn (defun tramp-register-archive-file-name-handler () diff --git a/tramp-cache.el b/tramp-cache.el index d754e73..4d5edc5 100644 --- a/tramp-cache.el +++ b/tramp-cache.el @@ -237,8 +237,7 @@ Return VALUE." ;;;###tramp-autoload (defun tramp-flush-file-properties (key file) "Remove all properties of FILE in the cache context of KEY." - (let* ((file (tramp-run-real-handler - #'directory-file-name (list file))) + (let* ((file (tramp-run-real-handler #'directory-file-name (list file))) (truename (tramp-get-file-property key file "file-truename" nil))) ;; Unify localname. Remove hop from `tramp-file-name' structure. (setq file (tramp-compat-file-name-unquote file) diff --git a/tramp-cmds.el b/tramp-cmds.el index a3cf6f3..d30d220 100644 --- a/tramp-cmds.el +++ b/tramp-cmds.el @@ -57,7 +57,9 @@ SYNTAX can be one of the symbols `default' (default), (all-completions "*tramp" (mapcar #'list (mapcar #'buffer-name (buffer-list)))) (all-completions - "*debug tramp" (mapcar #'list (mapcar #'buffer-name (buffer-list)))))) + "*debug tramp" (mapcar #'list (mapcar #'buffer-name (buffer-list)))) + (all-completions + "*trace tramp" (mapcar #'list (mapcar #'buffer-name (buffer-list)))))) (defun tramp-list-remote-buffers () "Return a list of all buffers with remote `default-directory'." @@ -496,7 +498,7 @@ This is needed if there are compatibility problems." ((dir (tramp-compat-funcall 'package-desc-dir (car (alist-get 'tramp (bound-and-true-p package-alist)))))) - (dolist (elc (directory-files dir 'full "\\.elc$")) + (dolist (elc (directory-files dir 'full "\\.elc\\'")) (delete-file elc)) (with-current-buffer (get-buffer-create byte-compile-log-buffer) (let ((inhibit-read-only t)) diff --git a/tramp-compat.el b/tramp-compat.el index fce9e0b..f727b8e 100644 --- a/tramp-compat.el +++ b/tramp-compat.el @@ -63,8 +63,6 @@ `(when (functionp ,function) (with-no-warnings (funcall ,function ,@arguments)))) -(put #'tramp-compat-funcall 'tramp-suppress-trace t) - (defsubst tramp-compat-temporary-file-directory () "Return name of directory for temporary files. It is the default value of `temporary-file-directory'." @@ -380,6 +378,9 @@ A nil value for either argument stands for the current time." (lambda (fromstring tostring instring) (replace-regexp-in-string (regexp-quote fromstring) tostring instring)))) +(dolist (elt (all-completions "tramp-compat-" obarray 'functionp)) + (put (intern elt) 'tramp-suppress-trace t)) + (add-hook 'tramp-unload-hook (lambda () (unload-feature 'tramp-loaddefs 'force) diff --git a/tramp-gvfs.el b/tramp-gvfs.el index c4ec112..f1d24dc 100644 --- a/tramp-gvfs.el +++ b/tramp-gvfs.el @@ -1089,7 +1089,7 @@ file names." 'copy filename newname ok-if-already-exists keep-date preserve-uid-gid preserve-extended-attributes) (tramp-run-real-handler - 'copy-file + #'copy-file (list filename newname ok-if-already-exists keep-date preserve-uid-gid preserve-extended-attributes)))) diff --git a/tramp-integration.el b/tramp-integration.el index 2931b4f..1726419 100644 --- a/tramp-integration.el +++ b/tramp-integration.el @@ -42,6 +42,8 @@ (declare-function tramp-dissect-file-name "tramp") (declare-function tramp-file-name-equal-p "tramp") (declare-function tramp-tramp-file-p "tramp") +(declare-function tramp-rename-files "tramp-cmds") +(declare-function tramp-rename-these-files "tramp-cmds") (defvar eshell-path-env) (defvar ido-read-file-name-non-ido) (defvar info-lookup-alist) @@ -184,14 +186,14 @@ NAME must be equal to `tramp-current-connection'." ;;; Integration of ido.el: (with-eval-after-load 'ido - (add-to-list 'ido-read-file-name-non-ido 'tramp-rename-files) - (add-to-list 'ido-read-file-name-non-ido 'tramp-these-rename-files) + (add-to-list 'ido-read-file-name-non-ido #'tramp-rename-files) + (add-to-list 'ido-read-file-name-non-ido #'tramp-rename-these-files) (add-hook 'tramp-integration-unload-hook (lambda () (setq ido-read-file-name-non-ido - (delq 'tramp-these-rename-files ido-read-file-name-non-ido) + (delq #'tramp-rename-these-files ido-read-file-name-non-ido) ido-read-file-name-non-ido - (delq 'tramp-rename-files ido-read-file-name-non-ido))))) + (delq #'tramp-rename-files ido-read-file-name-non-ido))))) ;;; Integration of ivy.el: @@ -199,17 +201,17 @@ NAME must be equal to `tramp-current-connection'." (add-to-list 'ivy-completing-read-handlers-alist '(tramp-rename-files . completing-read-default)) (add-to-list 'ivy-completing-read-handlers-alist - '(tramp-these-rename-files . completing-read-default)) + '(tramp-rename-these-files . completing-read-default)) (add-hook 'tramp-integration-unload-hook (lambda () (setq ivy-completing-read-handlers-alist (delete - (assq 'tramp-these-rename-files ivy-completing-read-handlers-alist) + (assq #'tramp-rename-these-files ivy-completing-read-handlers-alist) ivy-completing-read-handlers-alist) ivy-completing-read-handlers-alist (delete - (assq 'tramp-rename-files ivy-completing-read-handlers-alist) + (assq #'tramp-rename-files ivy-completing-read-handlers-alist) ivy-completing-read-handlers-alist))))) ;;; Integration of info-look.el: diff --git a/tramp-sh.el b/tramp-sh.el index b51ba11..29ed944 100644 --- a/tramp-sh.el +++ b/tramp-sh.el @@ -125,6 +125,15 @@ depends on the installed local ssh version. The string is used in `tramp-methods'.") +(defvar tramp-scp-strict-file-name-checking nil + "Which scp strict file name checking argument to use. + +It is the string \"-T\" if supported by the local scp (since +release 8.0), otherwise the string \"\". If it is nil, it will +be auto-detected by Tramp. + +The string is used in `tramp-methods'.") + ;; Initialize `tramp-methods' with the supported methods. ;;;###tramp-autoload (tramp--with-startup @@ -160,8 +169,8 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") - (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") - ("-r") ("%c"))) + (tramp-copy-args (("-P" "%p") ("-p" "%k") + ("%x") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -177,7 +186,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") - ("-q") ("-r") ("%c"))) + ("%x") ("-q") ("-r") ("%c"))) (tramp-copy-keep-date t) (tramp-copy-recursive t))) (add-to-list 'tramp-methods @@ -1834,7 +1843,7 @@ ID-FORMAT valid values are `string' and `integer'." 'copy filename newname ok-if-already-exists keep-date preserve-uid-gid preserve-extended-attributes) (tramp-run-real-handler - 'copy-file + #'copy-file (list filename newname ok-if-already-exists keep-date preserve-uid-gid preserve-extended-attributes)))) @@ -1875,7 +1884,7 @@ ID-FORMAT valid values are `string' and `integer'." ;; We must do it file-wise. (tramp-run-real-handler - 'copy-directory + #'copy-directory (list dirname newname keep-date parents copy-contents))) ;; When newname did exist, we have wrong cached values. @@ -2279,7 +2288,8 @@ The method used must be an out-of-band method." spec (list ?h (or host "") ?u (or user "") ?p (or port "") ?r listener ?c options ?k (if keep-date " " "") - ?n (concat "2>" (tramp-get-remote-null-device v))) + ?n (concat "2>" (tramp-get-remote-null-device v)) + ?x (tramp-scp-strict-file-name-checking v)) copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter v 'tramp-copy-keep-date) @@ -2361,11 +2371,12 @@ The method used must be an out-of-band method." ;; 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)) + p (let ((default-directory (tramp-compat-temporary-file-directory))) + (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) @@ -2712,13 +2723,12 @@ the result will be a local, non-Tramp, file name." ;; We use BUFFER also as connection buffer during setup. Because of ;; this, its original contents must be saved, and restored once ;; connection has been setup. -;; The complete STDERR buffer is available only when the process has -;; terminated. (defun tramp-sh-handle-make-process (&rest args) "Like `make-process' for Tramp files. -STDERR can also be a file name. If method parameter `tramp-direct-async' -and connection property \"direct-async-process\" are non-nil, an -alternative implementation will be used." +STDERR can also be a remote file name. If method parameter +`tramp-direct-async' and connection property +\"direct-async-process\" are non-nil, an alternative +implementation will be used." (if (tramp-direct-async-process-p args) (apply #'tramp-handle-make-process args) (when args @@ -2752,7 +2762,7 @@ alternative implementation will be used." (signal 'wrong-type-argument (list #'functionp sentinel))) (unless (or (null stderr) (bufferp stderr) (stringp stderr)) (signal 'wrong-type-argument (list #'bufferp stderr))) - (when (and (stringp stderr) (tramp-tramp-file-p stderr) + (when (and (stringp stderr) (not (tramp-equal-remote default-directory stderr))) (signal 'file-error (list "Wrong stderr" stderr))) @@ -2764,9 +2774,9 @@ alternative implementation will be used." ;; STDERR can also be a file name. (tmpstderr (and stderr - (if (and (stringp stderr) (tramp-tramp-file-p stderr)) - (tramp-unquote-file-local-name stderr) - (tramp-make-tramp-temp-file v)))) + (tramp-unquote-file-local-name + (if (stringp stderr) + stderr (tramp-make-tramp-temp-name v))))) (remote-tmpstderr (and tmpstderr (tramp-make-tramp-file-name v tmpstderr))) (program (car command)) @@ -2775,7 +2785,8 @@ alternative implementation will be used." ;; "-c", it might be that the arguments exceed the ;; command line length. Therefore, we modify the ;; command. - (heredoc (and (stringp program) + (heredoc (and (not (bufferp stderr)) + (stringp program) (string-match-p "sh$" program) (= (length args) 2) (string-equal "-c" (car args)) @@ -2839,6 +2850,23 @@ alternative implementation will be used." tramp-current-connection p) + ;; Handle error buffer. + (when (bufferp stderr) + (with-current-buffer stderr + (setq buffer-read-only nil)) + ;; Create named pipe. + (tramp-send-command v (format "mknod %s p" tmpstderr)) + ;; Create stderr process. + (make-process + :name (buffer-name stderr) + :buffer stderr + :command `("cat" ,tmpstderr) + :coding coding + :noquery t + :filter nil + :sentinel #'ignore + :file-handler t)) + (while (get-process name1) ;; NAME must be unique as process name. (setq i (1+ i) @@ -2867,14 +2895,11 @@ alternative implementation will be used." (if (symbolp coding) coding (cdr coding)))) (clear-visited-file-modtime) (narrow-to-region (point-max) (point-max)) - ;; We call `tramp-maybe-open-connection', in - ;; order to cleanup the prompt afterwards. (catch 'suppress - (tramp-maybe-open-connection v) - (setq p (tramp-get-connection-process v)) ;; Set the pid of the remote shell. This is ;; needed when sending signals remotely. (let ((pid (tramp-send-command-and-read v "echo $$"))) + (setq p (tramp-get-connection-process v)) (process-put p 'remote-pid pid) (tramp-set-connection-property p "remote-pid" pid)) ;; `tramp-maybe-open-connection' and @@ -2904,38 +2929,16 @@ alternative implementation will be used." (ignore-errors (set-process-query-on-exit-flag p (null noquery)) (set-marker (process-mark p) (point))) - ;; We must flush them here already; otherwise - ;; `rename-file', `delete-file' or - ;; `insert-file-contents' will fail. - (tramp-flush-connection-property v "process-name") - (tramp-flush-connection-property v "process-buffer") - ;; Copy tmpstderr file. - (when (and (stringp stderr) - (not (tramp-tramp-file-p stderr))) - (add-function - :after (process-sentinel p) - (lambda (_proc _msg) - (rename-file remote-tmpstderr stderr)))) - ;; Provide error buffer. This shows only - ;; initial error messages; messages arriving - ;; later on will be inserted when the process - ;; is deleted. The temporary file will exist - ;; until the process is deleted. + ;; Kill stderr process delete and named pipe. (when (bufferp stderr) - (with-current-buffer stderr - ;; 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 - (ignore-errors - (insert-file-contents-literally - remote-tmpstderr nil nil nil 'replace))) + (ignore-errors + (while (accept-process-output + (get-buffer-process stderr) 0 nil t)) + (delete-process (get-buffer-process stderr))) + (ignore-errors (delete-file remote-tmpstderr))))) ;; Return process. p))) @@ -4737,6 +4740,31 @@ Goes through the list `tramp-inline-compress-commands'." " -o ControlPersist=no"))))))))) tramp-ssh-controlmaster-options))) +(defun tramp-scp-strict-file-name-checking (vec) + "Return the strict file name checking argument of the local scp." + (cond + ;; No options to be computed. + ((null (assoc "%x" (tramp-get-method-parameter vec 'tramp-copy-args))) + "") + + ;; There is already a value to be used. + ((stringp tramp-scp-strict-file-name-checking) + tramp-scp-strict-file-name-checking) + + ;; Determine the options. + (t (setq tramp-scp-strict-file-name-checking "") + (let ((case-fold-search t)) + (ignore-errors + (when (executable-find "scp") + (with-tramp-progress-reporter + vec 4 "Computing strict file name argument" + (with-temp-buffer + (tramp-call-process vec "scp" nil t nil "-T") + (goto-char (point-min)) + (unless (search-forward-regexp "unknown option -- T" nil t) + (setq tramp-scp-strict-file-name-checking "-T"))))))) + tramp-scp-strict-file-name-checking))) + (defun tramp-timeout-session (vec) "Close the connection VEC after a session timeout. If there is just some editing, retry it after 5 seconds." @@ -4801,10 +4829,12 @@ connection if a previous connection has died for some reason." (with-tramp-progress-reporter vec 3 (if (zerop (length (tramp-file-name-user vec))) - (format "Opening connection for %s using %s" + (format "Opening connection %s for %s using %s" + process-name (tramp-file-name-host vec) (tramp-file-name-method vec)) - (format "Opening connection for %s@%s using %s" + (format "Opening connection %s for %s@%s using %s" + process-name (tramp-file-name-user vec) (tramp-file-name-host vec) (tramp-file-name-method vec))) @@ -5229,12 +5259,11 @@ 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> + ;; 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 "ftp$" method) - (setq localname (tramp-shell-quote-argument localname))) + (setq localname (tramp-unquote-shell-quote-argument localname))) (cond ((tramp-get-method-parameter vec 'tramp-remote-copy-program) localname) @@ -5905,8 +5934,6 @@ function cell is returned to be applied on a buffer." ;; session could be reused after a connection loss. Use dtach, or ;; screen, or tmux, or mosh. ;; -;; * Implement `:stderr' of `make-process' as pipe process. - ;; * One interesting solution (with other applications as well) would ;; be to stipulate, as a directory or connection-local variable, an ;; additional rc file on the remote machine that is sourced every diff --git a/tramp-sudoedit.el b/tramp-sudoedit.el index 66737e6..d641709 100644 --- a/tramp-sudoedit.el +++ b/tramp-sudoedit.el @@ -650,7 +650,7 @@ component is used as the target of the symlink." 'rename filename newname ok-if-already-exists 'keep-date 'preserve-uid-gid) (tramp-run-real-handler - 'rename-file (list filename newname ok-if-already-exists)))) + #'rename-file (list filename newname ok-if-already-exists)))) (defun tramp-sudoedit-handle-set-file-acl (filename acl-string) "Like `set-file-acl' for Tramp files." diff --git a/tramp.el b/tramp.el index 499789b..0b80175 100644 --- a/tramp.el +++ b/tramp.el @@ -109,7 +109,8 @@ Any level x includes messages for all levels 1 .. x-1. The levels are 7 file caching 8 connection properties 9 test commands -10 traces (huge)." +10 traces (huge) +11 call traces (maintainer only)." :type 'integer) (defcustom tramp-debug-to-file nil @@ -252,6 +253,8 @@ pair of the form (KEY VALUE). The following KEYs are defined: - \"%c\" adds additional `tramp-ssh-controlmaster-options' options for the first hop. - \"%n\" expands to \"2>/dev/null\". + - \"%x\" is replaced by the `tramp-scp-strict-file-name-checking' + argument if it is supported. The existence of `tramp-login-args', combined with the absence of `tramp-copy-args', is an indication that the @@ -1388,6 +1391,14 @@ calling HANDLER.") (cl-defstruct (tramp-file-name (:type list) :named) method user domain host port localname hop) +(put #'tramp-file-name-method 'tramp-suppress-trace t) +(put #'tramp-file-name-user 'tramp-suppress-trace t) +(put #'tramp-file-name-domain 'tramp-suppress-trace t) +(put #'tramp-file-name-host 'tramp-suppress-trace t) +(put #'tramp-file-name-port 'tramp-suppress-trace t) +(put #'tramp-file-name-localname 'tramp-suppress-trace t) +(put #'tramp-file-name-hop 'tramp-suppress-trace t) + (defun tramp-file-name-user-domain (vec) "Return user and domain components of VEC." (when (or (tramp-file-name-user vec) (tramp-file-name-domain vec)) @@ -1396,6 +1407,8 @@ calling HANDLER.") tramp-prefix-domain-format) (tramp-file-name-domain vec)))) +(put #'tramp-file-name-user-domain 'tramp-suppress-trace t) + (defun tramp-file-name-host-port (vec) "Return host and port components of VEC." (when (or (tramp-file-name-host vec) (tramp-file-name-port vec)) @@ -1404,12 +1417,16 @@ calling HANDLER.") tramp-prefix-port-format) (tramp-file-name-port vec)))) +(put #'tramp-file-name-host-port 'tramp-suppress-trace t) + (defun tramp-file-name-port-or-default (vec) "Return port component of VEC. If nil, return `tramp-default-port'." (or (tramp-file-name-port vec) (tramp-get-method-parameter vec 'tramp-default-port))) +(put #'tramp-file-name-port-or-default 'tramp-suppress-trace t) + ;; Comparison of file names is performed by `tramp-equal-remote'. (defun tramp-file-name-equal-p (vec1 vec2) "Check, whether VEC1 and VEC2 denote the same `tramp-file-name'." @@ -1456,6 +1473,8 @@ entry does not exist, return nil." (string-match-p tramp-file-name-regexp name) t)) +(put #'tramp-tramp-file-p 'tramp-suppress-trace t) + ;; This function bypasses the file name handler approach. It is NOT ;; recommended to use it in any package if not absolutely necessary. ;; However, it is more performant than `file-local-name', and might be @@ -1504,6 +1523,8 @@ This is METHOD, if non-nil. Otherwise, do a lookup in result (propertize result 'tramp-default t)))) +(put #'tramp-find-method 'tramp-suppress-trace t) + (defun tramp-find-user (method user host) "Return the right user string to use depending on METHOD and HOST. This is USER, if non-nil. Otherwise, do a lookup in @@ -1525,6 +1546,8 @@ This is USER, if non-nil. Otherwise, do a lookup in result (propertize result 'tramp-default t)))) +(put #'tramp-find-user 'tramp-suppress-trace t) + (defun tramp-find-host (method user host) "Return the right host string to use depending on METHOD and USER. This is HOST, if non-nil. Otherwise, do a lookup in @@ -1546,6 +1569,8 @@ This is HOST, if non-nil. Otherwise, do a lookup in result (propertize result 'tramp-default t)))) +(put #'tramp-find-host 'tramp-suppress-trace t) + (defun tramp-dissect-file-name (name &optional nodefault) "Return a `tramp-file-name' structure of NAME, a remote file name. The structure consists of method, user, domain, host, port, @@ -1610,6 +1635,8 @@ default values are used." (tramp-user-error v "Method `%s' is not supported for multi-hops." method))))))) +(put #'tramp-dissect-file-name 'tramp-suppress-trace t) + (defun tramp-dissect-hop-name (name &optional nodefault) "Return a `tramp-file-name' structure of `hop' part of NAME. See `tramp-dissect-file-name' for details." @@ -1627,6 +1654,8 @@ See `tramp-dissect-file-name' for details." ;; Return result. v)) +(put #'tramp-dissect-hop-name 'tramp-suppress-trace t) + (defun tramp-buffer-name (vec) "A name for the connection buffer VEC." (let ((method (tramp-file-name-method vec)) @@ -1636,6 +1665,8 @@ See `tramp-dissect-file-name' for details." (format "*tramp/%s %s@%s*" method user-domain host-port) (format "*tramp/%s %s*" method host-port)))) +(put #'tramp-buffer-name 'tramp-suppress-trace t) + (defun tramp-make-tramp-file-name (&rest args) "Construct a Tramp file name from ARGS. @@ -1803,6 +1834,8 @@ version, the function does nothing." (format "*debug tramp/%s %s@%s*" method user-domain host-port) (format "*debug tramp/%s %s*" method host-port)))) +(put #'tramp-debug-buffer-name 'tramp-suppress-trace t) + (defconst tramp-debug-outline-regexp (concat "[[:digit:]]+:[[:digit:]]+:[[:digit:]]+\\.[[:digit:]]+ " ;; Timestamp. @@ -1828,6 +1861,8 @@ Point must be at the beginning of a header line. The outline level is equal to the verbosity of the Tramp message." (1+ (string-to-number (match-string 2)))) +(put #'tramp-debug-outline-level 'tramp-suppress-trace t) + (defun tramp-get-debug-buffer (vec) "Get the debug buffer for VEC." (with-current-buffer (get-buffer-create (tramp-debug-buffer-name vec)) @@ -1853,12 +1888,25 @@ The outline level is equal to the verbosity of the Tramp message." (use-local-map special-mode-map)) (current-buffer))) +(put #'tramp-get-debug-buffer 'tramp-suppress-trace t) + (defun tramp-get-debug-file-name (vec) - "Get the debug buffer for VEC." + "Get the debug file name for VEC." (expand-file-name (tramp-compat-string-replace "/" " " (tramp-debug-buffer-name vec)) (tramp-compat-temporary-file-directory))) +(put #'tramp-get-debug-file-name 'tramp-suppress-trace t) + +(defun tramp-trace-buffer-name (vec) + "A name for the trace buffer for VEC." + (tramp-compat-string-replace "debug" "trace" (tramp-debug-buffer-name vec))) + +(put #'tramp-trace-buffer-name 'tramp-suppress-trace t) + +(defvar tramp-trace-functions nil + "A list of non-Tramp functions to be trace with tramp-verbose > 10.") + (defun tramp-debug-message (vec fmt-string &rest arguments) "Append message to debug buffer of VEC. Message is formatted with FMT-STRING as control string and the remaining @@ -1869,8 +1917,8 @@ ARGUMENTS to actually emit the message (if applicable)." (with-current-buffer (tramp-get-debug-buffer vec) (goto-char (point-max)) (let ((point (point))) - ;; Headline. (when (bobp) + ;; Headline. (insert (format ";; Emacs: %s Tramp: %s -*- mode: outline; coding: utf-8; -*-" @@ -1883,6 +1931,15 @@ ARGUMENTS to actually emit the message (if applicable)." (locate-library "tramp") (or tramp-repository-branch "") (or tramp-repository-version ""))))) + ;; Traces. + (when (>= tramp-verbose 11) + (dolist + (elt + (append + (mapcar #'intern (all-completions "tramp-" obarray 'functionp)) + tramp-trace-functions)) + (unless (get elt 'tramp-suppress-trace) + (trace-function-background elt)))) ;; Delete debug file. (when (and tramp-debug-to-file (tramp-get-debug-file-name vec)) (ignore-errors (delete-file (tramp-get-debug-file-name vec))))) @@ -2608,6 +2665,8 @@ Falls back to normal file name handler if no Tramp file name handler exists." ;; might be an older, incompatible version active. We try to ;; overload this. (let ((default-directory temporary-file-directory)) + (when (bound-and-true-p tramp-archive-autoload) + (load "tramp-archive" 'noerror 'nomessage)) (load "tramp" 'noerror 'nomessage))) (apply operation args))) @@ -2619,7 +2678,7 @@ Falls back to normal file name handler if no Tramp file name handler exists." "Add Tramp file name handlers to `file-name-handler-alist' during autoload." (add-to-list 'file-name-handler-alist (cons tramp-autoload-file-name-regexp - 'tramp-autoload-file-name-handler)) + #'tramp-autoload-file-name-handler)) (put #'tramp-autoload-file-name-handler 'safe-magic t))) ;;;###autoload (tramp-register-autoload-file-name-handlers) @@ -2831,7 +2890,7 @@ not in completion mode." result1 (ignore-errors (tramp-run-real-handler - 'file-name-all-completions (list filename directory)))))) + #'file-name-all-completions (list filename directory)))))) ;; Method, host name and user name completion for a file. (defun tramp-completion-handle-file-name-completion @@ -3252,7 +3311,7 @@ User is always nil." (tramp-compat-file-missing (tramp-dissect-file-name directory) directory)) ;; We must do it file-wise. (tramp-run-real-handler - 'copy-directory + #'copy-directory (list directory newname keep-date parents copy-contents))) (defun tramp-handle-directory-file-name (directory) @@ -5440,6 +5499,8 @@ Invokes `password-read' if available, `read-passwd' else." ;; Reenable the timers. (with-timeout-unsuspend stimers)))) +(put #'tramp-read-passwd 'tramp-suppress-trace t) + (defun tramp-clear-passwd (vec) "Clear password cache for connection related to VEC." (let ((method (tramp-file-name-method vec)) @@ -5454,6 +5515,8 @@ Invokes `password-read' if available, `read-passwd' else." :host ,host-port :port ,method)) (password-cache-remove (tramp-make-tramp-file-name vec 'noloc 'nohop)))) +(put #'tramp-clear-passwd 'tramp-suppress-trace t) + (defun tramp-time-diff (t1 t2) "Return the difference between the two times, in seconds. T1 and T2 are time values (as returned by `current-time' for example)." diff --git a/trampver.el b/trampver.el index ecf730d..6c041b2 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.4 +;; Version: 2.5.0.5 ;; 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.4" +(defconst tramp-version "2.5.0.5" "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.4 is not fit for %s" + (format "Tramp 2.5.0.5 is not fit for %s" (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x)))