diff options
Diffstat (limited to 'lisp/net/tramp-sh.el')
-rw-r--r-- | lisp/net/tramp-sh.el | 353 |
1 files changed, 174 insertions, 179 deletions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 502040902e1..9895af92502 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -81,13 +81,6 @@ the default storage location, e.g. \"$HOME/.sh_history\"." (const :tag "Unset HISTFILE" t) (string :tag "Redirect to a file"))) -;;;###tramp-autoload -(defconst tramp-display-escape-sequence-regexp (rx "\e" (+ (any ";[" digit)) "m") - "Terminal control escape sequences for display attributes.") - -(defconst tramp-device-escape-sequence-regexp (rx "\e" (+ (any "[" digit)) "n") - "Terminal control escape sequences for device status.") - ;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for ;; root users. It uses the `$' character for other users. In order ;; to guarantee a proper prompt, we use "#$ " for the prompt. @@ -109,11 +102,18 @@ detected as prompt when being sent on echoing hosts, therefore.") (defcustom tramp-use-ssh-controlmaster-options (not (eq system-type 'windows-nt)) "Whether to use `tramp-ssh-controlmaster-options'. +Set it to t, if you want Tramp to apply these options. Set it to nil, if you use Control* or Proxy* options in your ssh -configuration." +configuration. +Set it to `suppress' if you want to disable settings in your +\"~/.ssh/config¸\"." :group 'tramp - :version "28.1" - :type 'boolean) + :version "29.2" + :type '(choice (const :tag "Set ControlMaster" t) + (const :tag "Don't set ControlMaster" nil) + (const :tag "Suppress ControlMaster" suppress)) + ;; Check with (safe-local-variable-p 'tramp-use-ssh-controlmaster-options 'suppress) + :safe (lambda (val) (and (memq val '(t nil suppress)) t))) (defvar tramp-ssh-controlmaster-options nil "Which ssh Control* arguments to use. @@ -124,8 +124,8 @@ If it is a string, it should have the form spec must be doubled, because the string is used as format string. Otherwise, it will be auto-detected by Tramp, if -`tramp-use-ssh-controlmaster-options' is non-nil. The value -depends on the installed local ssh version. +`tramp-use-ssh-controlmaster-options' is t. The value depends on +the installed local ssh version. The string is used in `tramp-methods'.") @@ -632,7 +632,6 @@ foreach $f (@files) { print \"$f\\n\"; } } -print \"ok\\n\" ' \"$1\" %n" "Perl script to produce output suitable for use with `file-name-all-completions' on the remote file system. @@ -1159,8 +1158,8 @@ component is used as the target of the symlink." (unless ln (tramp-error v 'file-error - (concat "Making a symbolic link. " - "ln(1) does not exist on the remote host."))) + (concat "Making a symbolic link: " + "ln(1) does not exist on the remote host"))) ;; Do the 'confirm if exists' thing. (when (file-exists-p linkname) @@ -1252,20 +1251,13 @@ component is used as the target of the symlink." (defun tramp-sh-handle-file-exists-p (filename) "Like `file-exists-p' for Tramp files." - ;; `file-exists-p' is used as predicate in file name completion. - ;; We don't want to run it when `non-essential' is t, or there is - ;; no connection process yet. - (when (tramp-connectable-p filename) - (with-parsed-tramp-file-name (expand-file-name filename) nil - (with-tramp-file-property v localname "file-exists-p" - (if (tramp-file-property-p v localname "file-attributes") - (not (null (tramp-get-file-property v localname "file-attributes"))) - (tramp-send-command-and-check - v - (format - "%s %s" - (tramp-get-file-exists-command v) - (tramp-shell-quote-argument localname)))))))) + (tramp-skeleton-file-exists-p filename + (tramp-send-command-and-check + v + (format + "%s %s" + (tramp-get-file-exists-command v) + (tramp-shell-quote-argument localname))))) (defun tramp-sh-handle-file-attributes (filename &optional id-format) "Like `file-attributes' for Tramp files." @@ -1724,7 +1716,7 @@ ID-FORMAT valid values are `string' and `integer'." (if (tramp-file-property-p v localname "file-attributes") (or (tramp-check-cached-permissions v ?x) (tramp-check-cached-permissions v ?s)) - (tramp-run-test "-x" filename))))) + (tramp-run-test v "-x" localname))))) (defun tramp-sh-handle-file-readable-p (filename) "Like `file-readable-p' for Tramp files." @@ -1734,7 +1726,7 @@ ID-FORMAT valid values are `string' and `integer'." ;; satisfied without remote operation. (if (tramp-file-property-p v localname "file-attributes") (tramp-handle-file-readable-p filename) - (tramp-run-test "-r" filename))))) + (tramp-run-test v "-r" localname))))) ;; Functions implemented using the basic functions above. @@ -1745,7 +1737,7 @@ ID-FORMAT valid values are `string' and `integer'." ;; Sometimes, when a connection is not established yet, it is ;; desirable to return t immediately for "/method:foo:". It can ;; be expected that this is always a directory. - (or (zerop (length localname)) + (or (tramp-string-empty-or-nil-p localname) (with-tramp-file-property v localname "file-directory-p" (if-let ((truename (tramp-get-file-property v localname "file-truename")) @@ -1755,7 +1747,7 @@ ID-FORMAT valid values are `string' and `integer'." (tramp-get-file-property v (tramp-file-local-name truename) "file-attributes")) t) - (tramp-run-test "-d" filename)))))) + (tramp-run-test v "-d" localname)))))) (defun tramp-sh-handle-file-writable-p (filename) "Like `file-writable-p' for Tramp files." @@ -1766,7 +1758,7 @@ ID-FORMAT valid values are `string' and `integer'." ;; Examine `file-attributes' cache to see if request can ;; be satisfied without remote operation. (tramp-check-cached-permissions v ?w) - (tramp-run-test "-w" filename)) + (tramp-run-test v "-w" localname)) ;; If file doesn't exist, check if directory is writable. (and (file-directory-p (file-name-directory filename)) @@ -1840,64 +1832,43 @@ ID-FORMAT valid values are `string' and `integer'." (with-parsed-tramp-file-name (expand-file-name directory) nil (when (and (not (tramp-compat-string-search "/" filename)) (tramp-connectable-p v)) - (all-completions - filename - (with-tramp-file-property v localname "file-name-all-completions" - (let (result) - ;; Get a list of directories and files, including reliably - ;; tagging the directories with a trailing "/". Because I - ;; rock. --daniel@danann.net - (tramp-send-command - v - (if (tramp-get-remote-perl v) - (progn - (tramp-maybe-send-script - v tramp-perl-file-name-all-completions - "tramp_perl_file_name_all_completions") - (format "tramp_perl_file_name_all_completions %s" - (tramp-shell-quote-argument localname))) - - (format (concat - "(cd %s 2>&1 && %s -a 2>%s" - " | while IFS= read f; do" - " if %s -d \"$f\" 2>%s;" - " then \\echo \"$f/\"; else \\echo \"$f\"; fi; done" - " && \\echo ok) || \\echo fail") - (tramp-shell-quote-argument localname) - (tramp-get-ls-command v) - (tramp-get-remote-null-device v) - (tramp-get-test-command v) - (tramp-get-remote-null-device v)))) - - ;; Now grab the output. - (with-current-buffer (tramp-get-buffer v) - (goto-char (point-max)) - - ;; Check result code, found in last line of output. - (forward-line -1) - (if (looking-at-p (rx bol "fail" eol)) - (progn - ;; Grab error message from line before last line - ;; (it was put there by `cd 2>&1'). - (forward-line -1) - (tramp-error - v 'file-error - "tramp-sh-handle-file-name-all-completions: %s" - (buffer-substring (point) (line-end-position)))) - ;; For peace of mind, if buffer doesn't end in `fail' - ;; then it should end in `ok'. If neither are in the - ;; buffer something went seriously wrong on the remote - ;; side. - (unless (looking-at-p (rx bol "ok" eol)) - (tramp-error - v 'file-error - (concat "tramp-sh-handle-file-name-all-completions: " - "internal error accessing `%s': `%s'") - (tramp-shell-quote-argument localname) (buffer-string)))) - - (while (zerop (forward-line -1)) - (push (buffer-substring (point) (line-end-position)) result))) - result)))))) + (unless (tramp-compat-string-search "/" filename) + (tramp-compat-ignore-error file-missing + (all-completions + filename + (with-tramp-file-property v localname "file-name-all-completions" + (let (result) + ;; Get a list of directories and files, including + ;; reliably tagging the directories with a trailing "/". + ;; Because I rock. --daniel@danann.net + (when (tramp-send-command-and-check + v + (if (tramp-get-remote-perl v) + (progn + (tramp-maybe-send-script + v tramp-perl-file-name-all-completions + "tramp_perl_file_name_all_completions") + (format "tramp_perl_file_name_all_completions %s" + (tramp-shell-quote-argument localname))) + + (format (concat + "cd %s 2>&1 && %s -a 2>%s" + " | while IFS= read f; do" + " if %s -d \"$f\" 2>%s;" + " then \\echo \"$f/\"; else \\echo \"$f\"; fi;" + " done") + (tramp-shell-quote-argument localname) + (tramp-get-ls-command v) + (tramp-get-remote-null-device v) + (tramp-get-test-command v) + (tramp-get-remote-null-device v)))) + + ;; Now grab the output. + (with-current-buffer (tramp-get-buffer v) + (goto-char (point-max)) + (while (zerop (forward-line -1)) + (push (buffer-substring (point) (line-end-position)) result))) + result))))))))) ;; cp, mv and ln @@ -2240,7 +2211,7 @@ the uid and gid from FILENAME." cmd-result) (tramp-error-with-buffer nil v 'file-error - "Copying directly failed, see buffer `%s' for details." + "Copying directly failed, see buffer `%s' for details" (buffer-name))))) ;; We are on the local host. @@ -2295,7 +2266,7 @@ the uid and gid from FILENAME." "%s %s %s" cmd (tramp-shell-quote-argument localname1) (tramp-shell-quote-argument tmpfile)) - "Copying directly failed, see buffer `%s' for details." + "Copying directly failed, see buffer `%s' for details" (tramp-get-buffer v)) ;; We must change the ownership as remote user. ;; Since this does not work reliable, we also @@ -2328,7 +2299,7 @@ the uid and gid from FILENAME." "cp -f -p %s %s" (tramp-shell-quote-argument tmpfile) (tramp-shell-quote-argument localname2)) - "Copying directly failed, see buffer `%s' for details." + "Copying directly failed, see buffer `%s' for details" (tramp-get-buffer v))) (t1 (tramp-run-real-handler @@ -2363,7 +2334,7 @@ The method used must be an out-of-band method." copy-program copy-args copy-env copy-keep-date listener spec options source target remote-copy-program remote-copy-args p) - (if (and v1 v2 (zerop (length (tramp-scp-direct-remote-copying v1 v2)))) + (if (and v1 v2 (string-empty-p (tramp-scp-direct-remote-copying v1 v2))) ;; Both are Tramp files. We cannot use direct remote copying. (let* ((dir-flag (file-directory-p filename)) @@ -2523,7 +2494,11 @@ The method used must be an out-of-band method." (tramp-get-connection-buffer v) copy-program copy-args))) (tramp-message v 6 "%s" (string-join (process-command p) " ")) - (process-put p 'vector v) + (process-put p 'tramp-vector v) + ;; This is neded for ssh or PuTTY based processes, and + ;; only if the respective options are set. Perhaps, + ;; the setting could be more fine-grained. + ;; (process-put p 'tramp-shared-socket t) (process-put p 'adjust-window-size-function #'ignore) (set-process-query-on-exit-flag p nil) @@ -2673,7 +2648,7 @@ The method used must be an out-of-band method." (setq switches (append switches (split-string (tramp-sh--quoting-style-options v)))) (unless (tramp-get-ls-command-with v "--dired") - (setq switches (delete "--dired" switches))) + (setq switches (delete "-N" (delete "--dired" switches)))) (when wildcard (setq wildcard (tramp-run-real-handler #'file-name-nondirectory (list localname))) @@ -2711,9 +2686,9 @@ The method used must be an out-of-band method." (tramp-get-ls-command v) switches (if (or wildcard - (zerop (length - (tramp-run-real-handler - #'file-name-nondirectory (list localname))))) + (tramp-string-empty-or-nil-p + (tramp-run-real-handler + #'file-name-nondirectory (list localname)))) "" (tramp-shell-quote-argument (tramp-run-real-handler @@ -2761,7 +2736,7 @@ The method used must be an out-of-band method." (unless (tramp-compat-string-search "color" (tramp-get-connection-property v "ls" "")) (goto-char (point-min)) - (while (re-search-forward tramp-display-escape-sequence-regexp nil t) + (while (re-search-forward ansi-color-control-seq-regexp nil t) (replace-match ""))) ;; Now decode what read if necessary. Stolen from `insert-directory'. @@ -2830,13 +2805,15 @@ the result will be a local, non-Tramp, file name." ;; If DIR is not given, use `default-directory' or "/". (setq dir (or dir default-directory "/")) ;; Handle empty NAME. - (when (zerop (length name)) (setq name ".")) + (when (string-empty-p name) + (setq name ".")) ;; On MS Windows, some special file names are not returned properly ;; by `file-name-absolute-p'. If `tramp-syntax' is `simplified', ;; there could be the false positive "/:". (if (or (and (eq system-type 'windows-nt) (string-match-p - (tramp-compat-rx bol (| (: alpha ":") (: (literal null-device) eol))) + (tramp-compat-rx + bol (| (: alpha ":") (: (literal (or null-device "")) eol))) name)) (and (not (tramp-tramp-file-p name)) (not (tramp-tramp-file-p dir)))) @@ -2868,7 +2845,7 @@ the result will be a local, non-Tramp, file name." ;; the default user name for tilde expansion is not ;; appropriate either, because ssh and companions might ;; use a user name from the config file. - (when (and (zerop (length uname)) + (when (and (tramp-string-empty-or-nil-p uname) (string-match-p (rx bos "su" (? "do") eos) method)) (setq uname user)) (when (setq hname (tramp-get-home-directory v uname)) @@ -2969,7 +2946,7 @@ implementation will be used." (heredoc (and (not (bufferp stderr)) (stringp program) (string-match-p (rx "sh" eol) program) - (= (length args) 2) + (tramp-compat-length= args 2) (string-equal "-c" (car args)) ;; Don't if there is a quoted string. (not @@ -2979,7 +2956,7 @@ implementation will be used." ;; When PROGRAM is nil, we just provide a tty. (args (if (not heredoc) args (let ((i 250)) - (while (and (< i (length (cadr args))) + (while (and (not (tramp-compat-length< (cadr args) i)) (string-match " " (cadr args) i)) (setcdr args @@ -3095,13 +3072,20 @@ implementation will be used." (process-put p 'remote-pid pid) (tramp-set-connection-property p "remote-pid" pid)) - ;; Disable carriage return to newline - ;; translation. This does not work on - ;; macOS, see Bug#50748. - (when (and (memq connection-type '(nil pipe)) - (not - (tramp-check-remote-uname v "Darwin"))) - (tramp-send-command v "stty -icrnl")) + (when (memq connection-type '(nil pipe)) + ;; Disable carriage return to newline + ;; translation. This does not work on + ;; macOS, see Bug#50748. + ;; We must also disable buffering, + ;; otherwise strings larger than 4096 + ;; bytes, sent by the process, could + ;; block, see termios(3) and Bug#61341. + ;; FIXME: Shall we rather use "stty raw"? + (if (tramp-check-remote-uname v "Darwin") + (tramp-send-command + v "stty -icanon min 1 time 0") + (tramp-send-command + v "stty -icrnl -icanon min 1 time 0"))) ;; `tramp-maybe-open-connection' and ;; `tramp-send-command-and-read' could ;; have trashed the connection buffer. @@ -3236,7 +3220,7 @@ implementation will be used." (if (tramp-compat-string-search "=" elt) (setq env (append env `(,elt))) (setq uenv (cons elt uenv))))) - (setenv-internal env "INSIDE_EMACS" (tramp-inside-emacs) 'keep) + (setq env (setenv-internal env "INSIDE_EMACS" (tramp-inside-emacs) 'keep)) (when env (setq command (format @@ -3861,16 +3845,20 @@ Fall back to normal file name handler if no Tramp handler exists." "`%s' failed to start on remote host" (string-join sequence " ")) (tramp-message v 6 "Run `%s', %S" (string-join sequence " ") p) - (process-put p 'vector v) + (process-put p 'tramp-vector v) + ;; This is neded for ssh or PuTTY based processes, and only if + ;; the respective options are set. Perhaps, the setting could + ;; be more fine-grained. + ;; (process-put p 'tramp-shared-socket t) ;; Needed for process filter. - (process-put p 'events events) - (process-put p 'watch-name localname) + (process-put p 'tramp-events events) + (process-put p 'tramp-watch-name localname) (set-process-query-on-exit-flag p nil) (set-process-filter p filter) (set-process-sentinel p #'tramp-file-notify-process-sentinel) ;; There might be an error if the monitor is not supported. ;; Give the filter a chance to read the output. - (while (tramp-accept-process-output p 0)) + (while (tramp-accept-process-output p)) (unless (process-live-p p) (tramp-error p 'file-notify-error "Monitoring not supported for `%s'" file-name)) @@ -3878,10 +3866,10 @@ Fall back to normal file name handler if no Tramp handler exists." (defun tramp-sh-gio-monitor-process-filter (proc string) "Read output from \"gio monitor\" and add corresponding `file-notify' events." - (let ((events (process-get proc 'events)) + (let ((events (process-get proc 'tramp-events)) (remote-prefix (file-remote-p (tramp-get-default-directory (process-buffer proc)))) - (rest-string (process-get proc 'rest-string)) + (rest-string (process-get proc 'tramp-rest-string)) pos) (when rest-string (tramp-message proc 10 "Previous string:\n%s" rest-string)) @@ -3961,15 +3949,15 @@ Fall back to normal file name handler if no Tramp handler exists." ;; Save rest of the string. (while (string-match (rx bol "\n") string) (setq string (replace-match "" nil nil string))) - (when (zerop (length string)) (setq string nil)) + (when (string-empty-p string) (setq string nil)) (when string (tramp-message proc 10 "Rest string:\n%s" string)) - (process-put proc 'rest-string string))) + (process-put proc 'tramp-rest-string string))) (defun tramp-sh-inotifywait-process-filter (proc string) "Read output from \"inotifywait\" and add corresponding `file-notify' events." - (let ((events (process-get proc 'events))) + (let ((events (process-get proc 'tramp-events))) (tramp-message proc 6 "%S\n%s" proc string) - (dolist (line (split-string string "[\n\r]+" 'omit)) + (dolist (line (split-string string (rx (+ (any "\r\n"))) 'omit)) ;; Check, whether there is a problem. (unless (string-match (rx bol (+ (not blank)) (+ blank) (group (+ (not blank))) @@ -3986,7 +3974,8 @@ Fall back to normal file name handler if no Tramp handler exists." (tramp-compat-string-replace "_" "-" (downcase x)))) (split-string (match-string 1 line) "," 'omit)) (or (match-string 2 line) - (file-name-nondirectory (process-get proc 'watch-name)))))) + (file-name-nondirectory + (process-get proc 'tramp-watch-name)))))) ;; Usually, we would add an Emacs event now. Unfortunately, ;; `unread-command-events' does not accept several events at ;; once. Therefore, we apply the handler directly. @@ -4132,17 +4121,14 @@ Only send the definition if it has not already been done." (tramp-set-connection-property (tramp-get-connection-process vec) "scripts" (cons name scripts)))))) -(defun tramp-run-test (switch filename) - "Run `test' on the remote system, given a SWITCH and a FILENAME. +(defun tramp-run-test (vec switch localname) + "Run `test' on the remote system VEC, given a SWITCH and a LOCALNAME. Returns the exit code of the `test' program." - (with-parsed-tramp-file-name filename nil - (tramp-send-command-and-check - v - (format - "%s %s %s" - (tramp-get-test-command v) - switch - (tramp-shell-quote-argument localname))))) + (tramp-send-command-and-check + vec + (format + "%s %s %s" + (tramp-get-test-command vec) switch (tramp-shell-quote-argument localname)))) (defun tramp-find-executable (vec progname dirlist &optional ignore-tilde ignore-path) @@ -4217,7 +4203,7 @@ variable PATH." 'noerror))) tmpfile chunk chunksize) (tramp-message vec 5 "Setting $PATH environment variable") - (if (< (length command) pipe-buf) + (if (tramp-compat-length< command pipe-buf) (tramp-send-command vec command) ;; Use a temporary file. We cannot use `write-region' because ;; setting the remote path happens in the early connection @@ -4432,12 +4418,13 @@ file exists and nonzero exit status otherwise." "Wait for shell prompt and barf if none appears. Looks at process PROC to see if a shell prompt appears in TIMEOUT seconds. If not, it produces an error message with the given ERROR-ARGS." - (let ((vec (process-get proc 'vector))) + (let ((vec (process-get proc 'tramp-vector))) (condition-case nil (tramp-wait-for-regexp proc timeout (tramp-compat-rx (| (regexp shell-prompt-pattern) (regexp tramp-shell-prompt-pattern)) + (? (regexp ansi-color-control-seq-regexp)) eos)) (error (delete-process proc) @@ -4608,7 +4595,7 @@ process to set up. VEC specifies the connection." ;; Set `remote-tty' process property. (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror))) - (unless (zerop (length tty)) + (unless (tramp-string-empty-or-nil-p tty) (process-put proc 'remote-tty tty) (tramp-set-connection-property proc "remote-tty" tty))) @@ -4942,6 +4929,16 @@ Goes through the list `tramp-inline-compress-commands'." (tramp-message vec 2 "Couldn't find an inline transfer compress command"))))) +(defun tramp-ssh-option-exists-p (vec option) + "Check, whether local ssh OPTION is applicable." + ;; We don't want to cache it persistently. + (with-tramp-connection-property nil option + ;; "ssh -G" is introduced in OpenSSH 6.7. + ;; We use a non-existing IP address for check, in order to avoid + ;; useless connections, and DNS timeouts. + (zerop + (tramp-call-process vec "ssh" nil nil nil "-G" "-o" option "0.0.0.1")))) + (defun tramp-ssh-controlmaster-options (vec) "Return the Control* arguments of the local ssh." (cond @@ -4951,40 +4948,34 @@ Goes through the list `tramp-inline-compress-commands'." "") ;; There is already a value to be used. - ((stringp tramp-ssh-controlmaster-options) tramp-ssh-controlmaster-options) + ((and (eq tramp-use-ssh-controlmaster-options t) + (stringp tramp-ssh-controlmaster-options)) + tramp-ssh-controlmaster-options) + + ;; We can't auto-compute the options. + ((ignore-errors + (not (tramp-ssh-option-exists-p vec "ControlMaster=auto"))) + "") ;; Determine the options. - (t (setq tramp-ssh-controlmaster-options "") - (let ((case-fold-search t)) - (ignore-errors - (with-tramp-progress-reporter - vec 4 "Computing ControlMaster options" - ;; We use a non-existing IP address, in order to avoid - ;; useless connections, and DNS timeouts. - (when (zerop - (tramp-call-process - vec "ssh" nil nil nil - "-G" "-o" "ControlMaster=auto" "0.0.0.1")) - (setq tramp-ssh-controlmaster-options - "-o ControlMaster=auto") - (if (zerop - (tramp-call-process - vec "ssh" nil nil nil - "-G" "-o" "ControlPath=tramp.%C" "0.0.0.1")) - (setq tramp-ssh-controlmaster-options - (concat tramp-ssh-controlmaster-options - " -o ControlPath=tramp.%%C")) - (setq tramp-ssh-controlmaster-options - (concat tramp-ssh-controlmaster-options - " -o ControlPath=tramp.%%r@%%h:%%p"))) - (when (zerop - (tramp-call-process - vec "ssh" nil nil nil - "-G" "-o" "ControlPersist=no" "0.0.0.1")) - (setq tramp-ssh-controlmaster-options - (concat tramp-ssh-controlmaster-options - " -o ControlPersist=no"))))))) - tramp-ssh-controlmaster-options))) + (t (ignore-errors + ;; ControlMaster and ControlPath options are introduced in OpenSSH 3.9. + (concat + "-o ControlMaster=" + (if (eq tramp-use-ssh-controlmaster-options 'suppress) + "no" "auto") + + " -o ControlPath=" + (if (eq tramp-use-ssh-controlmaster-options 'suppress) + "none" + ;; Hashed tokens are introduced in OpenSSH 6.7. + (if (tramp-ssh-option-exists-p vec "ControlPath=tramp.%C") + "tramp.%%C" "tramp.%%r@%%h:%%p")) + + ;; ControlPersist option is introduced in OpenSSH 5.6. + (when (and (not (eq tramp-use-ssh-controlmaster-options 'suppress)) + (tramp-ssh-option-exists-p vec "ControlPersist=no")) + " -o ControlPersist=no")))))) (defun tramp-scp-strict-file-name-checking (vec) "Return the strict file name checking argument of the local scp." @@ -5181,7 +5172,7 @@ connection if a previous connection has died for some reason." (unless (process-live-p p) (with-tramp-progress-reporter vec 3 - (if (zerop (length (tramp-file-name-user vec))) + (if (tramp-string-empty-or-nil-p (tramp-file-name-user vec)) (format "Opening connection %s for %s using %s" process-name (tramp-file-name-host vec) @@ -5238,7 +5229,11 @@ connection if a previous connection has died for some reason." ;; Set sentinel and query flag. Initialize variables. (set-process-sentinel p #'tramp-process-sentinel) - (process-put p 'vector vec) + (process-put p 'tramp-vector vec) + ;; This is neded for ssh or PuTTY based processes, and + ;; only if the respective options are set. Perhaps, + ;; the setting could be more fine-grained. + ;; (process-put p 'tramp-shared-socket t) (process-put p 'adjust-window-size-function #'ignore) (set-process-query-on-exit-flag p nil) (setq tramp-current-connection (cons vec (current-time))) @@ -5405,14 +5400,14 @@ function waits for output unless NOOUTPUT is set." (tramp-error proc 'file-error "Process `%s' not available, try again" proc)) (with-current-buffer (process-buffer proc) (let* (;; Initially, `tramp-end-of-output' is "#$ ". There might - ;; be leading escape sequences, which must be ignored. - ;; Busyboxes built with the EDITING_ASK_TERMINAL config - ;; option send also escape sequences, which must be - ;; ignored. + ;; be leading ANSI control escape sequences, which must be + ;; ignored. Busyboxes built with the EDITING_ASK_TERMINAL + ;; config option send also ANSI control escape sequences, + ;; which must be ignored. (regexp (tramp-compat-rx (* (not (any "#$\n"))) (literal tramp-end-of-output) - (? (regexp tramp-device-escape-sequence-regexp)) + (? (regexp ansi-color-control-seq-regexp)) (? "\r") eol)) ;; Sometimes, the commands do not return a newline but a ;; null byte before the shell prompt, for example "git @@ -5555,7 +5550,7 @@ raises an error." (cond ((tramp-get-method-parameter vec 'tramp-remote-copy-program) localname) - ((zerop (length user)) (format "%s:%s" host localname)) + ((tramp-string-empty-or-nil-p user) (format "%s:%s" host localname)) (t (format "%s@%s:%s" user host localname))))) (defun tramp-method-out-of-band-p (vec size) |