From: Michael Albinus Date: Thu, 12 Dec 2019 14:21:34 +0000 (+0100) Subject: Optimize prompt search in Tramp X-Git-Tag: emacs-27.0.90~369 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=ede63fed1f08bb3af6b22dc4b8a47154b18ffc4b;p=emacs.git Optimize prompt search in Tramp * lisp/net/tramp.el (tramp-search-regexp): New defun. (tramp-check-for-regexp, tramp-process-sentinel): * lisp/net/tramp-adb.el (tramp-adb-send-command-and-check) (tramp-adb-wait-for-output): * lisp/net/tramp-sh.el (tramp-wait-for-output) (tramp-send-command-and-check): * lisp/net/tramp-smb.el (tramp-smb-handle-set-file-acl): Bind search length. --- diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index b56ffdd7bc0..f0abb277965 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -1156,8 +1156,7 @@ the exit status is not equal 0, and t otherwise." (format "%s; echo tramp_exit_status $?" command) "echo tramp_exit_status $?")) (with-current-buffer (tramp-get-connection-buffer vec) - (goto-char (point-max)) - (unless (re-search-backward "tramp_exit_status [0-9]+" nil t) + (unless (tramp-search-regexp "tramp_exit_status [0-9]+") (tramp-error vec 'file-error "Couldn't find exit status of `%s'" command)) (skip-chars-forward "^ ") @@ -1191,9 +1190,8 @@ FMT and ARGS are passed to `error'." (when (re-search-forward prompt (point-at-eol) t) (forward-line 1) (delete-region (point-min) (point))) - (goto-char (point-max)) - (re-search-backward prompt nil t) - (delete-region (point) (point-max))) + (when (tramp-search-regexp prompt) + (delete-region (point) (point-max)))) (if timeout (tramp-error proc 'file-error diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 8de88d355f9..506c33df466 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5102,9 +5102,8 @@ function waits for output unless NOOUTPUT is set." (forward-line 1) (delete-region (point-min) (point))) ;; Delete the prompt. - (goto-char (point-max)) - (re-search-backward regexp nil t) - (delete-region (point) (point-max))) + (when (tramp-search-regexp regexp) + (delete-region (point) (point-max)))) (if timeout (tramp-error proc 'file-error @@ -5134,8 +5133,7 @@ DONT-SUPPRESS-ERR is non-nil, stderr won't be sent to /dev/null." "echo tramp_exit_status $?" (if subshell " )" ""))) (with-current-buffer (tramp-get-connection-buffer vec) - (goto-char (point-max)) - (unless (re-search-backward "tramp_exit_status [0-9]+" nil t) + (unless (tramp-search-regexp "tramp_exit_status [0-9]+") (tramp-error vec 'file-error "Couldn't find exit status of `%s'" command)) (skip-chars-forward "^ ") diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 38149da6643..1a4b63d2c79 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1451,11 +1451,10 @@ component is used as the target of the symlink." (process-put p 'adjust-window-size-function #'ignore) (set-process-query-on-exit-flag p nil) (tramp-process-actions p v nil tramp-smb-actions-set-acl) - (goto-char (point-max)) ;; This is meant for traces, and returning from the ;; function. No error is propagated outside, due to ;; the `ignore-errors' closure. - (unless (re-search-backward "tramp_exit_status [0-9]+" nil t) + (unless (tramp-search-regexp "tramp_exit_status [0-9]+") (tramp-error v 'file-error "Couldn't find exit status of `%s'" tramp-smb-acl-program)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index e344990f7fc..f419aecbe77 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -4163,19 +4163,35 @@ for process communication also." (buffer-string)) result))) +(defun tramp-search-regexp (regexp) + "Search for REGEXP backwards, starting at point-max. +If found, set point to the end of the occurrence found, and return point. +Otherwise, return nil." + (goto-char (point-max)) + ;; We restrict ourselves to the last 256 characters. There were + ;; reports of 85kB output, which has blocked Tramp forever. + (re-search-backward regexp (max (point-min) (- (point) 256)) 'noerror)) + (defun tramp-check-for-regexp (proc regexp) "Check, whether REGEXP is contained in process buffer of PROC. Erase echoed commands if exists." (with-current-buffer (process-buffer proc) (goto-char (point-min)) - ;; Check whether we need to remove echo output. + ;; Check whether we need to remove echo output. The max length of + ;; the echo mark regexp is taken for search. We restrict the + ;; search for the second echo mark to PIPE_BUF characters. (when (and (tramp-get-connection-property proc "check-remote-echo" nil) - (re-search-forward tramp-echoed-echo-mark-regexp nil t)) + (re-search-forward + tramp-echoed-echo-mark-regexp + (+ (point) (* 5 tramp-echo-mark-marker-length)) t)) (let ((begin (match-beginning 0))) - (when (re-search-forward tramp-echoed-echo-mark-regexp nil t) + (when + (re-search-forward + tramp-echoed-echo-mark-regexp + (+ (point) (tramp-get-connection-property proc "pipe-buf" 4096)) t) ;; Discard echo from remote output. - (tramp-set-connection-property proc "check-remote-echo" nil) + (tramp-flush-connection-property proc "check-remote-echo") (tramp-message proc 5 "echo-mark found") (forward-line 1) (delete-region begin (point)) @@ -4196,8 +4212,7 @@ Erase echoed commands if exists." ;; overflow in regexp matcher". For example, //DIRED// lines of ;; directory listings with some thousand files. Therefore, we ;; look from the end. - (goto-char (point-max)) - (ignore-errors (re-search-backward regexp nil t))))) + (tramp-search-regexp regexp)))) (defun tramp-wait-for-regexp (proc timeout regexp) "Wait for a REGEXP to appear from process PROC within TIMEOUT seconds. @@ -4285,8 +4300,7 @@ the remote host use line-endings as defined in the variable (tramp-flush-connection-properties proc) (tramp-flush-directory-properties vec "")) (with-current-buffer (process-buffer proc) - (goto-char (point-max)) - (when (and prompt (re-search-backward (regexp-quote prompt) nil t)) + (when (and prompt (tramp-search-regexp (regexp-quote prompt))) (delete-region (point) (point-max))))))) (defun tramp-get-inode (vec)