* net/tramp-sh.el (tramp-maybe-open-connection): Handle user
interrupt. (Bug#10187)
This commit is contained in:
parent
95ca9bc734
commit
6bdac7360d
2 changed files with 162 additions and 139 deletions
|
@ -1,3 +1,8 @@
|
|||
2011-12-02 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* net/tramp-sh.el (tramp-maybe-open-connection): Handle user
|
||||
interrupt. (Bug#10187)
|
||||
|
||||
2011-12-02 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* pcmpl-gnu.el (pcomplete/tar): large-file-warn-threshold can be nil
|
||||
|
|
|
@ -1042,9 +1042,9 @@ target of the symlink differ."
|
|||
(tramp-flush-file-property l (file-name-directory l-localname))
|
||||
(tramp-flush-file-property l l-localname)
|
||||
|
||||
;; Right, they are on the same host, regardless of user, method, etc.
|
||||
;; We now make the link on the remote machine. This will occur as the user
|
||||
;; that FILENAME belongs to.
|
||||
;; Right, they are on the same host, regardless of user, method,
|
||||
;; etc. We now make the link on the remote machine. This will
|
||||
;; occur as the user that FILENAME belongs to.
|
||||
(tramp-send-command-and-check
|
||||
l
|
||||
(format
|
||||
|
@ -4224,148 +4224,166 @@ connection if a previous connection has died for some reason."
|
|||
(setq p nil)))
|
||||
|
||||
;; New connection must be opened.
|
||||
(unless (and p (processp p) (memq (process-status p) '(run open)))
|
||||
(condition-case err
|
||||
(unless (and p (processp p) (memq (process-status p) '(run open)))
|
||||
|
||||
;; We call `tramp-get-buffer' in order to get a debug buffer for
|
||||
;; messages from the beginning.
|
||||
(tramp-get-buffer vec)
|
||||
(tramp-with-progress-reporter
|
||||
vec 3
|
||||
(if (zerop (length (tramp-file-name-user vec)))
|
||||
(format "Opening connection for %s using %s"
|
||||
(tramp-file-name-host vec)
|
||||
(tramp-file-name-method vec))
|
||||
(format "Opening connection for %s@%s using %s"
|
||||
(tramp-file-name-user vec)
|
||||
(tramp-file-name-host vec)
|
||||
(tramp-file-name-method vec)))
|
||||
;; We call `tramp-get-buffer' in order to get a debug
|
||||
;; buffer for messages from the beginning.
|
||||
(tramp-get-buffer vec)
|
||||
(tramp-with-progress-reporter
|
||||
vec 3
|
||||
(if (zerop (length (tramp-file-name-user vec)))
|
||||
(format "Opening connection for %s using %s"
|
||||
(tramp-file-name-host vec)
|
||||
(tramp-file-name-method vec))
|
||||
(format "Opening connection for %s@%s using %s"
|
||||
(tramp-file-name-user vec)
|
||||
(tramp-file-name-host vec)
|
||||
(tramp-file-name-method vec)))
|
||||
|
||||
;; Start new process.
|
||||
(when (and p (processp p))
|
||||
(delete-process p))
|
||||
(setenv "TERM" tramp-terminal-type)
|
||||
(setenv "LC_ALL" "C")
|
||||
(setenv "PROMPT_COMMAND")
|
||||
(setenv "PS1" tramp-initial-end-of-output)
|
||||
(let* ((target-alist (tramp-compute-multi-hops vec))
|
||||
(process-connection-type tramp-process-connection-type)
|
||||
(process-adaptive-read-buffering nil)
|
||||
(coding-system-for-read nil)
|
||||
;; This must be done in order to avoid our file name handler.
|
||||
(p (let ((default-directory
|
||||
(tramp-compat-temporary-file-directory)))
|
||||
(apply
|
||||
'start-process
|
||||
(tramp-get-connection-name vec)
|
||||
(tramp-get-connection-buffer vec)
|
||||
(if tramp-encoding-command-interactive
|
||||
(list tramp-encoding-shell
|
||||
tramp-encoding-command-interactive)
|
||||
(list tramp-encoding-shell))))))
|
||||
;; Start new process.
|
||||
(when (and p (processp p))
|
||||
(delete-process p))
|
||||
(setenv "TERM" tramp-terminal-type)
|
||||
(setenv "LC_ALL" "C")
|
||||
(setenv "PROMPT_COMMAND")
|
||||
(setenv "PS1" tramp-initial-end-of-output)
|
||||
(let* ((target-alist (tramp-compute-multi-hops vec))
|
||||
(process-connection-type tramp-process-connection-type)
|
||||
(process-adaptive-read-buffering nil)
|
||||
(coding-system-for-read nil)
|
||||
;; This must be done in order to avoid our file
|
||||
;; name handler.
|
||||
(p (let ((default-directory
|
||||
(tramp-compat-temporary-file-directory)))
|
||||
(apply
|
||||
'start-process
|
||||
(tramp-get-connection-name vec)
|
||||
(tramp-get-connection-buffer vec)
|
||||
(if tramp-encoding-command-interactive
|
||||
(list tramp-encoding-shell
|
||||
tramp-encoding-command-interactive)
|
||||
(list tramp-encoding-shell))))))
|
||||
|
||||
;; Set sentinel and query flag.
|
||||
(tramp-set-connection-property p "vector" vec)
|
||||
(set-process-sentinel p 'tramp-process-sentinel)
|
||||
(tramp-compat-set-process-query-on-exit-flag p nil)
|
||||
;; Set sentinel and query flag.
|
||||
(tramp-set-connection-property p "vector" vec)
|
||||
(set-process-sentinel p 'tramp-process-sentinel)
|
||||
(tramp-compat-set-process-query-on-exit-flag p nil)
|
||||
|
||||
(tramp-message
|
||||
vec 6 "%s" (mapconcat 'identity (process-command p) " "))
|
||||
|
||||
;; Check whether process is alive.
|
||||
(tramp-barf-if-no-shell-prompt
|
||||
p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell)
|
||||
|
||||
;; Now do all the connections as specified.
|
||||
(while target-alist
|
||||
(let* ((hop (car target-alist))
|
||||
(l-method (tramp-file-name-method hop))
|
||||
(l-user (tramp-file-name-user hop))
|
||||
(l-host (tramp-file-name-host hop))
|
||||
(l-port nil)
|
||||
(login-program
|
||||
(tramp-get-method-parameter
|
||||
l-method 'tramp-login-program))
|
||||
(login-args
|
||||
(tramp-get-method-parameter l-method 'tramp-login-args))
|
||||
(async-args
|
||||
(tramp-get-method-parameter l-method 'tramp-async-args))
|
||||
(gw-args
|
||||
(tramp-get-method-parameter l-method 'tramp-gw-args))
|
||||
(gw (tramp-get-file-property hop "" "gateway" nil))
|
||||
(g-method (and gw (tramp-file-name-method gw)))
|
||||
(g-user (and gw (tramp-file-name-user gw)))
|
||||
(g-host (and gw (tramp-file-name-real-host gw)))
|
||||
(command login-program)
|
||||
;; We don't create the temporary file. In fact,
|
||||
;; it is just a prefix for the ControlPath option
|
||||
;; of ssh; the real temporary file has another
|
||||
;; name, and it is created and protected by ssh.
|
||||
;; It is also removed by ssh when the connection
|
||||
;; is closed.
|
||||
(tmpfile
|
||||
(tramp-set-connection-property
|
||||
p "temp-file"
|
||||
(make-temp-name
|
||||
(expand-file-name
|
||||
tramp-temp-name-prefix
|
||||
(tramp-compat-temporary-file-directory)))))
|
||||
spec)
|
||||
|
||||
;; Add arguments for asynchronous processes.
|
||||
(when (and process-name async-args)
|
||||
(setq login-args (append async-args login-args)))
|
||||
|
||||
;; Add gateway arguments if necessary.
|
||||
(when (and gw gw-args)
|
||||
(setq login-args (append gw-args login-args)))
|
||||
|
||||
;; Check for port number. Until now, there's no need
|
||||
;; for handling like method, user, host.
|
||||
(when (string-match tramp-host-with-port-regexp l-host)
|
||||
(setq l-port (match-string 2 l-host)
|
||||
l-host (match-string 1 l-host)))
|
||||
|
||||
;; Set variables for computing the prompt for reading
|
||||
;; password. They can also be derived from a gateway.
|
||||
(setq tramp-current-method (or g-method l-method)
|
||||
tramp-current-user (or g-user l-user)
|
||||
tramp-current-host (or g-host l-host))
|
||||
|
||||
;; Replace login-args place holders.
|
||||
(setq
|
||||
l-host (or l-host "")
|
||||
l-user (or l-user "")
|
||||
l-port (or l-port "")
|
||||
spec (format-spec-make
|
||||
?h l-host ?u l-user ?p l-port ?t tmpfile)
|
||||
command
|
||||
(concat
|
||||
;; We do not want to see the trailing local prompt in
|
||||
;; `start-file-process'.
|
||||
(unless (memq system-type '(windows-nt)) "exec ")
|
||||
command " "
|
||||
(mapconcat
|
||||
(lambda (x)
|
||||
(setq x (mapcar (lambda (y) (format-spec y spec)) x))
|
||||
(unless (member "" x) (mapconcat 'identity x " ")))
|
||||
login-args " ")
|
||||
;; Local shell could be a Windows COMSPEC. It
|
||||
;; doesn't know the ";" syntax, but we must exit
|
||||
;; always for `start-file-process'. "exec" does not
|
||||
;; work either.
|
||||
(if (memq system-type '(windows-nt)) " && exit || exit")))
|
||||
|
||||
;; Send the command.
|
||||
(tramp-message vec 3 "Sending command `%s'" command)
|
||||
(tramp-send-command vec command t t)
|
||||
(tramp-process-actions p vec pos tramp-actions-before-shell 60)
|
||||
(tramp-message
|
||||
vec 3 "Found remote shell prompt on `%s'" l-host))
|
||||
;; Next hop.
|
||||
(setq target-alist (cdr target-alist)))
|
||||
vec 6 "%s" (mapconcat 'identity (process-command p) " "))
|
||||
|
||||
;; Make initial shell settings.
|
||||
(tramp-open-connection-setup-interactive-shell p vec)))))))
|
||||
;; Check whether process is alive.
|
||||
(tramp-barf-if-no-shell-prompt
|
||||
p 60
|
||||
"Couldn't find local shell prompt %s" tramp-encoding-shell)
|
||||
|
||||
;; Now do all the connections as specified.
|
||||
(while target-alist
|
||||
(let* ((hop (car target-alist))
|
||||
(l-method (tramp-file-name-method hop))
|
||||
(l-user (tramp-file-name-user hop))
|
||||
(l-host (tramp-file-name-host hop))
|
||||
(l-port nil)
|
||||
(login-program
|
||||
(tramp-get-method-parameter
|
||||
l-method 'tramp-login-program))
|
||||
(login-args
|
||||
(tramp-get-method-parameter
|
||||
l-method 'tramp-login-args))
|
||||
(async-args
|
||||
(tramp-get-method-parameter
|
||||
l-method 'tramp-async-args))
|
||||
(gw-args
|
||||
(tramp-get-method-parameter l-method 'tramp-gw-args))
|
||||
(gw (tramp-get-file-property hop "" "gateway" nil))
|
||||
(g-method (and gw (tramp-file-name-method gw)))
|
||||
(g-user (and gw (tramp-file-name-user gw)))
|
||||
(g-host (and gw (tramp-file-name-real-host gw)))
|
||||
(command login-program)
|
||||
;; We don't create the temporary file. In
|
||||
;; fact, it is just a prefix for the
|
||||
;; ControlPath option of ssh; the real
|
||||
;; temporary file has another name, and it is
|
||||
;; created and protected by ssh. It is also
|
||||
;; removed by ssh when the connection is
|
||||
;; closed.
|
||||
(tmpfile
|
||||
(tramp-set-connection-property
|
||||
p "temp-file"
|
||||
(make-temp-name
|
||||
(expand-file-name
|
||||
tramp-temp-name-prefix
|
||||
(tramp-compat-temporary-file-directory)))))
|
||||
spec)
|
||||
|
||||
;; Add arguments for asynchronous processes.
|
||||
(when (and process-name async-args)
|
||||
(setq login-args (append async-args login-args)))
|
||||
|
||||
;; Add gateway arguments if necessary.
|
||||
(when (and gw gw-args)
|
||||
(setq login-args (append gw-args login-args)))
|
||||
|
||||
;; Check for port number. Until now, there's no
|
||||
;; need for handling like method, user, host.
|
||||
(when (string-match tramp-host-with-port-regexp l-host)
|
||||
(setq l-port (match-string 2 l-host)
|
||||
l-host (match-string 1 l-host)))
|
||||
|
||||
;; Set variables for computing the prompt for
|
||||
;; reading password. They can also be derived
|
||||
;; from a gateway.
|
||||
(setq tramp-current-method (or g-method l-method)
|
||||
tramp-current-user (or g-user l-user)
|
||||
tramp-current-host (or g-host l-host))
|
||||
|
||||
;; Replace login-args place holders.
|
||||
(setq
|
||||
l-host (or l-host "")
|
||||
l-user (or l-user "")
|
||||
l-port (or l-port "")
|
||||
spec (format-spec-make
|
||||
?h l-host ?u l-user ?p l-port ?t tmpfile)
|
||||
command
|
||||
(concat
|
||||
;; We do not want to see the trailing local
|
||||
;; prompt in `start-file-process'.
|
||||
(unless (memq system-type '(windows-nt)) "exec ")
|
||||
command " "
|
||||
(mapconcat
|
||||
(lambda (x)
|
||||
(setq x (mapcar (lambda (y) (format-spec y spec)) x))
|
||||
(unless (member "" x) (mapconcat 'identity x " ")))
|
||||
login-args " ")
|
||||
;; Local shell could be a Windows COMSPEC. It
|
||||
;; doesn't know the ";" syntax, but we must exit
|
||||
;; always for `start-file-process'. "exec" does
|
||||
;; not work either.
|
||||
(if (memq system-type '(windows-nt)) " && exit || exit")))
|
||||
|
||||
;; Send the command.
|
||||
(tramp-message vec 3 "Sending command `%s'" command)
|
||||
(tramp-send-command vec command t t)
|
||||
(tramp-process-actions
|
||||
p vec pos tramp-actions-before-shell 60)
|
||||
(tramp-message
|
||||
vec 3 "Found remote shell prompt on `%s'" l-host))
|
||||
;; Next hop.
|
||||
(setq target-alist (cdr target-alist)))
|
||||
|
||||
;; Make initial shell settings.
|
||||
(tramp-open-connection-setup-interactive-shell p vec))))
|
||||
|
||||
;; When the user did interrupt, we must cleanup.
|
||||
(quit
|
||||
(let ((p (tramp-get-connection-process vec)))
|
||||
(when (and p (processp p))
|
||||
(tramp-flush-connection-property vec)
|
||||
(tramp-flush-connection-property p)
|
||||
(delete-process p)))
|
||||
;; Propagate the quit signal.
|
||||
(signal (car err) (cdr err)))))))
|
||||
|
||||
(defun tramp-send-command (vec command &optional neveropen nooutput)
|
||||
"Send the COMMAND to connection VEC.
|
||||
|
|
Loading…
Add table
Reference in a new issue