diff options
| author | Michael Albinus | 2011-12-02 20:23:19 +0100 |
|---|---|---|
| committer | Michael Albinus | 2011-12-02 20:23:19 +0100 |
| commit | 6bdac7360d522bc7a11b0ab867e3517ddacfaa35 (patch) | |
| tree | 4ca59ec95cf74bff40f313b37bd7f313aafe5634 | |
| parent | 95ca9bc7340332c09c0a083aeae21cd25bb3928b (diff) | |
| download | emacs-6bdac7360d522bc7a11b0ab867e3517ddacfaa35.tar.gz emacs-6bdac7360d522bc7a11b0ab867e3517ddacfaa35.zip | |
* net/tramp-sh.el (tramp-maybe-open-connection): Handle user
interrupt. (Bug#10187)
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 304 |
2 files changed, 166 insertions, 143 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ef99c31d1e8..4ab35890cae 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2011-12-02 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp-sh.el (tramp-maybe-open-connection): Handle user | ||
| 4 | interrupt. (Bug#10187) | ||
| 5 | |||
| 1 | 2011-12-02 Stefan Monnier <monnier@iro.umontreal.ca> | 6 | 2011-12-02 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 7 | ||
| 3 | * pcmpl-gnu.el (pcomplete/tar): large-file-warn-threshold can be nil | 8 | * pcmpl-gnu.el (pcomplete/tar): large-file-warn-threshold can be nil |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 941b788ae4d..ee4c8966626 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1042,9 +1042,9 @@ target of the symlink differ." | |||
| 1042 | (tramp-flush-file-property l (file-name-directory l-localname)) | 1042 | (tramp-flush-file-property l (file-name-directory l-localname)) |
| 1043 | (tramp-flush-file-property l l-localname) | 1043 | (tramp-flush-file-property l l-localname) |
| 1044 | 1044 | ||
| 1045 | ;; Right, they are on the same host, regardless of user, method, etc. | 1045 | ;; Right, they are on the same host, regardless of user, method, |
| 1046 | ;; We now make the link on the remote machine. This will occur as the user | 1046 | ;; etc. We now make the link on the remote machine. This will |
| 1047 | ;; that FILENAME belongs to. | 1047 | ;; occur as the user that FILENAME belongs to. |
| 1048 | (tramp-send-command-and-check | 1048 | (tramp-send-command-and-check |
| 1049 | l | 1049 | l |
| 1050 | (format | 1050 | (format |
| @@ -4224,148 +4224,166 @@ connection if a previous connection has died for some reason." | |||
| 4224 | (setq p nil))) | 4224 | (setq p nil))) |
| 4225 | 4225 | ||
| 4226 | ;; New connection must be opened. | 4226 | ;; New connection must be opened. |
| 4227 | (unless (and p (processp p) (memq (process-status p) '(run open))) | 4227 | (condition-case err |
| 4228 | 4228 | (unless (and p (processp p) (memq (process-status p) '(run open))) | |
| 4229 | ;; We call `tramp-get-buffer' in order to get a debug buffer for | 4229 | |
| 4230 | ;; messages from the beginning. | 4230 | ;; We call `tramp-get-buffer' in order to get a debug |
| 4231 | (tramp-get-buffer vec) | 4231 | ;; buffer for messages from the beginning. |
| 4232 | (tramp-with-progress-reporter | 4232 | (tramp-get-buffer vec) |
| 4233 | vec 3 | 4233 | (tramp-with-progress-reporter |
| 4234 | (if (zerop (length (tramp-file-name-user vec))) | 4234 | vec 3 |
| 4235 | (format "Opening connection for %s using %s" | 4235 | (if (zerop (length (tramp-file-name-user vec))) |
| 4236 | (tramp-file-name-host vec) | 4236 | (format "Opening connection for %s using %s" |
| 4237 | (tramp-file-name-method vec)) | 4237 | (tramp-file-name-host vec) |
| 4238 | (format "Opening connection for %s@%s using %s" | 4238 | (tramp-file-name-method vec)) |
| 4239 | (tramp-file-name-user vec) | 4239 | (format "Opening connection for %s@%s using %s" |
| 4240 | (tramp-file-name-host vec) | 4240 | (tramp-file-name-user vec) |
| 4241 | (tramp-file-name-method vec))) | 4241 | (tramp-file-name-host vec) |
| 4242 | 4242 | (tramp-file-name-method vec))) | |
| 4243 | ;; Start new process. | 4243 | |
| 4244 | (when (and p (processp p)) | 4244 | ;; Start new process. |
| 4245 | (delete-process p)) | 4245 | (when (and p (processp p)) |
| 4246 | (setenv "TERM" tramp-terminal-type) | 4246 | (delete-process p)) |
| 4247 | (setenv "LC_ALL" "C") | 4247 | (setenv "TERM" tramp-terminal-type) |
| 4248 | (setenv "PROMPT_COMMAND") | 4248 | (setenv "LC_ALL" "C") |
| 4249 | (setenv "PS1" tramp-initial-end-of-output) | 4249 | (setenv "PROMPT_COMMAND") |
| 4250 | (let* ((target-alist (tramp-compute-multi-hops vec)) | 4250 | (setenv "PS1" tramp-initial-end-of-output) |
| 4251 | (process-connection-type tramp-process-connection-type) | 4251 | (let* ((target-alist (tramp-compute-multi-hops vec)) |
| 4252 | (process-adaptive-read-buffering nil) | 4252 | (process-connection-type tramp-process-connection-type) |
| 4253 | (coding-system-for-read nil) | 4253 | (process-adaptive-read-buffering nil) |
| 4254 | ;; This must be done in order to avoid our file name handler. | 4254 | (coding-system-for-read nil) |
| 4255 | (p (let ((default-directory | 4255 | ;; This must be done in order to avoid our file |
| 4256 | (tramp-compat-temporary-file-directory))) | 4256 | ;; name handler. |
| 4257 | (apply | 4257 | (p (let ((default-directory |
| 4258 | 'start-process | 4258 | (tramp-compat-temporary-file-directory))) |
| 4259 | (tramp-get-connection-name vec) | 4259 | (apply |
| 4260 | (tramp-get-connection-buffer vec) | 4260 | 'start-process |
| 4261 | (if tramp-encoding-command-interactive | 4261 | (tramp-get-connection-name vec) |
| 4262 | (list tramp-encoding-shell | 4262 | (tramp-get-connection-buffer vec) |
| 4263 | tramp-encoding-command-interactive) | 4263 | (if tramp-encoding-command-interactive |
| 4264 | (list tramp-encoding-shell)))))) | 4264 | (list tramp-encoding-shell |
| 4265 | 4265 | tramp-encoding-command-interactive) | |
| 4266 | ;; Set sentinel and query flag. | 4266 | (list tramp-encoding-shell)))))) |
| 4267 | (tramp-set-connection-property p "vector" vec) | 4267 | |
| 4268 | (set-process-sentinel p 'tramp-process-sentinel) | 4268 | ;; Set sentinel and query flag. |
| 4269 | (tramp-compat-set-process-query-on-exit-flag p nil) | 4269 | (tramp-set-connection-property p "vector" vec) |
| 4270 | (set-process-sentinel p 'tramp-process-sentinel) | ||
| 4271 | (tramp-compat-set-process-query-on-exit-flag p nil) | ||
| 4270 | 4272 | ||
| 4271 | (tramp-message | ||
| 4272 | vec 6 "%s" (mapconcat 'identity (process-command p) " ")) | ||
| 4273 | |||
| 4274 | ;; Check whether process is alive. | ||
| 4275 | (tramp-barf-if-no-shell-prompt | ||
| 4276 | p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell) | ||
| 4277 | |||
| 4278 | ;; Now do all the connections as specified. | ||
| 4279 | (while target-alist | ||
| 4280 | (let* ((hop (car target-alist)) | ||
| 4281 | (l-method (tramp-file-name-method hop)) | ||
| 4282 | (l-user (tramp-file-name-user hop)) | ||
| 4283 | (l-host (tramp-file-name-host hop)) | ||
| 4284 | (l-port nil) | ||
| 4285 | (login-program | ||
| 4286 | (tramp-get-method-parameter | ||
| 4287 | l-method 'tramp-login-program)) | ||
| 4288 | (login-args | ||
| 4289 | (tramp-get-method-parameter l-method 'tramp-login-args)) | ||
| 4290 | (async-args | ||
| 4291 | (tramp-get-method-parameter l-method 'tramp-async-args)) | ||
| 4292 | (gw-args | ||
| 4293 | (tramp-get-method-parameter l-method 'tramp-gw-args)) | ||
| 4294 | (gw (tramp-get-file-property hop "" "gateway" nil)) | ||
| 4295 | (g-method (and gw (tramp-file-name-method gw))) | ||
| 4296 | (g-user (and gw (tramp-file-name-user gw))) | ||
| 4297 | (g-host (and gw (tramp-file-name-real-host gw))) | ||
| 4298 | (command login-program) | ||
| 4299 | ;; We don't create the temporary file. In fact, | ||
| 4300 | ;; it is just a prefix for the ControlPath option | ||
| 4301 | ;; of ssh; the real temporary file has another | ||
| 4302 | ;; name, and it is created and protected by ssh. | ||
| 4303 | ;; It is also removed by ssh when the connection | ||
| 4304 | ;; is closed. | ||
| 4305 | (tmpfile | ||
| 4306 | (tramp-set-connection-property | ||
| 4307 | p "temp-file" | ||
| 4308 | (make-temp-name | ||
| 4309 | (expand-file-name | ||
| 4310 | tramp-temp-name-prefix | ||
| 4311 | (tramp-compat-temporary-file-directory))))) | ||
| 4312 | spec) | ||
| 4313 | |||
| 4314 | ;; Add arguments for asynchronous processes. | ||
| 4315 | (when (and process-name async-args) | ||
| 4316 | (setq login-args (append async-args login-args))) | ||
| 4317 | |||
| 4318 | ;; Add gateway arguments if necessary. | ||
| 4319 | (when (and gw gw-args) | ||
| 4320 | (setq login-args (append gw-args login-args))) | ||
| 4321 | |||
| 4322 | ;; Check for port number. Until now, there's no need | ||
| 4323 | ;; for handling like method, user, host. | ||
| 4324 | (when (string-match tramp-host-with-port-regexp l-host) | ||
| 4325 | (setq l-port (match-string 2 l-host) | ||
| 4326 | l-host (match-string 1 l-host))) | ||
| 4327 | |||
| 4328 | ;; Set variables for computing the prompt for reading | ||
| 4329 | ;; password. They can also be derived from a gateway. | ||
| 4330 | (setq tramp-current-method (or g-method l-method) | ||
| 4331 | tramp-current-user (or g-user l-user) | ||
| 4332 | tramp-current-host (or g-host l-host)) | ||
| 4333 | |||
| 4334 | ;; Replace login-args place holders. | ||
| 4335 | (setq | ||
| 4336 | l-host (or l-host "") | ||
| 4337 | l-user (or l-user "") | ||
| 4338 | l-port (or l-port "") | ||
| 4339 | spec (format-spec-make | ||
| 4340 | ?h l-host ?u l-user ?p l-port ?t tmpfile) | ||
| 4341 | command | ||
| 4342 | (concat | ||
| 4343 | ;; We do not want to see the trailing local prompt in | ||
| 4344 | ;; `start-file-process'. | ||
| 4345 | (unless (memq system-type '(windows-nt)) "exec ") | ||
| 4346 | command " " | ||
| 4347 | (mapconcat | ||
| 4348 | (lambda (x) | ||
| 4349 | (setq x (mapcar (lambda (y) (format-spec y spec)) x)) | ||
| 4350 | (unless (member "" x) (mapconcat 'identity x " "))) | ||
| 4351 | login-args " ") | ||
| 4352 | ;; Local shell could be a Windows COMSPEC. It | ||
| 4353 | ;; doesn't know the ";" syntax, but we must exit | ||
| 4354 | ;; always for `start-file-process'. "exec" does not | ||
| 4355 | ;; work either. | ||
| 4356 | (if (memq system-type '(windows-nt)) " && exit || exit"))) | ||
| 4357 | |||
| 4358 | ;; Send the command. | ||
| 4359 | (tramp-message vec 3 "Sending command `%s'" command) | ||
| 4360 | (tramp-send-command vec command t t) | ||
| 4361 | (tramp-process-actions p vec pos tramp-actions-before-shell 60) | ||
| 4362 | (tramp-message | 4273 | (tramp-message |
| 4363 | vec 3 "Found remote shell prompt on `%s'" l-host)) | 4274 | vec 6 "%s" (mapconcat 'identity (process-command p) " ")) |
| 4364 | ;; Next hop. | 4275 | |
| 4365 | (setq target-alist (cdr target-alist))) | 4276 | ;; Check whether process is alive. |
| 4366 | 4277 | (tramp-barf-if-no-shell-prompt | |
| 4367 | ;; Make initial shell settings. | 4278 | p 60 |
| 4368 | (tramp-open-connection-setup-interactive-shell p vec))))))) | 4279 | "Couldn't find local shell prompt %s" tramp-encoding-shell) |
| 4280 | |||
| 4281 | ;; Now do all the connections as specified. | ||
| 4282 | (while target-alist | ||
| 4283 | (let* ((hop (car target-alist)) | ||
| 4284 | (l-method (tramp-file-name-method hop)) | ||
| 4285 | (l-user (tramp-file-name-user hop)) | ||
| 4286 | (l-host (tramp-file-name-host hop)) | ||
| 4287 | (l-port nil) | ||
| 4288 | (login-program | ||
| 4289 | (tramp-get-method-parameter | ||
| 4290 | l-method 'tramp-login-program)) | ||
| 4291 | (login-args | ||
| 4292 | (tramp-get-method-parameter | ||
| 4293 | l-method 'tramp-login-args)) | ||
| 4294 | (async-args | ||
| 4295 | (tramp-get-method-parameter | ||
| 4296 | l-method 'tramp-async-args)) | ||
| 4297 | (gw-args | ||
| 4298 | (tramp-get-method-parameter l-method 'tramp-gw-args)) | ||
| 4299 | (gw (tramp-get-file-property hop "" "gateway" nil)) | ||
| 4300 | (g-method (and gw (tramp-file-name-method gw))) | ||
| 4301 | (g-user (and gw (tramp-file-name-user gw))) | ||
| 4302 | (g-host (and gw (tramp-file-name-real-host gw))) | ||
| 4303 | (command login-program) | ||
| 4304 | ;; We don't create the temporary file. In | ||
| 4305 | ;; fact, it is just a prefix for the | ||
| 4306 | ;; ControlPath option of ssh; the real | ||
| 4307 | ;; temporary file has another name, and it is | ||
| 4308 | ;; created and protected by ssh. It is also | ||
| 4309 | ;; removed by ssh when the connection is | ||
| 4310 | ;; closed. | ||
| 4311 | (tmpfile | ||
| 4312 | (tramp-set-connection-property | ||
| 4313 | p "temp-file" | ||
| 4314 | (make-temp-name | ||
| 4315 | (expand-file-name | ||
| 4316 | tramp-temp-name-prefix | ||
| 4317 | (tramp-compat-temporary-file-directory))))) | ||
| 4318 | spec) | ||
| 4319 | |||
| 4320 | ;; Add arguments for asynchronous processes. | ||
| 4321 | (when (and process-name async-args) | ||
| 4322 | (setq login-args (append async-args login-args))) | ||
| 4323 | |||
| 4324 | ;; Add gateway arguments if necessary. | ||
| 4325 | (when (and gw gw-args) | ||
| 4326 | (setq login-args (append gw-args login-args))) | ||
| 4327 | |||
| 4328 | ;; Check for port number. Until now, there's no | ||
| 4329 | ;; need for handling like method, user, host. | ||
| 4330 | (when (string-match tramp-host-with-port-regexp l-host) | ||
| 4331 | (setq l-port (match-string 2 l-host) | ||
| 4332 | l-host (match-string 1 l-host))) | ||
| 4333 | |||
| 4334 | ;; Set variables for computing the prompt for | ||
| 4335 | ;; reading password. They can also be derived | ||
| 4336 | ;; from a gateway. | ||
| 4337 | (setq tramp-current-method (or g-method l-method) | ||
| 4338 | tramp-current-user (or g-user l-user) | ||
| 4339 | tramp-current-host (or g-host l-host)) | ||
| 4340 | |||
| 4341 | ;; Replace login-args place holders. | ||
| 4342 | (setq | ||
| 4343 | l-host (or l-host "") | ||
| 4344 | l-user (or l-user "") | ||
| 4345 | l-port (or l-port "") | ||
| 4346 | spec (format-spec-make | ||
| 4347 | ?h l-host ?u l-user ?p l-port ?t tmpfile) | ||
| 4348 | command | ||
| 4349 | (concat | ||
| 4350 | ;; We do not want to see the trailing local | ||
| 4351 | ;; prompt in `start-file-process'. | ||
| 4352 | (unless (memq system-type '(windows-nt)) "exec ") | ||
| 4353 | command " " | ||
| 4354 | (mapconcat | ||
| 4355 | (lambda (x) | ||
| 4356 | (setq x (mapcar (lambda (y) (format-spec y spec)) x)) | ||
| 4357 | (unless (member "" x) (mapconcat 'identity x " "))) | ||
| 4358 | login-args " ") | ||
| 4359 | ;; Local shell could be a Windows COMSPEC. It | ||
| 4360 | ;; doesn't know the ";" syntax, but we must exit | ||
| 4361 | ;; always for `start-file-process'. "exec" does | ||
| 4362 | ;; not work either. | ||
| 4363 | (if (memq system-type '(windows-nt)) " && exit || exit"))) | ||
| 4364 | |||
| 4365 | ;; Send the command. | ||
| 4366 | (tramp-message vec 3 "Sending command `%s'" command) | ||
| 4367 | (tramp-send-command vec command t t) | ||
| 4368 | (tramp-process-actions | ||
| 4369 | p vec pos tramp-actions-before-shell 60) | ||
| 4370 | (tramp-message | ||
| 4371 | vec 3 "Found remote shell prompt on `%s'" l-host)) | ||
| 4372 | ;; Next hop. | ||
| 4373 | (setq target-alist (cdr target-alist))) | ||
| 4374 | |||
| 4375 | ;; Make initial shell settings. | ||
| 4376 | (tramp-open-connection-setup-interactive-shell p vec)))) | ||
| 4377 | |||
| 4378 | ;; When the user did interrupt, we must cleanup. | ||
| 4379 | (quit | ||
| 4380 | (let ((p (tramp-get-connection-process vec))) | ||
| 4381 | (when (and p (processp p)) | ||
| 4382 | (tramp-flush-connection-property vec) | ||
| 4383 | (tramp-flush-connection-property p) | ||
| 4384 | (delete-process p))) | ||
| 4385 | ;; Propagate the quit signal. | ||
| 4386 | (signal (car err) (cdr err))))))) | ||
| 4369 | 4387 | ||
| 4370 | (defun tramp-send-command (vec command &optional neveropen nooutput) | 4388 | (defun tramp-send-command (vec command &optional neveropen nooutput) |
| 4371 | "Send the COMMAND to connection VEC. | 4389 | "Send the COMMAND to connection VEC. |