From 5d50acd0a61f70db4069457a5f14fb1a9b0f7f7c Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 12 Aug 2021 20:09:48 +0200 Subject: [PATCH] Improve connection type `pipe' for remote processes * doc/misc/tramp.texi (Remote processes): New subsection "Remote process connection type". * lisp/net/tramp-adb.el (tramp-adb-handle-make-process): Use `tramp-process-connection-type' as default connection type. Improve check for `:connection-type'. * lisp/net/tramp-sh.el (tramp-sh-handle-make-process): Use `tramp-process-connection-type' as default connection type. Improve check for `:connection-type'. Send "stty -icrnl" when connection type is a pipe. * lisp/net/tramp.el (tramp-process-connection-type): Allow all possible values. (tramp-handle-make-process): Use `tramp-process-connection-type' as default connection type. Improve check for `:connection-type'. * test/lisp/net/tramp-tests.el (tramp-test30-make-process): Extend test. --- doc/misc/tramp.texi | 26 +++++++++++++++++++++++ lisp/net/tramp-adb.el | 7 +++++-- lisp/net/tramp-sh.el | 10 +++++++-- lisp/net/tramp.el | 11 ++++++---- test/lisp/net/tramp-tests.el | 40 +++++++++++++++++++++++++++++++++++- 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 38c20de62a2..bd9bd998dfb 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3734,6 +3734,32 @@ To open @command{powershell} as a remote shell, use this: @end lisp +@subsection Remote process connection type +@vindex process-connection-type +@cindex tramp-process-connection-type + +Asynchronous processes differ in the way, whether they use a pseudo +tty, or not. This is controlled by the variable +@code{process-connection-type}, which can be @code{t} or @code{pty} +(use a pseudo tty), or @code{nil} or @code{pipe} (don't use it). +@value{tramp} is based on running shells on the remote host, which +require a pseudo tty. Therefore, it declares the variable +@code{tramp-process-connection-type}, which carries this information +for remote processes. Per default, its value is @code{t}. The name +of the remote pseudo tty is returned by the function +@code{process-tty-name}. + +If a remote process, started by @code{start-file-process}, shouldn't +use a pseudo tty, this is emulated by let-binding this variable to +@code{nil} or @code{pipe}. There is still a pseudo tty for the +started process, but some terminal properties are changed, like +suppressing translation of carriage return characters into newline. + +The function @code{make-process} allows an explicit setting by the +@code{:connection-type} keyword. If this keyword is not used, the +value of @code{tramp-process-connection-type} is applied instead. + + @anchor{Improving performance of asynchronous remote processes} @subsection Improving performance of asynchronous remote processes @cindex Asynchronous remote processes diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 2f84312f077..c16e232c6d5 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -924,7 +924,10 @@ implementation will be used." (command (plist-get args :command)) (coding (plist-get args :coding)) (noquery (plist-get args :noquery)) - (connection-type (plist-get args :connection-type)) + (connection-type + (if (plist-member args :connection-type) + (plist-get args :connection-type) + tramp-process-connection-type)) (filter (plist-get args :filter)) (sentinel (plist-get args :sentinel)) (stderr (plist-get args :stderr))) @@ -940,7 +943,7 @@ implementation will be used." (memq (car coding) coding-system-list) (memq (cdr coding) coding-system-list))) (signal 'wrong-type-argument (list #'symbolp coding))) - (unless (or (null connection-type) (memq connection-type '(pipe pty))) + (unless (memq connection-type '(nil pipe t pty)) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index fad07d87c51..f00434c1468 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2752,7 +2752,10 @@ implementation will be used." (command (plist-get args :command)) (coding (plist-get args :coding)) (noquery (plist-get args :noquery)) - (connection-type (plist-get args :connection-type)) + (connection-type + (if (plist-member args :connection-type) + (plist-get args :connection-type) + tramp-process-connection-type)) (filter (plist-get args :filter)) (sentinel (plist-get args :sentinel)) (stderr (plist-get args :stderr))) @@ -2768,7 +2771,7 @@ implementation will be used." (memq (car coding) coding-system-list) (memq (cdr coding) coding-system-list))) (signal 'wrong-type-argument (list #'symbolp coding))) - (unless (or (null connection-type) (memq connection-type '(pipe pty))) + (unless (memq connection-type '(nil pipe t pty)) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) @@ -2916,6 +2919,9 @@ implementation will be used." (setq p (tramp-get-connection-process v)) (process-put p 'remote-pid pid) (tramp-set-connection-property p "remote-pid" pid)) + ;; Disable carriage return to newline translation. + (when (memq connection-type '(nil pipe)) + (tramp-send-command v "stty -icrnl")) ;; `tramp-maybe-open-connection' and ;; `tramp-send-command-and-read' could have ;; trashed the connection buffer. Remove this. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 6fc0ac8e1ef..83df05c24b7 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1264,14 +1264,14 @@ this variable to be set as well." :type '(choice (const nil) integer)) ;; Logging in to a remote host normally requires obtaining a pty. But -;; Emacs on macOS has process-connection-type set to nil by default, +;; Emacs on macOS has `process-connection-type' set to nil by default, ;; so on those systems Tramp doesn't obtain a pty. Here, we allow ;; for an override of the system default. (defcustom tramp-process-connection-type t "Overrides `process-connection-type' for connections from Tramp. Tramp binds `process-connection-type' to the value given here before opening a connection to a remote host." - :type '(choice (const nil) (const t) (const pty))) + :type '(choice (const nil) (const t) (const pipe) (const pty))) (defcustom tramp-connection-timeout 60 "Defines the max time to wait for establishing a connection (in seconds). @@ -4093,7 +4093,10 @@ substitution. SPEC-LIST is a list of char/value pairs used for (command (plist-get args :command)) (coding (plist-get args :coding)) (noquery (plist-get args :noquery)) - (connection-type (plist-get args :connection-type)) + (connection-type + (if (plist-member args :connection-type) + (plist-get args :connection-type) + tramp-process-connection-type)) (filter (plist-get args :filter)) (sentinel (plist-get args :sentinel)) (stderr (plist-get args :stderr))) @@ -4109,7 +4112,7 @@ substitution. SPEC-LIST is a list of char/value pairs used for (memq (car coding) coding-system-list) (memq (cdr coding) coding-system-list))) (signal 'wrong-type-argument (list #'symbolp coding))) - (unless (or (null connection-type) (memq connection-type '(pipe pty))) + (unless (memq connection-type '(nil pipe t pty)) (signal 'wrong-type-argument (list #'symbolp connection-type))) (unless (or (null filter) (functionp filter)) (signal 'wrong-type-argument (list #'functionp filter))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 052c03029fd..3008861f22b 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4749,7 +4749,45 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'." ;; Cleanup. (ignore-errors (delete-process proc)) - (ignore-errors (delete-file tmp-name))))))) + (ignore-errors (delete-file tmp-name)))) + + ;; Process connection type. + (when (and (tramp--test-sh-p) + ;; `executable-find' has changed the number of + ;; parameters in Emacs 27.1, so we use `apply' for + ;; older Emacsen. + (ignore-errors + (with-no-warnings + (apply #'executable-find '("hexdump" remote))))) + (dolist (connection-type '(nil pipe t pty)) + (unwind-protect + (with-temp-buffer + (setq proc + (with-no-warnings + (make-process + :name (format "test7-%s" connection-type) + :buffer (current-buffer) + :connection-type connection-type + :command '("hexdump" "-v" "-e" "/1 \"%02X\n\"") + :file-handler t))) + (should (processp proc)) + (should (equal (process-status proc) 'run)) + (process-send-string proc "foo\r\n") + (process-send-eof proc) + ;; Read output. + (with-timeout (10 (tramp--test-timeout-handler)) + (while (< (- (point-max) (point-min)) + (length "66\n6F\n6F\n0D\n0A\n")) + (while (accept-process-output proc 0 nil t)))) + (should + (string-match-p + (if (memq connection-type '(nil pipe)) + "66\n6F\n6F\n0D\n0A\n" + "66\n6F\n6F\n0A\n0A\n") + (buffer-string)))) + + ;; Cleanup. + (ignore-errors (delete-process proc)))))))) (tramp--test--deftest-direct-async-process tramp-test30-make-process "Check direct async `make-process'.") -- 2.39.5