Function: tramp-open-connection-setup-interactive-shell
tramp-open-connection-setup-interactive-shell is a byte-compiled
function defined in tramp-sh.el.gz.
Signature
(tramp-open-connection-setup-interactive-shell PROC VEC)
Documentation
Set up an interactive shell.
Mainly sets the prompt and the echo correctly. PROC is the shell process to set up. VEC specifies the connection.
Source Code
;; Defined in /usr/src/emacs/lisp/net/tramp-sh.el.gz
(defun tramp-open-connection-setup-interactive-shell (proc vec)
"Set up an interactive shell.
Mainly sets the prompt and the echo correctly. PROC is the shell
process to set up. VEC specifies the connection."
(let ((case-fold-search t))
(tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
(tramp-message vec 5 "Setting up remote shell environment")
;; Disable line editing. Dump option settings in the traces.
(tramp-send-command
vec
(if (>= tramp-verbose 9) "set +o vi +o emacs -o" "set +o vi +o emacs") t)
;; Disable echo expansion.
(tramp-send-command
vec "stty -inlcr -onlcr -echo kill '^U' erase '^H'" t)
;; Check whether the echo has really been disabled. Some
;; implementations, like busybox of embedded GNU/Linux, don't
;; support disabling.
(tramp-send-command vec "echo foo" t)
(with-current-buffer (process-buffer proc)
(goto-char (point-min))
(when (looking-at-p "echo foo")
(tramp-set-connection-property proc "remote-echo" t)
(tramp-message vec 5 "Remote echo still on. Ok.")
;; Make sure backspaces and their echo are enabled and no line
;; width magic interferes with them.
(tramp-send-command vec "stty icanon erase ^H cols 32767" t))))
;; Check whether the output of "uname -sr" has been changed. If
;; yes, this is a strong indication that we must expire all
;; connection properties. We start again with
;; `tramp-maybe-open-connection', it will be caught there. The same
;; check will be applied with the function kept in `tramp-config-check'.
(tramp-message vec 5 "Checking system information")
(let* ((old-uname (tramp-get-connection-property vec "uname"))
(uname
;; If we are in `make-process', we don't need to recompute.
(if (and old-uname (tramp-get-connection-property vec " process-name"))
old-uname
(tramp-set-connection-property
vec "uname"
(tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
(config-check-function
(buffer-local-value 'tramp-config-check (process-buffer proc)))
(old-config-check
(and config-check-function
(tramp-get-connection-property vec "config-check-data")))
(config-check
(and config-check-function
;; If we are in `make-process', we don't need to recompute.
(if (and old-config-check
(tramp-get-connection-property vec " process-name"))
old-config-check
(tramp-set-connection-property
vec "config-check-data"
(tramp-compat-funcall config-check-function vec))))))
(when (and (stringp old-uname) (stringp uname)
(not (string-equal old-uname uname)))
(tramp-message
vec 3
"Connection reset, because remote host changed from `%s' to `%s'"
old-uname uname)
;; We want to keep the password.
(tramp-cleanup-connection vec t t)
(throw 'uname-changed (tramp-maybe-open-connection vec)))
(when (and (stringp old-config-check) (stringp config-check)
(not (string-equal old-config-check config-check)))
(tramp-message
vec 3
"Connection reset, because remote configuration changed from `%s' to `%s'"
old-config-check config-check)
;; We want to keep the password.
(tramp-cleanup-connection vec t t)
(throw 'uname-changed (tramp-maybe-open-connection vec)))
;; Dump /etc/os-release in the traces.
(when (>= tramp-verbose 9)
(tramp-send-command
vec (format "cat /etc/os-release 2>%s" (tramp-get-remote-null-device vec))
t))
;; Try to set up the coding system correctly.
;; CCC this can't be the right way to do it. Hm.
(tramp-message vec 5 "Determining coding system")
(with-current-buffer (process-buffer proc)
;; Use MULE to select the right EOL convention for communicating
;; with the process.
(let ((cs (or (and (memq 'utf-8-hfs (coding-system-list))
(string-prefix-p "Darwin" uname)
(cons 'utf-8-hfs 'utf-8-hfs))
(and (memq 'utf-8 (coding-system-list))
(string-match-p
(rx "utf" (? "-") "8") (tramp-get-remote-locale vec))
(cons 'utf-8 'utf-8))
(process-coding-system proc)
(cons 'undecided 'undecided)))
cs-decode cs-encode)
(when (symbolp cs) (setq cs (cons cs cs)))
(setq cs-decode (or (car cs) 'undecided)
cs-encode (or (cdr cs) 'undecided)
cs-encode
(coding-system-change-eol-conversion
cs-encode (if (string-prefix-p "Darwin" uname) 'mac 'unix)))
(tramp-send-command vec "(echo foo ; echo bar)" t)
(goto-char (point-min))
(when (search-forward "\r" nil t)
(setq cs-decode (coding-system-change-eol-conversion cs-decode 'dos)))
(set-process-coding-system proc cs-decode cs-encode)
(tramp-message
vec 5 "Setting coding system to `%s' and `%s'" cs-decode cs-encode)))
;; Check whether the remote host suffers from buggy
;; `send-process-string'. This is known for FreeBSD (see comment
;; in `send_process', file process.c). I've tested sending 624
;; bytes successfully, sending 625 bytes failed. Emacs makes a
;; hack when this host type is detected locally. It cannot handle
;; remote hosts, though.
(with-tramp-connection-property proc "chunksize"
(cond
((and (integerp tramp-chunksize) (> tramp-chunksize 0))
tramp-chunksize)
(t
(tramp-message
vec 5 "Checking remote host type for `send-process-string' bug")
(if (string-match-p (rx (| "FreeBSD" "DragonFly")) uname) 500 0))))
;; Set remote PATH variable.
(tramp-set-remote-path vec)
;; Search for a good shell before searching for a command which
;; checks if a file exists. This is done because Tramp wants to
;; use "test foo; echo $?" to check if various conditions hold,
;; and there are buggy /bin/sh implementations which don't execute
;; the "echo $?" part if the "test" part has an error. In
;; particular, the OpenSolaris /bin/sh is a problem. There are
;; also other problems with /bin/sh of OpenSolaris, like
;; redirection of stderr in function declarations, or changing
;; HISTFILE in place. Therefore, OpenSolaris' /bin/sh is replaced
;; by bash, when detected.
(tramp-find-shell vec)
;; Disable unexpected output.
(tramp-send-command
vec
(format "mesg n 2>%s; biff n 2>%s"
(tramp-get-remote-null-device vec)
(tramp-get-remote-null-device vec))
t)
;; IRIX64 bash expands "!" even when in single quotes. This
;; destroys our shell functions, we must disable it. See
;; <https://stackoverflow.com/questions/3291692/irix-bash-shell-expands-expression-in-single-quotes-yet-shouldnt>.
(when (string-prefix-p "IRIX64" uname)
(tramp-send-command vec "set +H" t))
;; Disable tab expansion.
(if (string-match-p tramp-bsd-unames uname)
(tramp-send-command vec "stty tabs" t)
(tramp-send-command vec "stty tab0" t))
;; Set utf8 encoding. Needed for macOS, for example. This is
;; non-POSIX, so we must expect errors on some systems.
(tramp-send-command
vec (concat "stty iutf8 2>" (tramp-get-remote-null-device vec)) t)
;; Set `remote-tty' process property.
(let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
(unless (tramp-string-empty-or-nil-p tty)
(process-put proc 'remote-tty tty)
(tramp-set-connection-property proc "remote-tty" tty)))
;; Dump stty settings in the traces.
(when (>= tramp-verbose 9)
(tramp-send-command vec "stty -a" t))
;; Set the environment.
(tramp-message vec 5 "Setting default environment")
(let (unset vars)
(dolist (item (reverse
(append `(,(tramp-get-remote-locale vec))
(copy-sequence tramp-remote-process-environment))))
(setq item (split-string item "=" 'omit))
(setcdr item (string-join (cdr item) "="))
(if (and (stringp (cdr item)) (not (string-empty-p (cdr item))))
(push (format "%s %s" (car item) (cdr item)) vars)
(push (car item) unset)))
(when vars
(tramp-send-command
vec
(format
"while read var val; do export $var=\"$val\"; done <<'%s'\n%s\n%s"
tramp-end-of-heredoc
(string-join vars "\n")
tramp-end-of-heredoc)
t))
(when unset
(tramp-send-command
vec (format "unset %s" (string-join unset " ")) t)))))