From: Michael Albinus Date: Sat, 31 May 2025 13:08:06 +0000 (+0200) Subject: Fix Tramp bug#78508 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=aebbe52a8040751e10855ed5ddda8b61a194f51c;p=emacs.git Fix Tramp bug#78508 * lisp/net/tramp-container.el (tramp-methods) : * lisp/net/tramp-sh.el (tramp-methods) : * lisp/net/tramp-sshfs.el (tramp-methods) : Set TERM environment. (Bug#78508) * lisp/net/tramp-sh.el (tramp-find-executable): Handle superlong PATH. (tramp-set-remote-path): Simplify command. (tramp-timeout-session): Add ;;;###tramp-autoload cookie. * lisp/net/tramp-smb.el (tramp-smb-errors): Add string. (tramp-smb-winexe-program): Adapt docstring. (tramp-smb-handle-copy-directory, tramp-smb-handle-file-acl) (tramp-smb-handle-set-file-acl, tramp-smb-maybe-open-connection): Simplify argument handling. (tramp-smb-handle-process-file): Flush " process-exit-status" property. (tramp-smb-call-winexe): Set $winsize.Width to 102 only. * lisp/net/tramp.el (tramp-process-sentinel): Adapt docstring. Set " process-exit-status" property. * test/lisp/net/tramp-tests.el (tramp--test-enabled): Make it more robust. (tramp-test18-file-attributes) (tramp-test26-interactive-file-name-completion) (tramp-test26-file-name-completion-boundaries) (tramp-test35-remote-path): Adapt tests. (cherry picked from commit 5ce0e1372bb41ac83c513a632a57b3ffb643971e) --- diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 0078a2ed38b..6d686952c49 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -713,5 +713,7 @@ for all methods. Resulting data are derived from connection history." ;;; TODO: ;; ;; * Use multisession.el, starting with Emacs 29.1. +;; +;; Use `with-memoization', starting with Emacs 29.1. ;;; tramp-cache.el ends here diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el index f694423b2bb..4719eec4da9 100644 --- a/lisp/net/tramp-container.el +++ b/lisp/net/tramp-container.el @@ -551,6 +551,7 @@ see its function help for a description of the format." (tramp-login-args (("exec") ("-it") ("-u" "%u") + ("-e" ,(format "TERM=%s" tramp-terminal-type)) ("%h") ("%l"))) (tramp-direct-async (,tramp-default-remote-shell "-c")) @@ -565,6 +566,7 @@ see its function help for a description of the format." (tramp-login-args (("exec") ("-it") ("-u" "%u") + ("-e" ,(format "TERM=%s" tramp-terminal-type)) ("%h") ("%l"))) (tramp-direct-async (,tramp-default-remote-shell "-c")) @@ -583,6 +585,7 @@ see its function help for a description of the format." (tramp-login-args (("exec") ("-it") ("-u" "%u") + ("-e" ,(format "TERM=%s" tramp-terminal-type)) ("%h") ("%l"))) (tramp-direct-async (,tramp-default-remote-shell "-c")) @@ -597,6 +600,7 @@ see its function help for a description of the format." (tramp-login-args (("exec") ("-it") ("-u" "%u") + ("-e" ,(format "TERM=%s" tramp-terminal-type)) ("%h") ("%l"))) (tramp-direct-async (,tramp-default-remote-shell "-c")) @@ -754,6 +758,8 @@ see its function help for a description of the format." `(,tramp-apptainer-method (tramp-login-program ,tramp-apptainer-program) (tramp-login-args (("shell") + ("--env" + ,(format "TERM=%s" tramp-terminal-type)) ("instance://%h") ("%h"))) ; Needed for multi-hop check. (tramp-remote-shell ,tramp-default-remote-shell) @@ -777,6 +783,8 @@ see its function help for a description of the format." (tramp-login-args (("shell") ("-q") ("--uid" "%u") + ("-E" + ,(format "TERM=%s" tramp-terminal-type)) ("%h"))) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 5952e013e73..592a09d2e4e 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -190,7 +190,10 @@ The string is used in `tramp-methods'.") `("scp" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("%h"))) + ("-e" "none") + ("-o" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) + ("%h"))) (tramp-async-args (("-q"))) (tramp-direct-async ("-t" "-t")) (tramp-remote-shell ,tramp-default-remote-shell) @@ -208,6 +211,8 @@ The string is used in `tramp-methods'.") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("-t" "-t") ("-o" "RemoteCommand=\"%l\"") + ("-o" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell ,tramp-default-remote-shell) @@ -223,7 +228,10 @@ The string is used in `tramp-methods'.") `("rsync" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("%h"))) + ("-e" "none") + ("-o" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) + ("%h"))) (tramp-async-args (("-q"))) (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) @@ -254,7 +262,10 @@ The string is used in `tramp-methods'.") `("ssh" (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") - ("-e" "none") ("%h"))) + ("-e" "none") + ("-o" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) + ("%h"))) (tramp-async-args (("-q"))) (tramp-direct-async ("-t" "-t")) (tramp-remote-shell ,tramp-default-remote-shell) @@ -265,6 +276,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" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) ("-o" "RemoteCommand=\"%l\"") ("%h"))) (tramp-async-args (("-q"))) @@ -301,6 +314,7 @@ The string is used in `tramp-methods'.") ;; remote host echoes the command. ;; The "-p" argument doesn't work reliably, see Bug#50594. (tramp-login-args (("SUDO_PROMPT=P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":") + (,(format "TERM=%s" tramp-terminal-type)) ("sudo") ("-u" "%u") ("-s") ("-H") ("%l"))) (tramp-remote-shell ,tramp-default-remote-shell) @@ -4130,12 +4144,33 @@ This function expects to be in the right *tramp* buffer." (unless (char-equal ?~ (aref d 0)) (setq newdl (cons d newdl)))) (setq dirlist (nreverse newdl)))) - (when (tramp-send-command-and-check - vec (format "(unalias %s; %s command -v %s)" - progname - (if dirlist (concat "PATH=" (string-join dirlist ":")) "") - progname)) - (string-trim (tramp-get-buffer-string (tramp-get-connection-buffer vec))))) + (let ((command + (concat + (when dirlist (format "PATH=%s " (string-join dirlist ":"))) + "command -v " progname)) + (pipe-buf (tramp-get-remote-pipe-buf vec)) + tmpfile chunk chunksize) + (when (if (length< command pipe-buf) + (tramp-send-command-and-check vec command) + ;; Use a temporary file. We cannot use `write-region' + ;; because setting the remote path happens in the early + ;; connection handshake, and not all external tools are + ;; determined yet. + (setq command (concat command "\n") + tmpfile (tramp-make-tramp-temp-file vec)) + (while (not (string-empty-p command)) + (setq chunksize (min (length command) (/ pipe-buf 2)) + chunk (substring command 0 chunksize) + command (substring command chunksize)) + (tramp-send-command + vec (format "printf \"%%b\" \"$*\" %s >>%s" + (tramp-shell-quote-argument chunk) + (tramp-shell-quote-argument tmpfile)))) + (tramp-send-command-and-check + vec (format ". %s && rm -f %s" tmpfile tmpfile))) + + (string-trim + (tramp-get-buffer-string (tramp-get-connection-buffer vec)))))) ;; On hydra.nixos.org, the $PATH environment variable is too long to ;; send it. This is likely not due to PATH_MAX, but PIPE_BUF. We @@ -4169,12 +4204,11 @@ variable PATH." (setq chunksize (min (length command) (/ pipe-buf 2)) chunk (substring command 0 chunksize) command (substring command chunksize)) - (tramp-send-command vec (format - "printf \"%%b\" \"$*\" %s >>%s" - (tramp-shell-quote-argument chunk) - (tramp-shell-quote-argument tmpfile)))) - (tramp-send-command vec (format ". %s" tmpfile)) - (tramp-send-command vec (format "rm -f %s" tmpfile)))))) + (tramp-send-command + vec (format "printf \"%%b\" \"$*\" %s >>%s" + (tramp-shell-quote-argument chunk) + (tramp-shell-quote-argument tmpfile)))) + (tramp-send-command vec (format ". %s && rm -f %s" tmpfile tmpfile)))))) ;; ------------------------------------------------------------ ;; -- Communication with external shell -- @@ -5115,6 +5149,7 @@ Goes through the list `tramp-inline-compress-commands'." (t "-3"))) +;;;###tramp-autoload (defun tramp-timeout-session (vec) "Close the connection VEC after a session timeout. If there is just some editing, retry it after 5 seconds." diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 36d48f910a9..e9ee3228a6d 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -162,6 +162,7 @@ this variable \"client min protocol=NT1\"." "NT_STATUS_PASSWORD_MUST_CHANGE" "NT_STATUS_RESOURCE_NAME_NOT_FOUND" "NT_STATUS_REVISION_MISMATCH" + "NT_STATUS_RPC_SS_CONTEXT_MISMATCH" "NT_STATUS_SHARING_VIOLATION" "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE" "NT_STATUS_UNSUCCESSFUL" @@ -316,7 +317,7 @@ Operations not mentioned here will be handled by the default Emacs primitives.") ;; Options for remote processes via winexe. (defcustom tramp-smb-winexe-program "winexe" "Name of winexe client to run. -If it isn't found in the local $PATH, the absolute path of winexe +If it isn't found in the local $PATH, the absolute path of \"winexe\" shall be given. This is needed for remote processes." :group 'tramp :version "24.3" @@ -488,12 +489,13 @@ arguments to pass to the OPERATION." (args (list (concat "//" host "/" share) "-E")) (options tramp-smb-options)) - (if (tramp-string-empty-or-nil-p user) - (setq args (append args (list "-N"))) - (setq args (append args (list "-U" user)))) + (setq args + (append args + (if (tramp-string-empty-or-nil-p user) + (list "-N") + (list "-U" (if domain (concat domain "/" user) user))) + (when port (list "-p" port)))) - (when domain (setq args (append args (list "-W" domain)))) - (when port (setq args (append args (list "-p" port)))) (when tramp-smb-conf (setq args (append args (list "-s" tramp-smb-conf)))) (while options @@ -779,12 +781,13 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (args (list (concat "//" host "/" share) "-E")) (options tramp-smb-options)) - (if (tramp-string-empty-or-nil-p user) - (setq args (append args (list "-N"))) - (setq args (append args (list "-U" user)))) + (setq args + (append args + (if (tramp-string-empty-or-nil-p user) + (list "-N") + (list "-U" (if domain (concat domain "/" user) user))) + (when port (list "-p" port)))) - (when domain (setq args (append args (list "-W" domain)))) - (when port (setq args (append args (list "-p" port)))) (when tramp-smb-conf (setq args (append args (list "-s" tramp-smb-conf)))) (while options @@ -1251,6 +1254,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (tramp-set-connection-property v " process-buffer" (or outbuf (generate-new-buffer tramp-temp-buffer-name))) + (tramp-flush-connection-property v " process-exit-status") (with-current-buffer (tramp-get-connection-buffer v) ;; Preserve buffer contents. (narrow-to-region (point-max) (point-max)) @@ -1366,12 +1370,13 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (string-replace "\n" "," acl-string))) (options tramp-smb-options)) - (if (tramp-string-empty-or-nil-p user) - (setq args (append args (list "-N"))) - (setq args (append args (list "-U" user)))) + (setq args + (append args + (if (tramp-string-empty-or-nil-p user) + (list "-N") + (list "-U" (if domain (concat domain "/" user) user))) + (when port (list "-p" port)))) - (when domain (setq args (append args (list "-W" domain)))) - (when port (setq args (append args (list "-p" port)))) (when tramp-smb-conf (setq args (append args (list "-s" tramp-smb-conf)))) (while options @@ -1906,16 +1911,19 @@ If ARGUMENT is non-nil, use it as argument for (share (setq args (list (concat "//" host "/" share)))) (t (setq args (list "-g" "-L" host )))) - (if (tramp-string-empty-or-nil-p user) - (setq args (append args (list "-N"))) - (setq args (append args (list "-U" user)))) + (setq args + (append args + (if (tramp-string-empty-or-nil-p user) + (list "-N") + (list "-U" (if domain (concat domain "/" user) user))) + (when port (list "-p" port)))) - (when domain (setq args (append args (list "-W" domain)))) - (when port (setq args (append args (list "-p" port)))) (when tramp-smb-conf (setq args (append args (list "-s" tramp-smb-conf)))) (dolist (option options) (setq args (append args (list "--option" option)))) + ;; For debugging. + (setq args (append args (list "-d" "1"))) (when argument (setq args (append args (list argument)))) @@ -2026,6 +2034,8 @@ Removes smb prompt. Returns nil if an error message has appeared." (when (tramp-file-name-port vec) (tramp-error vec 'file-error "Port not supported for remote processes")) + ;; In case of "NT_STATUS_RPC_SS_CONTEXT_MISMATCH", the remote server + ;; is a Samba server. winexe cannot install the respective service there. (tramp-smb-maybe-open-connection vec (format @@ -2037,12 +2047,14 @@ Removes smb prompt. Returns nil if an error message has appeared." ;; Suppress "^M". Shouldn't we specify utf8? (set-process-coding-system (tramp-get-connection-process vec) 'raw-text-dos) - ;; Set width to 128. This avoids mixing prompt and long error messages. + ;; Set width to 128 ($bufsize.Width) or 102 ($winsize.Width), + ;; respectively. $winsize.Width cannot be larger. This avoids + ;; mixing prompt and long error messages. (tramp-smb-send-command vec "$rawui = (Get-Host).UI.RawUI") (tramp-smb-send-command vec "$bufsize = $rawui.BufferSize") (tramp-smb-send-command vec "$winsize = $rawui.WindowSize") (tramp-smb-send-command vec "$bufsize.Width = 128") - (tramp-smb-send-command vec "$winsize.Width = 128") + (tramp-smb-send-command vec "$winsize.Width = 102") (tramp-smb-send-command vec "$rawui.BufferSize = $bufsize") (tramp-smb-send-command vec "$rawui.WindowSize = $winsize")) @@ -2069,5 +2081,7 @@ Removes smb prompt. Returns nil if an error message has appeared." ;; several places, especially in `tramp-smb-handle-insert-directory'. ;; ;; * Keep a separate connection process per share. +;; +;; * Keep a permanent connection process for `process-file'. ;;; tramp-smb.el ends here diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el index b8e74a6348d..6bf5b8c01a0 100644 --- a/lisp/net/tramp-sshfs.el +++ b/lisp/net/tramp-sshfs.el @@ -62,6 +62,8 @@ (tramp-login-program "ssh") (tramp-login-args (("-q") ("-l" "%u") ("-p" "%p") ("-e" "none") ("%a" "%a") + ("-o" ,(format "SetEnv=\"TERM=%s\"" + tramp-terminal-type)) ("%h") ("%l"))) (tramp-direct-async t) (tramp-remote-shell ,tramp-default-remote-shell) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 58d6805f1b1..2ad6d916d71 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -6249,15 +6249,22 @@ the remote host use line-endings as defined in the variable (process-send-string p string))))))) (defun tramp-process-sentinel (proc event) - "Flush file caches and remove shell prompt." + "Flush file caches and remove shell prompt. +Set exit status of PROC as connection property \" process-exit-status\"." (unless (process-live-p proc) (let ((vec (process-get proc 'tramp-vector)) (buf (process-buffer proc)) (prompt (tramp-get-connection-property proc "prompt"))) (when vec - (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) + (tramp-message + vec 5 "Sentinel called: `%S' event: `%s' status: %s" + proc event (process-exit-status proc)) (tramp-flush-connection-properties proc) - (tramp-flush-directory-properties vec "/")) + (tramp-flush-directory-properties vec "/") + ;; Sometimes, the process has been deleted already before we + ;; can retrieve the exit status. + (tramp-set-connection-property + vec " process-exit-status" (process-exit-status proc))) (when (buffer-live-p buf) (with-current-buffer buf (when (and prompt (tramp-search-regexp (rx (literal prompt))))