aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2008-06-15 16:59:25 +0000
committerMichael Albinus2008-06-15 16:59:25 +0000
commitd8ac123e392b87317aee5f56dc9244e1f780ca63 (patch)
treeb449cd2b29e0ddbf234905589d6737a02cfa3cbe
parent6653c6b7692032ddae8305530c1f97c532c78305 (diff)
downloademacs-d8ac123e392b87317aee5f56dc9244e1f780ca63.tar.gz
emacs-d8ac123e392b87317aee5f56dc9244e1f780ca63.zip
(tramp-open-connection-setup-interactive-shell): Flush cache, and
restart `tramp-maybe-open-connection' when the remote system has been changed. Throw 'uname-changed event. (tramp-maybe-open-connection): Catch it.
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/net/tramp.el340
2 files changed, 179 insertions, 165 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 0d3d3a40638..6f7b1ce01b2 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -29,6 +29,10 @@
29 modification time of the connection buffer. 29 modification time of the connection buffer.
30 (tramp-sh-file-name-handler): Reset `tramp-locked' in case of 30 (tramp-sh-file-name-handler): Reset `tramp-locked' in case of
31 error. 31 error.
32 (tramp-open-connection-setup-interactive-shell): Flush cache, and
33 restart `tramp-maybe-open-connection' when the remote system has
34 been changed. Throw 'uname-changed event.
35 (tramp-maybe-open-connection): Catch it.
32 36
33 * net/tramp-cmds.el (tramp-cleanup-all-connections): Reset 37 * net/tramp-cmds.el (tramp-cleanup-all-connections): Reset
34 `tramp-locked'. 38 `tramp-locked'.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 943a7a66b55..5918db6df4a 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -5846,7 +5846,8 @@ process to set up. VEC specifies the connection."
5846 5846
5847 ;; Check whether the output of "uname -sr" has been changed. If 5847 ;; Check whether the output of "uname -sr" has been changed. If
5848 ;; yes, this is a strong indication that we must expire all 5848 ;; yes, this is a strong indication that we must expire all
5849 ;; connection properties. 5849 ;; connection properties. We start again with
5850 ;; `tramp-maybe-open-connection', it will be catched there.
5850 (tramp-message vec 5 "Checking system information") 5851 (tramp-message vec 5 "Checking system information")
5851 (let ((old-uname (tramp-get-connection-property vec "uname" nil)) 5852 (let ((old-uname (tramp-get-connection-property vec "uname" nil))
5852 (new-uname 5853 (new-uname
@@ -5854,12 +5855,20 @@ process to set up. VEC specifies the connection."
5854 vec "uname" 5855 vec "uname"
5855 (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\"")))) 5856 (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
5856 (when (and (stringp old-uname) (not (string-equal old-uname new-uname))) 5857 (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
5857 (funcall (symbol-function 'tramp-cleanup-connection) vec) 5858 (with-current-buffer (tramp-get-debug-buffer vec)
5858 (signal 5859 ;; Keep the debug buffer
5859 'quit 5860 (rename-buffer " *temp*" 'unique)
5860 (list (format 5861 (funcall (symbol-function 'tramp-cleanup-connection) vec)
5861 "Connection reset, because remote host changed from `%s' to `%s'" 5862 (if (= (point-min) (point-max))
5862 old-uname new-uname))))) 5863 (kill-buffer nil)
5864 (rename-buffer (tramp-debug-buffer-name vec) 'unique))
5865 ;; We call `tramp-get-buffer' in order to keep the debug buffer.
5866 (tramp-get-buffer vec)
5867 (tramp-message
5868 vec 3
5869 "Connection reset, because remote host changed from `%s' to `%s'"
5870 old-uname new-uname)
5871 (throw 'uname-changed (tramp-maybe-open-connection vec)))))
5863 5872
5864 ;; Check whether the remote host suffers from buggy 5873 ;; Check whether the remote host suffers from buggy
5865 ;; `send-process-string'. This is known for FreeBSD (see comment in 5874 ;; `send-process-string'. This is known for FreeBSD (see comment in
@@ -6222,167 +6231,168 @@ Gateway hops are already opened."
6222 "Maybe open a connection VEC. 6231 "Maybe open a connection VEC.
6223Does not do anything if a connection is already open, but re-opens the 6232Does not do anything if a connection is already open, but re-opens the
6224connection if a previous connection has died for some reason." 6233connection if a previous connection has died for some reason."
6225 (let ((p (tramp-get-connection-process vec)) 6234 (catch 'uname-changed
6226 (process-environment (copy-sequence process-environment))) 6235 (let ((p (tramp-get-connection-process vec))
6227 6236 (process-environment (copy-sequence process-environment)))
6228 ;; If too much time has passed since last command was sent, look 6237
6229 ;; whether process is still alive. If it isn't, kill it. When 6238 ;; If too much time has passed since last command was sent, look
6230 ;; using ssh, it can sometimes happen that the remote end has hung 6239 ;; whether process is still alive. If it isn't, kill it. When
6231 ;; up but the local ssh client doesn't recognize this until it 6240 ;; using ssh, it can sometimes happen that the remote end has
6232 ;; tries to send some data to the remote end. So that's why we 6241 ;; hung up but the local ssh client doesn't recognize this until
6233 ;; try to send a command from time to time, then look again 6242 ;; it tries to send some data to the remote end. So that's why
6234 ;; whether the process is really alive. 6243 ;; we try to send a command from time to time, then look again
6235 (condition-case nil 6244 ;; whether the process is really alive.
6236 (when (and (> (tramp-time-diff 6245 (condition-case nil
6237 (current-time) 6246 (when (and (> (tramp-time-diff
6238 (tramp-get-connection-property 6247 (current-time)
6239 p "last-cmd-time" '(0 0 0))) 6248 (tramp-get-connection-property
6240 60) 6249 p "last-cmd-time" '(0 0 0)))
6241 p (processp p) (memq (process-status p) '(run open))) 6250 60)
6242 (tramp-send-command vec "echo are you awake" t t) 6251 p (processp p) (memq (process-status p) '(run open)))
6243 (unless (and (memq (process-status p) '(run open)) 6252 (tramp-send-command vec "echo are you awake" t t)
6244 (tramp-wait-for-output p 10)) 6253 (unless (and (memq (process-status p) '(run open))
6245 ;; The error will be catched locally. 6254 (tramp-wait-for-output p 10))
6246 (tramp-error vec 'file-error "Awake did fail"))) 6255 ;; The error will be catched locally.
6247 (file-error 6256 (tramp-error vec 'file-error "Awake did fail")))
6248 (tramp-flush-connection-property vec) 6257 (file-error
6249 (tramp-flush-connection-property p) 6258 (tramp-flush-connection-property vec)
6250 (delete-process p) 6259 (tramp-flush-connection-property p)
6251 (setq p nil))) 6260 (delete-process p)
6252 6261 (setq p nil)))
6253 ;; New connection must be opened. 6262
6254 (unless (and p (processp p) (memq (process-status p) '(run open))) 6263 ;; New connection must be opened.
6255 6264 (unless (and p (processp p) (memq (process-status p) '(run open)))
6256 ;; We call `tramp-get-buffer' in order to get a debug buffer for 6265
6257 ;; messages from the beginning. 6266 ;; We call `tramp-get-buffer' in order to get a debug buffer for
6258 (tramp-get-buffer vec) 6267 ;; messages from the beginning.
6259 (if (zerop (length (tramp-file-name-user vec))) 6268 (tramp-get-buffer vec)
6269 (if (zerop (length (tramp-file-name-user vec)))
6270 (tramp-message
6271 vec 3 "Opening connection for %s using %s..."
6272 (tramp-file-name-host vec)
6273 (tramp-file-name-method vec))
6260 (tramp-message 6274 (tramp-message
6261 vec 3 "Opening connection for %s using %s..." 6275 vec 3 "Opening connection for %s@%s using %s..."
6276 (tramp-file-name-user vec)
6262 (tramp-file-name-host vec) 6277 (tramp-file-name-host vec)
6263 (tramp-file-name-method vec)) 6278 (tramp-file-name-method vec)))
6264 (tramp-message 6279
6265 vec 3 "Opening connection for %s@%s using %s..." 6280 ;; Start new process.
6266 (tramp-file-name-user vec) 6281 (when (and p (processp p))
6267 (tramp-file-name-host vec) 6282 (delete-process p))
6268 (tramp-file-name-method vec))) 6283 (setenv "TERM" tramp-terminal-type)
6269 6284 (setenv "LC_ALL" "C")
6270 ;; Start new process. 6285 (setenv "PROMPT_COMMAND")
6271 (when (and p (processp p)) 6286 (setenv "PS1" "$ ")
6272 (delete-process p)) 6287 (let* ((target-alist (tramp-compute-multi-hops vec))
6273 (setenv "TERM" tramp-terminal-type) 6288 (process-connection-type tramp-process-connection-type)
6274 (setenv "LC_ALL" "C") 6289 (process-adaptive-read-buffering nil)
6275 (setenv "PROMPT_COMMAND") 6290 (coding-system-for-read nil)
6276 (setenv "PS1" "$ ") 6291 ;; This must be done in order to avoid our file name handler.
6277 (let* ((target-alist (tramp-compute-multi-hops vec)) 6292 (p (let ((default-directory
6278 (process-connection-type tramp-process-connection-type) 6293 (tramp-compat-temporary-file-directory)))
6279 (process-adaptive-read-buffering nil) 6294 (start-process
6280 (coding-system-for-read nil) 6295 (or (tramp-get-connection-property vec "process-name" nil)
6281 ;; This must be done in order to avoid our file name handler. 6296 (tramp-buffer-name vec))
6282 (p (let ((default-directory 6297 (tramp-get-connection-buffer vec)
6283 (tramp-compat-temporary-file-directory))) 6298 tramp-encoding-shell)))
6284 (start-process 6299 (first-hop t))
6285 (or (tramp-get-connection-property vec "process-name" nil)
6286 (tramp-buffer-name vec))
6287 (tramp-get-connection-buffer vec)
6288 tramp-encoding-shell)))
6289 (first-hop t))
6290 6300
6291 (tramp-message 6301 (tramp-message
6292 vec 6 "%s" (mapconcat 'identity (process-command p) " ")) 6302 vec 6 "%s" (mapconcat 'identity (process-command p) " "))
6293 6303
6294 ;; Check whether process is alive. 6304 ;; Check whether process is alive.
6295 (set-process-sentinel p 'tramp-process-sentinel) 6305 (set-process-sentinel p 'tramp-process-sentinel)
6296 (tramp-set-process-query-on-exit-flag p nil) 6306 (tramp-set-process-query-on-exit-flag p nil)
6297 (tramp-message vec 3 "Waiting 60s for local shell to come up...") 6307 (tramp-message vec 3 "Waiting 60s for local shell to come up...")
6298 (tramp-barf-if-no-shell-prompt 6308 (tramp-barf-if-no-shell-prompt
6299 p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell) 6309 p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell)
6300 6310
6301 ;; Now do all the connections as specified. 6311 ;; Now do all the connections as specified.
6302 (while target-alist 6312 (while target-alist
6303 (let* ((hop (car target-alist)) 6313 (let* ((hop (car target-alist))
6304 (l-method (tramp-file-name-method hop)) 6314 (l-method (tramp-file-name-method hop))
6305 (l-user (tramp-file-name-user hop)) 6315 (l-user (tramp-file-name-user hop))
6306 (l-host (tramp-file-name-host hop)) 6316 (l-host (tramp-file-name-host hop))
6307 (l-port nil) 6317 (l-port nil)
6308 (login-program 6318 (login-program
6309 (tramp-get-method-parameter l-method 'tramp-login-program)) 6319 (tramp-get-method-parameter l-method 'tramp-login-program))
6310 (login-args 6320 (login-args
6311 (tramp-get-method-parameter l-method 'tramp-login-args)) 6321 (tramp-get-method-parameter l-method 'tramp-login-args))
6312 (gw-args 6322 (gw-args
6313 (tramp-get-method-parameter l-method 'tramp-gw-args)) 6323 (tramp-get-method-parameter l-method 'tramp-gw-args))
6314 (gw (tramp-get-file-property hop "" "gateway" nil)) 6324 (gw (tramp-get-file-property hop "" "gateway" nil))
6315 (g-method (and gw (tramp-file-name-method gw))) 6325 (g-method (and gw (tramp-file-name-method gw)))
6316 (g-user (and gw (tramp-file-name-user gw))) 6326 (g-user (and gw (tramp-file-name-user gw)))
6317 (g-host (and gw (tramp-file-name-host gw))) 6327 (g-host (and gw (tramp-file-name-host gw)))
6318 (command login-program) 6328 (command login-program)
6319 ;; We don't create the temporary file. In fact, it 6329 ;; We don't create the temporary file. In fact, it
6320 ;; is just a prefix for the ControlPath option of 6330 ;; is just a prefix for the ControlPath option of
6321 ;; ssh; the real temporary file has another name, and 6331 ;; ssh; the real temporary file has another name, and
6322 ;; it is created and protected by ssh. It is also 6332 ;; it is created and protected by ssh. It is also
6323 ;; removed by ssh, when the connection is closed. 6333 ;; removed by ssh, when the connection is closed.
6324 (tmpfile 6334 (tmpfile
6325 (tramp-set-connection-property 6335 (tramp-set-connection-property
6326 p "temp-file" 6336 p "temp-file"
6327 (make-temp-name 6337 (make-temp-name
6328 (expand-file-name 6338 (expand-file-name
6329 tramp-temp-name-prefix 6339 tramp-temp-name-prefix
6330 (tramp-compat-temporary-file-directory))))) 6340 (tramp-compat-temporary-file-directory)))))
6331 spec) 6341 spec)
6332 6342
6333 ;; Add gateway arguments if necessary. 6343 ;; Add gateway arguments if necessary.
6334 (when (and gw gw-args) 6344 (when (and gw gw-args)
6335 (setq login-args (append login-args gw-args))) 6345 (setq login-args (append login-args gw-args)))
6336 6346
6337 ;; Check for port number. Until now, there's no need for handling 6347 ;; Check for port number. Until now, there's no need
6338 ;; like method, user, host. 6348 ;; for handling like method, user, host.
6339 (when (string-match tramp-host-with-port-regexp l-host) 6349 (when (string-match tramp-host-with-port-regexp l-host)
6340 (setq l-port (match-string 2 l-host) 6350 (setq l-port (match-string 2 l-host)
6341 l-host (match-string 1 l-host))) 6351 l-host (match-string 1 l-host)))
6342 6352
6343 ;; Set variables for computing the prompt for reading password. 6353 ;; Set variables for computing the prompt for reading
6344 ;; They can also be derived from a gatewy. 6354 ;; password. They can also be derived from a gatewy.
6345 (setq tramp-current-method (or g-method l-method) 6355 (setq tramp-current-method (or g-method l-method)
6346 tramp-current-user (or g-user l-user) 6356 tramp-current-user (or g-user l-user)
6347 tramp-current-host (or g-host l-host)) 6357 tramp-current-host (or g-host l-host))
6348 6358
6349 ;; Replace login-args place holders. 6359 ;; Replace login-args place holders.
6350 (setq 6360 (setq
6351 l-host (or l-host "") 6361 l-host (or l-host "")
6352 l-user (or l-user "") 6362 l-user (or l-user "")
6353 l-port (or l-port "") 6363 l-port (or l-port "")
6354 spec `((?h . ,l-host) (?u . ,l-user) (?p . ,l-port) 6364 spec `((?h . ,l-host) (?u . ,l-user) (?p . ,l-port)
6355 (?t . ,tmpfile)) 6365 (?t . ,tmpfile))
6356 command 6366 command
6357 (concat 6367 (concat
6358 command " " 6368 command " "
6359 (mapconcat 6369 (mapconcat
6360 '(lambda (x) 6370 '(lambda (x)
6361 (setq x (mapcar '(lambda (y) (format-spec y spec)) x)) 6371 (setq x (mapcar '(lambda (y) (format-spec y spec)) x))
6362 (unless (member "" x) (mapconcat 'identity x " "))) 6372 (unless (member "" x) (mapconcat 'identity x " ")))
6363 login-args " ") 6373 login-args " ")
6364 ;; String to detect failed connection. Every single word must 6374 ;; String to detect failed connection. Every single
6365 ;; be enclosed with '\"'; otherwise it is detected 6375 ;; word must be enclosed with '\"'; otherwise it is
6366 ;; during connection setup. 6376 ;; detected during connection setup.
6367 ;; Local shell could be a Windows COMSPEC. It doesn't know 6377 ;; Local shell could be a Windows COMSPEC. It doesn't
6368 ;; the ";" syntax, but we must exit always for `start-process'. 6378 ;; know the ";" syntax, but we must exit always for
6369 ;; "exec" does not work either. 6379 ;; `start-process'. "exec" does not work either.
6370 (if first-hop 6380 (if first-hop
6371 " && exit || exit" 6381 " && exit || exit"
6372 "; echo \"Tramp\" \"connection\" \"closed\"; sleep 1")) 6382 "; echo \"Tramp\" \"connection\" \"closed\"; sleep 1"))
6373 ;; We don't reach a Windows shell. Could be initial only. 6383 ;; We don't reach a Windows shell. Could be initial only.
6374 first-hop nil) 6384 first-hop nil)
6375 6385
6376 ;; Send the command. 6386 ;; Send the command.
6377 (tramp-message vec 3 "Sending command `%s'" command) 6387 (tramp-message vec 3 "Sending command `%s'" command)
6378 (tramp-send-command vec command t t) 6388 (tramp-send-command vec command t t)
6379 (tramp-process-actions p vec tramp-actions-before-shell 60) 6389 (tramp-process-actions p vec tramp-actions-before-shell 60)
6380 (tramp-message vec 3 "Found remote shell prompt on `%s'" l-host)) 6390 (tramp-message vec 3 "Found remote shell prompt on `%s'" l-host))
6381 ;; Next hop. 6391 ;; Next hop.
6382 (setq target-alist (cdr target-alist))) 6392 (setq target-alist (cdr target-alist)))
6383 6393
6384 ;; Make initial shell settings. 6394 ;; Make initial shell settings.
6385 (tramp-open-connection-setup-interactive-shell p vec))))) 6395 (tramp-open-connection-setup-interactive-shell p vec))))))
6386 6396
6387(defun tramp-send-command (vec command &optional neveropen nooutput) 6397(defun tramp-send-command (vec command &optional neveropen nooutput)
6388 "Send the COMMAND to connection VEC. 6398 "Send the COMMAND to connection VEC.