diff options
| author | Michael Albinus | 2008-06-15 16:59:25 +0000 |
|---|---|---|
| committer | Michael Albinus | 2008-06-15 16:59:25 +0000 |
| commit | d8ac123e392b87317aee5f56dc9244e1f780ca63 (patch) | |
| tree | b449cd2b29e0ddbf234905589d6737a02cfa3cbe | |
| parent | 6653c6b7692032ddae8305530c1f97c532c78305 (diff) | |
| download | emacs-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/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 340 |
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. |
| 6223 | Does not do anything if a connection is already open, but re-opens the | 6232 | Does not do anything if a connection is already open, but re-opens the |
| 6224 | connection if a previous connection has died for some reason." | 6233 | connection 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. |